Skip to content

Commit c57c80f

Browse files
committed
change sysctl of cpuinfo
1 parent cb64777 commit c57c80f

File tree

3 files changed

+50
-55
lines changed

3 files changed

+50
-55
lines changed

src/freebsd/api.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ struct cpuinfo_freebsd_topology {
77
uint32_t packages;
88
uint32_t cores;
99
uint32_t threads;
10+
uint32_t threads_per_core;
1011
};
1112

1213

src/freebsd/topology.c

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -8,25 +8,27 @@
88
#include <cpuinfo/log.h>
99
#include <freebsd/api.h>
1010

11-
12-
13-
struct cpuinfo_freebsd_topology cpuinfo_freebsd_detect_topology(void) {
14-
int threads = 1;
15-
size_t sizeof_threads = sizeof(threads);
16-
if (sysctlbyname("hw.ncpu", &threads, &sizeof_threads, NULL, 0) != 0) {
17-
cpuinfo_log_error("sysctlbyname(\"hw.ncpu\") failed: %s", strerror(errno));
18-
} else if (threads <= 0) {
19-
cpuinfo_log_error("sysctlbyname(\"hw.ncpu\") returned invalid value %d", threads);
11+
static int cpuinfo_from_freebsd_sysctl(const char *name) {
12+
int value = 0;
13+
size_t sizeof_int = sizeof(value);
14+
if (sysctlbyname(name, &value, &sizeof_int, NULL, 0) != 0) {
15+
cpuinfo_log_error("sysctlbyname(\"%s\") failed: %s", name, strerror(errno));
16+
} else if (value <= 0) {
17+
cpuinfo_log_error("sysctlbyname(\"%s\") returned invalid value %d", name, value);
2018
}
19+
return value;
20+
}
2121

22-
int cores = threads / 2;
23-
int packages = 1;
24-
25-
cpuinfo_log_debug("freebsd topology: packages = %d, cores = %d, threads = %d", packages, (int) cores, (int) threads);
22+
struct cpuinfo_freebsd_topology cpuinfo_freebsd_detect_topology(void) {
23+
int packages = cpuinfo_from_freebsd_sysctl("kern.smp.cpus");
24+
int cores = cpuinfo_from_freebsd_sysctl("kern.smp.cores");
25+
int threads_per_core = cpuinfo_from_freebsd_sysctl("kern.smp.threads_per_core");
26+
cpuinfo_log_debug("freebsd topology: packages = %d, cores = %d, threads_per_core = %d", packages, cores, threads_per_core);
2627
struct cpuinfo_freebsd_topology topology = {
2728
.packages = (uint32_t) packages,
2829
.cores = (uint32_t) cores,
29-
.threads = (uint32_t) threads
30+
.threads_per_core = (uint32_t) threads_per_core,
31+
.threads = (uint32_t) (threads_per_core * cores)
3032
};
3133

3234
return topology;

src/x86/freebsd/init.c

Lines changed: 33 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -31,26 +31,26 @@ void cpuinfo_x86_freebsd_init(void) {
3131
struct cpuinfo_freebsd_topology freebsd_topology = cpuinfo_freebsd_detect_topology();
3232
processors = calloc(freebsd_topology.threads, sizeof(struct cpuinfo_processor));
3333
if (processors == NULL) {
34-
cpuinfo_log_error("failed to allocate %zu bytes for descriptions of %"PRIu32" logical processors",
34+
cpuinfo_log_error("failed to allocate %zu bytes for descriptions of %"PRIu32" logical processors",
3535
freebsd_topology.threads * sizeof(struct cpuinfo_processor), freebsd_topology.threads);
3636
goto cleanup;
3737
}
3838
cores = calloc(freebsd_topology.cores, sizeof(struct cpuinfo_core));
3939
if (cores == NULL) {
40-
cpuinfo_log_error("failed to allocate %zu bytes for descriptions of %"PRIu32" cores",
40+
cpuinfo_log_error("failed to allocate %zu bytes for descriptions of %"PRIu32" cores",
4141
freebsd_topology.cores * sizeof(struct cpuinfo_core), freebsd_topology.cores);
4242
goto cleanup;
4343
}
4444
/* On x86 cluster of cores is a physical package */
4545
clusters = calloc(freebsd_topology.packages, sizeof(struct cpuinfo_cluster));
4646
if (clusters == NULL) {
47-
cpuinfo_log_error("failed to allocate %zu bytes for descriptions of %"PRIu32" core clusters",
47+
cpuinfo_log_error("failed to allocate %zu bytes for descriptions of %"PRIu32" core clusters",
4848
freebsd_topology.packages * sizeof(struct cpuinfo_cluster), freebsd_topology.packages);
4949
goto cleanup;
5050
}
5151
packages = calloc(freebsd_topology.packages, sizeof(struct cpuinfo_package));
5252
if (packages == NULL) {
53-
cpuinfo_log_error("failed to allocate %zu bytes for descriptions of %"PRIu32" physical packages",
53+
cpuinfo_log_error("failed to allocate %zu bytes for descriptions of %"PRIu32" physical packages",
5454
freebsd_topology.packages * sizeof(struct cpuinfo_package), freebsd_topology.packages);
5555
goto cleanup;
5656
}
@@ -61,7 +61,7 @@ void cpuinfo_x86_freebsd_init(void) {
6161
char brand_string[48];
6262
cpuinfo_x86_normalize_brand_string(x86_processor.brand_string, brand_string);
6363

64-
const uint32_t threads_per_core = freebsd_topology.threads / freebsd_topology.cores;
64+
const uint32_t threads_per_core = freebsd_topology.threads_per_core;
6565
const uint32_t threads_per_package = freebsd_topology.threads / freebsd_topology.packages;
6666
const uint32_t cores_per_package = freebsd_topology.cores / freebsd_topology.packages;
6767
for (uint32_t i = 0; i < freebsd_topology.packages; i++) {
@@ -122,60 +122,52 @@ void cpuinfo_x86_freebsd_init(void) {
122122

123123
uint32_t threads_per_l1 = 0, l1_count = 0;
124124
if (x86_processor.cache.l1i.size != 0 || x86_processor.cache.l1d.size != 0) {
125-
if (threads_per_l1 == 0) {
126-
/* Assume that threads on the same core share L1 */
127-
threads_per_l1 = freebsd_topology.threads / freebsd_topology.cores;
128-
cpuinfo_log_warning("freebsd kernel did not report number of threads sharing L1 cache; assume %"PRIu32,
129-
threads_per_l1);
130-
}
125+
/* Assume that threads on the same core share L1 */
126+
threads_per_l1 = freebsd_topology.threads / freebsd_topology.cores;
127+
cpuinfo_log_warning("freebsd kernel did not report number of threads sharing L1 cache; assume %"PRIu32,
128+
threads_per_l1);
131129
l1_count = freebsd_topology.threads / threads_per_l1;
132130
cpuinfo_log_debug("detected %"PRIu32" L1 caches", l1_count);
133131
}
134132

135133
uint32_t threads_per_l2 = 0, l2_count = 0;
136134
if (x86_processor.cache.l2.size != 0) {
137-
if (threads_per_l2 == 0) {
138-
if (x86_processor.cache.l3.size != 0) {
139-
/* This is not a last-level cache; assume that threads on the same core share L2 */
140-
threads_per_l2 = freebsd_topology.threads / freebsd_topology.cores;
141-
} else {
142-
/* This is a last-level cache; assume that threads on the same package share L2 */
143-
threads_per_l2 = freebsd_topology.threads / freebsd_topology.packages;
144-
}
145-
cpuinfo_log_warning("freebsd kernel did not report number of threads sharing L2 cache; assume %"PRIu32,
146-
threads_per_l2);
147-
}
135+
if (x86_processor.cache.l3.size != 0) {
136+
/* This is not a last-level cache; assume that threads on the same core share L2 */
137+
threads_per_l2 = freebsd_topology.threads / freebsd_topology.cores;
138+
} else {
139+
/* This is a last-level cache; assume that threads on the same package share L2 */
140+
threads_per_l2 = freebsd_topology.threads / freebsd_topology.packages;
141+
}
142+
cpuinfo_log_warning("freebsd kernel did not report number of threads sharing L2 cache; assume %"PRIu32,
143+
threads_per_l2);
148144
l2_count = freebsd_topology.threads / threads_per_l2;
149145
cpuinfo_log_debug("detected %"PRIu32" L2 caches", l2_count);
150146
}
151147

152148
uint32_t threads_per_l3 = 0, l3_count = 0;
153149
if (x86_processor.cache.l3.size != 0) {
154-
if (threads_per_l3 == 0) {
155-
/*
156-
* Assume that threads on the same package share L3.
157-
* However, is it not necessarily the last-level cache (there may be L4 cache as well)
158-
*/
159-
threads_per_l3 = freebsd_topology.threads / freebsd_topology.packages;
160-
cpuinfo_log_warning("freebsd kernel did not report number of threads sharing L3 cache; assume %"PRIu32,
161-
threads_per_l3);
162-
}
150+
/*
151+
* Assume that threads on the same package share L3.
152+
* However, is it not necessarily the last-level cache (there may be L4 cache as well)
153+
*/
154+
threads_per_l3 = freebsd_topology.threads / freebsd_topology.packages;
155+
cpuinfo_log_warning("freebsd kernel did not report number of threads sharing L3 cache; assume %"PRIu32,
156+
threads_per_l3);
163157
l3_count = freebsd_topology.threads / threads_per_l3;
164158
cpuinfo_log_debug("detected %"PRIu32" L3 caches", l3_count);
165159
}
166160

167161
uint32_t threads_per_l4 = 0, l4_count = 0;
168162
if (x86_processor.cache.l4.size != 0) {
169-
if (threads_per_l4 == 0) {
170-
/*
171-
* Assume that all threads share this L4.
172-
* As of now, L4 cache exists only on notebook x86 CPUs, which are single-package,
173-
* but multi-socket systems could have shared L4 (like on IBM POWER8).
174-
*/
175-
threads_per_l4 = freebsd_topology.threads;
176-
cpuinfo_log_warning("freebsd kernel did not report number of threads sharing L4 cache; assume %"PRIu32,
177-
threads_per_l4);
178-
}
163+
/*
164+
* Assume that all threads share this L4.
165+
* As of now, L4 cache exists only on notebook x86 CPUs, which are single-package,
166+
* but multi-socket systems could have shared L4 (like on IBM POWER8).
167+
*/
168+
threads_per_l4 = freebsd_topology.threads;
169+
cpuinfo_log_warning("freebsd kernel did not report number of threads sharing L4 cache; assume %"PRIu32,
170+
threads_per_l4);
179171
l4_count = freebsd_topology.threads / threads_per_l4;
180172
cpuinfo_log_debug("detected %"PRIu32" L4 caches", l4_count);
181173
}

0 commit comments

Comments
 (0)