mirror of https://github.com/Qortal/Brooklyn
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
99 lines
1.7 KiB
99 lines
1.7 KiB
#include <stdio.h> |
|
#include <stdlib.h> |
|
#include <unistd.h> |
|
#include <linux/bitops.h> |
|
#include "api/fs/fs.h" |
|
#include "smt.h" |
|
|
|
/** |
|
* hweight_str - Returns the number of bits set in str. Stops at first non-hex |
|
* or ',' character. |
|
*/ |
|
static int hweight_str(char *str) |
|
{ |
|
int result = 0; |
|
|
|
while (*str) { |
|
switch (*str++) { |
|
case '0': |
|
case ',': |
|
break; |
|
case '1': |
|
case '2': |
|
case '4': |
|
case '8': |
|
result++; |
|
break; |
|
case '3': |
|
case '5': |
|
case '6': |
|
case '9': |
|
case 'a': |
|
case 'A': |
|
case 'c': |
|
case 'C': |
|
result += 2; |
|
break; |
|
case '7': |
|
case 'b': |
|
case 'B': |
|
case 'd': |
|
case 'D': |
|
case 'e': |
|
case 'E': |
|
result += 3; |
|
break; |
|
case 'f': |
|
case 'F': |
|
result += 4; |
|
break; |
|
default: |
|
goto done; |
|
} |
|
} |
|
done: |
|
return result; |
|
} |
|
|
|
int smt_on(void) |
|
{ |
|
static bool cached; |
|
static int cached_result; |
|
int cpu; |
|
int ncpu; |
|
|
|
if (cached) |
|
return cached_result; |
|
|
|
if (sysfs__read_int("devices/system/cpu/smt/active", &cached_result) >= 0) { |
|
cached = true; |
|
return cached_result; |
|
} |
|
|
|
cached_result = 0; |
|
ncpu = sysconf(_SC_NPROCESSORS_CONF); |
|
for (cpu = 0; cpu < ncpu; cpu++) { |
|
unsigned long long siblings; |
|
char *str; |
|
size_t strlen; |
|
char fn[256]; |
|
|
|
snprintf(fn, sizeof fn, |
|
"devices/system/cpu/cpu%d/topology/thread_siblings", cpu); |
|
if (sysfs__read_str(fn, &str, &strlen) < 0) { |
|
snprintf(fn, sizeof fn, |
|
"devices/system/cpu/cpu%d/topology/core_cpus", cpu); |
|
if (sysfs__read_str(fn, &str, &strlen) < 0) |
|
continue; |
|
} |
|
/* Entry is hex, but does not have 0x, so need custom parser */ |
|
siblings = hweight_str(str); |
|
free(str); |
|
if (siblings > 1) { |
|
cached_result = 1; |
|
break; |
|
} |
|
} |
|
cached = true; |
|
return cached_result; |
|
}
|
|
|