Skip to content

Commit 59868c6

Browse files
committed
CPU (FreeBSD): don't assume one SMT group has only two threads
Fix #1670
1 parent e13eb05 commit 59868c6

File tree

1 file changed

+47
-21
lines changed

1 file changed

+47
-21
lines changed

Diff for: src/detection/cpu/cpu_bsd.c

+47-21
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#include "cpu.h"
22
#include "common/sysctl.h"
3+
#include "util/stringUtils.h"
34

45
#include <sys/param.h>
56
#if __has_include(<sys/cpuset.h>)
@@ -34,35 +35,60 @@ const char* ffDetectCPUImpl(const FFCPUOptions* options, FFCPUResult* cpu)
3435
if (ffSysctlGetString("hw.model", &cpu->name) != NULL)
3536
return "sysctlbyname(hw.model) failed";
3637

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;
3940
cpu->coresOnline = (uint16_t) ffSysctlGetInt("kern.smp.cpus", cpu->coresLogical);
4041

4142
FF_STRBUF_AUTO_DESTROY buffer = ffStrbufCreate();
4243
if (ffSysctlGetString("kern.sched.topology_spec", &buffer) == NULL && buffer.length > 0)
4344
{
4445
// <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>
5859
// </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))
6165
{
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+
}
6692
}
6793
}
6894

0 commit comments

Comments
 (0)