|
1 | 1 | #include "cpu.h" |
2 | 2 | #include "common/sysctl.h" |
| 3 | +#include "util/stringUtils.h" |
3 | 4 |
|
4 | 5 | #include <sys/param.h> |
5 | 6 | #if __has_include(<sys/cpuset.h>) |
@@ -34,35 +35,60 @@ const char* ffDetectCPUImpl(const FFCPUOptions* options, FFCPUResult* cpu) |
34 | 35 | if (ffSysctlGetString("hw.model", &cpu->name) != NULL) |
35 | 36 | return "sysctlbyname(hw.model) failed"; |
36 | 37 |
|
37 | | - cpu->coresPhysical = (uint16_t) ffSysctlGetInt("hw.ncpu", 1); |
38 | | - cpu->coresLogical = cpu->coresPhysical; |
| 38 | + cpu->coresLogical = (uint16_t) ffSysctlGetInt("hw.ncpu", 1); |
| 39 | + cpu->coresPhysical = 0; |
39 | 40 | cpu->coresOnline = (uint16_t) ffSysctlGetInt("kern.smp.cpus", cpu->coresLogical); |
40 | 41 |
|
41 | 42 | FF_STRBUF_AUTO_DESTROY buffer = ffStrbufCreate(); |
42 | 43 | if (ffSysctlGetString("kern.sched.topology_spec", &buffer) == NULL && buffer.length > 0) |
43 | 44 | { |
44 | 45 | // <groups> |
45 | | - // <group level="1" cache-level="3"> |
46 | | - // <cpu count="4" mask="f,0,0,0">0, 1, 2, 3</cpu> |
47 | | - // <children> |
48 | | - // <group level="2" cache-level="2"> |
49 | | - // <cpu count="2" mask="3,0,0,0">0, 1</cpu> |
50 | | - // <flags><flag name="THREAD">THREAD group</flag><flag name="SMT">SMT group</flag></flags> |
51 | | - // </group> |
52 | | - // <group level="2" cache-level="2"> |
53 | | - // <cpu count="2" mask="c,0,0,0">2, 3</cpu> |
54 | | - // <flags><flag name="THREAD">THREAD group</flag><flag name="SMT">SMT group</flag></flags> |
55 | | - // </group> |
56 | | - // </children> |
57 | | - // </group> |
| 46 | + // <group level="1" cache-level="3"> |
| 47 | + // <cpu count="4" mask="f,0,0,0">0, 1, 2, 3</cpu> |
| 48 | + // <children> |
| 49 | + // <group level="2" cache-level="2"> |
| 50 | + // <cpu count="2" mask="3,0,0,0">0, 1</cpu> |
| 51 | + // <flags><flag name="THREAD">THREAD group</flag><flag name="SMT">SMT group</flag></flags> |
| 52 | + // </group> |
| 53 | + // <group level="2" cache-level="2"> |
| 54 | + // <cpu count="2" mask="c,0,0,0">2, 3</cpu> |
| 55 | + // <flags><flag name="THREAD">THREAD group</flag><flag name="SMT">SMT group</flag></flags> |
| 56 | + // </group> |
| 57 | + // </children> |
| 58 | + // </group> |
58 | 59 | // </groups> |
59 | | - uint32_t i = 0; |
60 | | - while (true) |
| 60 | + char* line = NULL; |
| 61 | + size_t len = 0; |
| 62 | + bool inLvl2 = false, threadGroup = false; |
| 63 | + uint32_t cpuCount = 0; |
| 64 | + while (ffStrbufGetline(&line, &len, &buffer)) |
61 | 65 | { |
62 | | - i = ffStrbufNextIndexS(&buffer, i, "<flag name=\"THREAD\">THREAD group</flag>"); // Find physical core with hyper-threading enabled |
63 | | - if (i >= buffer.length) break; |
64 | | - cpu->coresPhysical--; |
65 | | - i += (uint32_t) strlen("<flag name=\"THREAD\">THREAD group</flag>"); |
| 66 | + if (!inLvl2) |
| 67 | + { |
| 68 | + if (ffStrStartsWith(line, " <group level=\"2\"")) |
| 69 | + { |
| 70 | + inLvl2 = true; |
| 71 | + cpuCount = 0; |
| 72 | + threadGroup = false; |
| 73 | + } |
| 74 | + else if (ffStrStartsWith(line, " <group level=\"1\"")) |
| 75 | + cpu->packages++; |
| 76 | + } |
| 77 | + else |
| 78 | + { |
| 79 | + if (ffStrEquals(line, " </group>")) |
| 80 | + { |
| 81 | + cpu->coresPhysical += threadGroup ? 1 : cpuCount; |
| 82 | + inLvl2 = false; |
| 83 | + } |
| 84 | + else if (cpuCount == 0 && ffStrStartsWith(line, " <cpu count=\"")) |
| 85 | + cpuCount = (uint32_t) strtoul(line + strlen(" <cpu count=\""), NULL, 10); |
| 86 | + else if (cpuCount > 0 && ffStrStartsWith(line, " <flags>")) |
| 87 | + { |
| 88 | + if (ffStrContains(line, "<flag name=\"THREAD\">THREAD group</flag>")) |
| 89 | + threadGroup = true; |
| 90 | + } |
| 91 | + } |
66 | 92 | } |
67 | 93 | } |
68 | 94 |
|
|
0 commit comments