forked from cathugger/mkp224o
-
Notifications
You must be signed in to change notification settings - Fork 0
/
cpucount.c
149 lines (137 loc) · 2.6 KB
/
cpucount.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
#include "cpucount.h"
#ifndef BSD
# ifndef __linux__
// FreeBSD
# ifdef __FreeBSD__
# undef BSD
# define BSD
# endif
// OpenBSD
# ifdef __OpenBSD__
# undef BSD
# define BSD
# endif
// NetBSD
# ifdef __NetBSD__
# undef BSD
# define BSD
# endif
// DragonFly
# ifdef __DragonFly__
# undef BSD
# define BSD
# endif
# endif // __linux__
// sys/param.h may have its own define
# ifdef BSD
# undef BSD
# include <sys/param.h>
# define SYS_PARAM_INCLUDED
# ifndef BSD
# define BSD
# endif
# endif
#endif // BSD
#ifdef BSD
# ifndef SYS_PARAM_INCLUDED
# include <sys/param.h>
# endif
# include <sys/sysctl.h>
#endif
#include <string.h>
#ifndef _WIN32
#include <unistd.h>
#else
#define UNICODE 1
#include <windows.h>
#endif
#ifdef __linux__
#include <stdio.h>
#include <stdlib.h>
#include <strings.h>
static int parsecpuinfo(void)
{
unsigned char cpubitmap[128];
memset(cpubitmap,0,sizeof(cpubitmap));
FILE *f = fopen("/proc/cpuinfo","r");
if (!f)
return -1;
char buf[8192];
while (fgets(buf,sizeof(buf),f)) {
// we don't like newlines
for (char *p = buf;*p;++p) {
if (*p == '\n') {
*p = 0;
break;
}
}
// split ':'
char *v = 0;
for (char *p = buf;*p;++p) {
if (*p == ':') {
*p = 0;
v = p + 1;
break;
}
}
// key padding
size_t kl = strlen(buf);
while (kl > 0 && (buf[kl - 1] == '\t' || buf[kl - 1] == ' ')) {
--kl;
buf[kl] = 0;
}
// space before value
if (v) {
while (*v && (*v == ' ' || *v == '\t'))
++v;
}
// check what we need
if (strcasecmp(buf,"processor") == 0 && v) {
char *endp = 0;
long n = strtol(v,&endp,10);
if (endp && endp > v && n >= 0 && (size_t)n < sizeof(cpubitmap) * 8)
cpubitmap[n / 8] |= 1 << (n % 8);
}
}
fclose(f);
// count bits in bitmap
int ncpu = 0;
for (size_t n = 0;n < sizeof(cpubitmap) * 8;++n)
if (cpubitmap[n / 8] & (1 << (n % 8)))
++ncpu;
return ncpu;
}
#endif
int cpucount(void)
{
int ncpu;
#ifdef _SC_NPROCESSORS_ONLN
ncpu = (int)sysconf(_SC_NPROCESSORS_ONLN);
if (ncpu > 0)
return ncpu;
#endif
#ifdef __linux__
// try parsing /proc/cpuinfo
// NOTE seems cygwin can provide this too, idk if need tho
ncpu = parsecpuinfo();
if (ncpu > 0)
return ncpu;
#endif
#ifdef BSD
const int ctlname[2] = {CTL_HW,HW_NCPU};
size_t ctllen = sizeof(ncpu);
if (sysctl(ctlname,2,&ncpu,&ctllen,0,0) < 0)
ncpu = -1;
if (ncpu > 0)
return ncpu;
#endif
#ifdef _WIN32
SYSTEM_INFO sysinfo;
GetSystemInfo(&sysinfo);
ncpu = (int)sysinfo.dwNumberOfProcessors;
if (ncpu > 0)
return ncpu;
#endif
(void) ncpu;
return -1;
}