Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
tpruvot
GitHub Repository: tpruvot/cpuminer-multi
Path: blob/linux/sysinfos.c
1201 views
1
/**
2
* Unit to read cpu informations
3
*
4
* tpruvot 2014
5
*/
6
7
#include <stdio.h>
8
#include <ctype.h>
9
#include <stdlib.h>
10
#include <string.h>
11
12
#include "miner.h"
13
14
#ifndef WIN32
15
16
#define HWMON_PATH \
17
"/sys/devices/platform/coretemp.0/hwmon/hwmon1/temp1_input"
18
#define HWMON_ALT \
19
"/sys/class/hwmon/hwmon1/temp1_input"
20
#define HWMON_ALT2 \
21
"/sys/class/hwmon/hwmon0/temp1_input"
22
#define HWMON_ALT3 \
23
"/sys/devices/platform/coretemp.0/hwmon/hwmon0/temp2_input"
24
#define HWMON_ALT4 \
25
"/sys/class/hwmon/hwmon0/temp2_input"
26
#define HWMON_ALT5 \
27
"/sys/class/hwmon/hwmon0/device/temp1_input"
28
#define HWMON_ALT6 \
29
"/sys/class/thermal/thermal_zone0/temp"
30
31
static float linux_cputemp(int core)
32
{
33
float tc = 0.0;
34
FILE *fd = fopen(HWMON_PATH, "r");
35
uint32_t val = 0;
36
37
if (!fd)
38
fd = fopen(HWMON_ALT, "r");
39
40
if (!fd)
41
fd = fopen(HWMON_ALT2, "r");
42
43
if (!fd)
44
fd = fopen(HWMON_ALT3, "r");
45
46
if (!fd)
47
fd = fopen(HWMON_ALT4, "r");
48
49
if (!fd)
50
fd = fopen(HWMON_ALT5, "r");
51
52
if (!fd)
53
fd = fopen(HWMON_ALT6, "r");
54
55
if (!fd)
56
return tc;
57
58
if (fscanf(fd, "%d", &val))
59
tc = val / 1000.0;
60
61
fclose(fd);
62
return tc;
63
}
64
65
#define CPUFREQ_PATH \
66
"/sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_cur_freq"
67
static uint32_t linux_cpufreq(int core)
68
{
69
FILE *fd = fopen(CPUFREQ_PATH, "r");
70
uint32_t freq = 0;
71
72
if (!fd)
73
return freq;
74
75
if (!fscanf(fd, "%d", &freq))
76
return freq;
77
78
fclose(fd);
79
return freq;
80
}
81
82
#else /* WIN32 */
83
84
static float win32_cputemp(int core)
85
{
86
// todo
87
return 0.0;
88
}
89
90
#endif /* !WIN32 */
91
92
93
/* exports */
94
95
96
float cpu_temp(int core)
97
{
98
#ifdef WIN32
99
return win32_cputemp(core);
100
#else
101
return linux_cputemp(core);
102
#endif
103
}
104
105
uint32_t cpu_clock(int core)
106
{
107
#ifdef WIN32
108
return 0;
109
#else
110
return linux_cpufreq(core);
111
#endif
112
}
113
114
int cpu_fanpercent()
115
{
116
return 0;
117
}
118
119
#if !defined(__arm__) && !defined(__aarch64__)
120
static inline void cpuid(int functionnumber, int output[4]) {
121
#ifdef _MSC_VER
122
// Microsoft compiler, intrin.h included
123
__cpuidex(output, functionnumber, 0);
124
#elif defined(__INTEL_COMPILER)
125
__cpuid(output, functionnumber);
126
#elif defined(__GNUC__) || defined(__clang__)
127
// use inline assembly, Gnu/AT&T syntax
128
int a, b, c, d;
129
asm volatile("cpuid" : "=a"(a), "=b"(b), "=c"(c), "=d"(d) : "a"(functionnumber), "c"(0));
130
output[0] = a;
131
output[1] = b;
132
output[2] = c;
133
output[3] = d;
134
#else
135
// unknown platform. try inline assembly with masm/intel syntax
136
__asm {
137
mov eax, functionnumber
138
xor ecx, ecx
139
cpuid;
140
mov esi, output
141
mov[esi], eax
142
mov[esi + 4], ebx
143
mov[esi + 8], ecx
144
mov[esi + 12], edx
145
}
146
#endif
147
}
148
#else /* !__arm__ */
149
#define cpuid(fn, out) out[0] = 0;
150
#endif
151
152
// For the i7-5775C will output : Intel(R) Core(TM) i7-5775C CPU @ 3.30GHz
153
void cpu_getname(char *outbuf, size_t maxsz)
154
{
155
memset(outbuf, 0, maxsz);
156
#ifdef WIN32
157
char brand[0xC0] = { 0 };
158
int output[4] = { 0 }, ext;
159
cpuid(0x80000000, output);
160
ext = output[0];
161
if (ext >= 0x80000004) {
162
for (int i = 2; i <= (ext & 0xF); i++) {
163
cpuid(0x80000000+i, output);
164
memcpy(&brand[(i-2) * 4*sizeof(int)], output, 4*sizeof(int));
165
}
166
snprintf(outbuf, maxsz, "%s", brand);
167
} else {
168
// Fallback, for the i7-5775C will output
169
// Intel64 Family 6 Model 71 Stepping 1, GenuineIntel
170
snprintf(outbuf, maxsz, "%s", getenv("PROCESSOR_IDENTIFIER"));
171
}
172
#else
173
// Intel(R) Xeon(R) CPU E3-1245 V2 @ 3.40GHz
174
FILE *fd = fopen("/proc/cpuinfo", "rb");
175
char *buf = NULL, *p, *eol;
176
size_t size = 0;
177
if (!fd) return;
178
while(getdelim(&buf, &size, 0, fd) != -1) {
179
if (buf && (p = strstr(buf, "model name\t")) && strstr(p, ":")) {
180
p = strstr(p, ":");
181
if (p) {
182
p += 2;
183
eol = strstr(p, "\n"); if (eol) *eol = '\0';
184
snprintf(outbuf, maxsz, "%s", p);
185
}
186
break;
187
}
188
}
189
free(buf);
190
fclose(fd);
191
#endif
192
}
193
194
void cpu_getmodelid(char *outbuf, size_t maxsz)
195
{
196
memset(outbuf, 0, maxsz);
197
#ifdef WIN32
198
// For the i7-5775C will output 6:4701:8
199
snprintf(outbuf, maxsz, "%s:%s:%s", getenv("PROCESSOR_LEVEL"), // hexa ?
200
getenv("PROCESSOR_REVISION"), getenv("NUMBER_OF_PROCESSORS"));
201
#else
202
FILE *fd = fopen("/proc/cpuinfo", "rb");
203
char *buf = NULL, *p, *eol;
204
int cpufam = 0, model = 0, stepping = 0;
205
size_t size = 0;
206
if (!fd) return;
207
while(getdelim(&buf, &size, 0, fd) != -1) {
208
if (buf && (p = strstr(buf, "cpu family\t")) && strstr(p, ":")) {
209
p = strstr(p, ":");
210
if (p) {
211
p += 2;
212
cpufam = atoi(p);
213
}
214
}
215
if (buf && (p = strstr(buf, "model\t")) && strstr(p, ":")) {
216
p = strstr(p, ":");
217
if (p) {
218
p += 2;
219
model = atoi(p);
220
}
221
}
222
if (buf && (p = strstr(buf, "stepping\t")) && strstr(p, ":")) {
223
p = strstr(p, ":");
224
if (p) {
225
p += 2;
226
stepping = atoi(p);
227
}
228
}
229
if (cpufam && model && stepping) {
230
snprintf(outbuf, maxsz, "%x:%02x%02x:%d", cpufam, model, stepping, num_cpus);
231
outbuf[maxsz-1] = '\0';
232
break;
233
}
234
}
235
free(buf);
236
fclose(fd);
237
#endif
238
}
239
240
// http://en.wikipedia.org/wiki/CPUID
241
#define OSXSAVE_Flag (1 << 27)
242
#define AVX1_Flag ((1 << 28)|OSXSAVE_Flag)
243
#define XOP_Flag (1 << 11)
244
#define FMA3_Flag ((1 << 12)|AVX1_Flag|OSXSAVE_Flag)
245
#define AES_Flag (1 << 25)
246
#define SSE42_Flag (1 << 20)
247
248
#define SSE_Flag (1 << 25) // EDX
249
#define SSE2_Flag (1 << 26) // EDX
250
251
#define AVX2_Flag (1 << 5) // ADV EBX
252
253
bool has_aes_ni()
254
{
255
#if defined(__arm__) || defined(__aarch64__)
256
return false;
257
#else
258
int cpu_info[4] = { 0 };
259
cpuid(1, cpu_info);
260
return cpu_info[2] & AES_Flag;
261
#endif
262
}
263
264
void cpu_bestfeature(char *outbuf, size_t maxsz)
265
{
266
#if defined(__arm__) || defined(__aarch64__)
267
sprintf(outbuf, "ARM");
268
#else
269
int cpu_info[4] = { 0 };
270
int cpu_info_adv[4] = { 0 };
271
cpuid(1, cpu_info);
272
cpuid(7, cpu_info_adv);
273
if ((cpu_info[2] & AVX1_Flag) && (cpu_info_adv[1] & AVX2_Flag))
274
sprintf(outbuf, "AVX2");
275
else if (cpu_info[2] & AVX1_Flag)
276
sprintf(outbuf, "AVX");
277
else if (cpu_info[2] & FMA3_Flag)
278
sprintf(outbuf, "FMA3");
279
else if (cpu_info[2] & XOP_Flag)
280
sprintf(outbuf, "XOP");
281
else if (cpu_info[2] & SSE42_Flag)
282
sprintf(outbuf, "SSE42");
283
else if (cpu_info[3] & SSE2_Flag)
284
sprintf(outbuf, "SSE2");
285
else if (cpu_info[3] & SSE_Flag)
286
sprintf(outbuf, "SSE");
287
else
288
*outbuf = '\0';
289
#endif
290
}
291
292