rid of more of unnamed unions
[mkp224o.git] / cpucount.c
blob11fef4d16e7188cd9cf70684eb80e592bdb99eb5
2 #ifndef BSD
3 # ifndef __linux__
4 // FreeBSD
5 # ifdef __FreeBSD__
6 # undef BSD
7 # define BSD
8 # endif
9 // OpenBSD
10 # ifdef __OpenBSD__
11 # undef BSD
12 # define BSD
13 # endif
14 // NetBSD
15 # ifdef __NetBSD__
16 # undef BSD
17 # define BSD
18 # endif
19 // DragonFly
20 # ifdef __DragonFly__
21 # undef BSD
22 # define BSD
23 # endif
24 # endif // __linux__
25 // sys/param.h may have its own define
26 # ifdef BSD
27 # undef BSD
28 # include <sys/param.h>
29 # define SYS_PARAM_INCLUDED
30 # ifndef BSD
31 # define BSD
32 # endif
33 # endif
34 #endif // BSD
36 #ifdef BSD
37 # ifndef SYS_PARAM_INCLUDED
38 # include <sys/param.h>
39 # endif
40 # include <sys/sysctl.h>
41 #endif
43 #include <unistd.h>
44 #include <string.h>
45 #include <stdio.h>
47 #ifdef __linux__
48 #include <stdio.h>
49 #include <stdlib.h>
50 #include <strings.h>
51 static int parsecpuinfo()
53 unsigned char cpubitmap[128];
55 memset(cpubitmap,0,sizeof(cpubitmap));
57 FILE *f = fopen("/proc/cpuinfo","r");
58 if (!f)
59 return -1;
61 char buf[8192];
62 while (fgets(buf,sizeof(buf),f)) {
63 // we don't like newlines
64 for (char *p = buf;*p;++p) {
65 if (*p == '\n') {
66 *p = 0;
67 break;
70 // split ':'
71 char *v = 0;
72 for (char *p = buf;*p;++p) {
73 if (*p == ':') {
74 *p = 0;
75 v = p + 1;
76 break;
79 // key padding
80 size_t kl = strlen(buf);
81 while (kl > 0 && (buf[kl - 1] == '\t' || buf[kl - 1] == ' ')) {
82 --kl;
83 buf[kl] = 0;
85 // space before value
86 if (v) {
87 while (*v && (*v == ' ' || *v == '\t'))
88 ++v;
90 // check what we need
91 if (strcasecmp(buf,"processor") == 0 && v) {
92 char *endp = 0;
93 long n = strtol(v,&endp,10);
94 if (endp && endp > v && n >= 0 && n < sizeof(cpubitmap) * 8)
95 cpubitmap[n / 8] |= 1 << (n % 8);
99 fclose(f);
101 // count bits in bitmap
102 int ncpu = 0;
103 for (size_t n = 0;n < sizeof(cpubitmap) * 8;++n)
104 if (cpubitmap[n / 8] & (1 << (n % 8)))
105 ++ncpu;
107 return ncpu;
109 #endif
111 #include "cpucount.h"
113 int cpucount()
115 int ncpu;
116 #ifdef _SC_NPROCESSORS_ONLN
117 ncpu = (int)sysconf(_SC_NPROCESSORS_ONLN);
118 if (ncpu > 0)
119 return ncpu;
120 #endif
121 #ifdef __linux__
122 // try parsing /proc/cpuinfo
123 ncpu = parsecpuinfo();
124 if (ncpu > 0)
125 return ncpu;
126 #endif
127 #ifdef BSD
128 const int ctlname[2] = {CTL_HW,HW_NCPU};
129 size_t ctllen = sizeof(ncpu);
130 if (sysctl(ctlname,2,&ncpu,&ctllen,0,0) < 0)
131 ncpu = -1;
132 if (ncpu > 0)
133 return ncpu;
134 #endif
135 return -1;