Andrew Scull | b4b6d4a | 2019-01-02 15:54:55 +0000 | [diff] [blame] | 1 | #include <stdio.h> |
| 2 | #include <stdlib.h> |
| 3 | #include <unistd.h> |
| 4 | #include <linux/bitops.h> |
| 5 | #include "api/fs/fs.h" |
| 6 | #include "smt.h" |
| 7 | |
| 8 | int smt_on(void) |
| 9 | { |
| 10 | static bool cached; |
| 11 | static int cached_result; |
| 12 | int cpu; |
| 13 | int ncpu; |
| 14 | |
| 15 | if (cached) |
| 16 | return cached_result; |
| 17 | |
| 18 | ncpu = sysconf(_SC_NPROCESSORS_CONF); |
| 19 | for (cpu = 0; cpu < ncpu; cpu++) { |
| 20 | unsigned long long siblings; |
| 21 | char *str; |
| 22 | size_t strlen; |
| 23 | char fn[256]; |
| 24 | |
| 25 | snprintf(fn, sizeof fn, |
| 26 | "devices/system/cpu/cpu%d/topology/thread_siblings", |
| 27 | cpu); |
| 28 | if (sysfs__read_str(fn, &str, &strlen) < 0) |
| 29 | continue; |
| 30 | /* Entry is hex, but does not have 0x, so need custom parser */ |
| 31 | siblings = strtoull(str, NULL, 16); |
| 32 | free(str); |
| 33 | if (hweight64(siblings) > 1) { |
| 34 | cached_result = 1; |
| 35 | cached = true; |
| 36 | break; |
| 37 | } |
| 38 | } |
| 39 | if (!cached) { |
| 40 | cached_result = 0; |
| 41 | cached = true; |
| 42 | } |
| 43 | return cached_result; |
| 44 | } |