diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2013-01-24 20:58:53 +0000 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2013-01-24 21:13:47 +0000 |
commit | 326dcd75f2202b1af29e986f5efb6b1e133217cb (patch) | |
tree | 4906f63d5d2dfd37f3d9d19ca2de59561cbb62ac /src/sna/sna_threads.c | |
parent | f597b647180c1e7bf83693060f244926191b7462 (diff) |
sna: Parse cpuinfo to determine the actual number of physical cores/caches
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Diffstat (limited to 'src/sna/sna_threads.c')
-rw-r--r-- | src/sna/sna_threads.c | 52 |
1 files changed, 51 insertions, 1 deletions
diff --git a/src/sna/sna_threads.c b/src/sna/sna_threads.c index 3f70f8fc..b375b946 100644 --- a/src/sna/sna_threads.c +++ b/src/sna/sna_threads.c @@ -63,6 +63,54 @@ static void *__run__(void *arg) return NULL; } +#if defined(__GNUC__) +#define popcount(x) __builtin_popcount(x) +#else +static int popcount(unsigned int x) +{ + int count = 0; + + while (x) { + count += x&1; + x >>= 1; + } + + return count; +} +#endif + +static int +num_cores(void) +{ + FILE *file = fopen("/proc/cpuinfo", "r"); + int count = 0; + if (file) { + size_t len = 0; + char *line = NULL; + uint32_t processors = 0, cores = 0; + while (getline(&line, &len, file) != -1) { + int id; + if (sscanf(line, "physical id : %d", &id) == 1) { + if (id >= 32) + return 0; + processors |= 1 << id; + } else if (sscanf(line, "core id : %d", &id) == 1) { + if (id >= 32) + return 0; + cores |= 1 << id; + } + } + free(line); + fclose(file); + + DBG(("%s: processors=0x%08x, cores=0x%08x\n", + __FUNCTION__, processors, cores)); + + count = popcount(processors) * popcount(cores); + } + return count; +} + void sna_threads_init(void) { int n; @@ -70,7 +118,9 @@ void sna_threads_init(void) if (max_threads != -1) return; - max_threads = sysconf (_SC_NPROCESSORS_ONLN) / 2; + max_threads = num_cores(); + if (max_threads == 0) + max_threads = sysconf(_SC_NPROCESSORS_ONLN) / 2; if (max_threads <= 1) goto bail; |