aboutsummaryrefslogtreecommitdiff
path: root/libgo
diff options
context:
space:
mode:
authorIan Lance Taylor <ian@gcc.gnu.org>2012-08-10 06:08:11 +0000
committerIan Lance Taylor <ian@gcc.gnu.org>2012-08-10 06:08:11 +0000
commit938ff79ae799ad8e961c6562b31d20899c6a132b (patch)
treeaa24175caf108038c2ecde81b10654a851f55416 /libgo
parent0d8e4dacd4781c147ad32dbc48a3382117bca9f6 (diff)
downloadgcc-938ff79ae799ad8e961c6562b31d20899c6a132b.zip
gcc-938ff79ae799ad8e961c6562b31d20899c6a132b.tar.gz
gcc-938ff79ae799ad8e961c6562b31d20899c6a132b.tar.bz2
runtime: use sched_getaffinity for runtime.NumCPU() on Linux
Fixes Go issue 3921 for gccgo. From Shenghou Ma. From-SVN: r190282
Diffstat (limited to 'libgo')
-rw-r--r--libgo/runtime/getncpu-linux.c53
1 files changed, 21 insertions, 32 deletions
diff --git a/libgo/runtime/getncpu-linux.c b/libgo/runtime/getncpu-linux.c
index 05bd4a3..0122b77 100644
--- a/libgo/runtime/getncpu-linux.c
+++ b/libgo/runtime/getncpu-linux.c
@@ -2,46 +2,35 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-#include <string.h>
-#include <sys/types.h>
-#include <fcntl.h>
-#include <unistd.h>
+#include <features.h>
+#include <sched.h>
-#include "runtime.h"
-#include "defs.h"
+// CPU_COUNT is only provided by glibc 2.6 or higher
+#if !defined(__GLIBC_PREREQ) || !__GLIBC_PREREQ(2, 6)
+#define CPU_COUNT(set) _CPU_COUNT((unsigned int *)(set), sizeof(*(set))/sizeof(unsigned int))
+static int _CPU_COUNT(unsigned int *set, size_t len) {
+ int cnt;
-#ifndef O_CLOEXEC
-#define O_CLOEXEC 0
+ cnt = 0;
+ while (len--)
+ cnt += __builtin_popcount(*set++);
+ return cnt;
+}
#endif
+#include "runtime.h"
+#include "defs.h"
+
int32
getproccount(void)
{
- int32 fd, rd, cnt, cpustrlen;
- const char *cpustr;
- const byte *pos;
- byte *bufpos;
- byte buf[256];
+ cpu_set_t set;
+ int32 r, cnt;
- fd = open("/proc/stat", O_RDONLY|O_CLOEXEC, 0);
- if(fd == -1)
- return 1;
cnt = 0;
- bufpos = buf;
- cpustr = "\ncpu";
- cpustrlen = strlen(cpustr);
- for(;;) {
- rd = read(fd, bufpos, sizeof(buf)-cpustrlen);
- if(rd == -1)
- break;
- bufpos[rd] = 0;
- for(pos=buf; (pos=(const byte*)strstr((const char*)pos, cpustr)) != nil; cnt++, pos++) {
- }
- if(rd < cpustrlen)
- break;
- memmove(buf, bufpos+rd-cpustrlen+1, cpustrlen-1);
- bufpos = buf+cpustrlen-1;
- }
- close(fd);
+ r = sched_getaffinity(0, sizeof(set), &set);
+ if(r == 0)
+ cnt += CPU_COUNT(&set);
+
return cnt ? cnt : 1;
}