|
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