this repo has no description
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Implement machdep.cpu.core_count

+62
+62
src/kernel/emulation/linux/misc/sysctl_machdep.c
··· 2 2 #include "simple.h" 3 3 #include <sys/errno.h> 4 4 #include <alloca.h> 5 + #include "../fcntl/open.h" 6 + #include "../readline.h" 7 + #include "../unistd/close.h" 5 8 6 9 extern char *strncpy(char *dest, const char *src, __SIZE_TYPE__ n); 10 + extern int strncmp(const char* str1, const char* str2, __SIZE_TYPE__ n);; 7 11 8 12 enum { 9 13 _MACHDEP_CPU = 1000, ··· 17 21 _CPU_STEPPING, 18 22 _CPU_BRAND_STRING, 19 23 _CPU_FEATURES, 24 + _CPU_CORE_COUNT, 20 25 }; 21 26 22 27 static sysctl_handler(handle_vendor); ··· 26 31 static sysctl_handler(handle_stepping); 27 32 static sysctl_handler(handle_brand_string); 28 33 static sysctl_handler(handle_features); 34 + static sysctl_handler(handle_core_count); 29 35 30 36 const struct known_sysctl sysctls_machdep_cpu[] = { 31 37 { .oid = _CPU_MAX_BASIC, .type = CTLTYPE_INT, .exttype = "I", .name = "max_basic", .handler = handle_max_basic }, ··· 35 41 { .oid = _CPU_STEPPING, .type = CTLTYPE_INT, .exttype = "I", .name = "stepping", .handler = handle_stepping }, 36 42 { .oid = _CPU_BRAND_STRING, .type = CTLTYPE_STRING, .exttype = "S", .name = "vendor", .handler = handle_brand_string }, 37 43 { .oid = _CPU_FEATURES, .type = CTLTYPE_STRING, .exttype = "S", .name = "features", .handler = handle_features }, 44 + { .oid = _CPU_CORE_COUNT, .type = CTLTYPE_INT, .exttype = "I", .name = "core_count", .handler = handle_core_count }, 38 45 { .oid = -1 } 39 46 }; 40 47 ··· 254 261 return 0; 255 262 256 263 } 264 + 265 + 266 + // TODO: i doubt core count is ever going to change. 267 + // this is something that could be cached if we had some way of doing something only once in libsystem_kernel (i.e. a simple version of dispatch_once). 268 + sysctl_handler(handle_core_count) { 269 + // it's easier to use /proc/cpuinfo for this. 270 + // using cpuid directly is more difficult because AMD processors don't use the same method as Intel processors. 271 + 272 + int infofd = sys_open_nocancel("/proc/cpuinfo", BSD_O_RDONLY, 0); 273 + struct rdline_buffer rbuf; 274 + const char* line; 275 + 276 + // a reasonable default 277 + size_t core_count = 1; 278 + 279 + if (infofd < 0) 280 + goto out; 281 + 282 + _readline_init(&rbuf); 283 + 284 + while ((line = _readline(infofd, &rbuf)) != NULL) { 285 + if (strncmp(line, "cpu cores", 9) != 0) { 286 + continue; 287 + } 288 + 289 + // great, we've got "cpu cores" 290 + // now find the actual number 291 + while (*line != ':' && *line != '\0') 292 + ++line; 293 + 294 + // shouldn't happen, but just in case 295 + if (*line == '\0') 296 + continue; 297 + 298 + ++line; // skip the colon 299 + if (*line == '\0') 300 + continue; 301 + 302 + ++line; // skip the space 303 + if (*line == '\0') 304 + continue; 305 + 306 + core_count = __simple_atoi(line, NULL); 307 + break; 308 + } 309 + 310 + out: 311 + if (infofd >= 0) 312 + close_internal(infofd); 313 + if (old != NULL && oldlen && *oldlen >= sizeof(uint32_t)) 314 + *(uint32_t*)old = core_count; 315 + if (oldlen) 316 + *oldlen = sizeof(uint32_t); 317 + return 0; 318 + };