]> Cypherpunks repositories - gostls13.git/commitdiff
runtime: use sched_getaffinity for runtime.NumCPU() on Linux
authorShenghou Ma <minux.ma@gmail.com>
Fri, 10 Aug 2012 02:05:26 +0000 (10:05 +0800)
committerShenghou Ma <minux.ma@gmail.com>
Fri, 10 Aug 2012 02:05:26 +0000 (10:05 +0800)
        Fixes #3921.

R=iant
CC=golang-dev
https://golang.org/cl/6448132

src/pkg/runtime/sys_linux_386.s
src/pkg/runtime/sys_linux_amd64.s
src/pkg/runtime/sys_linux_arm.s
src/pkg/runtime/thread_linux.c

index 602d9ddac1cdad3a25cde88745e2d8e2b5b042ff..d9f979f509bb7aa8d8f46f2983253d3cc390e1c2 100644 (file)
@@ -423,3 +423,11 @@ TEXT runtime·osyield(SB),7,$0
        MOVL    $158, AX
        CALL    *runtime·_vdso(SB)
        RET
+
+TEXT runtime·sched_getaffinity(SB),7,$0
+       MOVL    $242, AX                // syscall - sched_getaffinity
+       MOVL    4(SP), BX
+       MOVL    8(SP), CX
+       MOVL    12(SP), DX
+       CALL    *runtime·_vdso(SB)
+       RET
index 657ab7e0bbf3859ebd947fe1f70eaf33f63a3837..e0ca6583c65e10a4c4af757253b69c6fadec12e1 100644 (file)
@@ -310,3 +310,11 @@ TEXT runtime·osyield(SB),7,$0
        MOVL    $24, AX
        SYSCALL
        RET
+
+TEXT runtime·sched_getaffinity(SB),7,$0
+       MOVQ    8(SP), DI
+       MOVL    16(SP), SI
+       MOVQ    24(SP), DX
+       MOVL    $204, AX                        // syscall entry
+       SYSCALL
+       RET
index 220f9adac7a87ec599fbc8af92551fc8fb7d1861..0112cf915855a7cac6a7a0e6bab7233895be7506 100644 (file)
@@ -34,6 +34,7 @@
 #define SYS_sched_yield (SYS_BASE + 158)
 #define SYS_select (SYS_BASE + 142) // newselect
 #define SYS_ugetrlimit (SYS_BASE + 191)
+#define SYS_sched_getaffinity (SYS_BASE + 242)
 
 #define ARM_BASE (SYS_BASE + 0x0f0000)
 #define SYS_ARM_cacheflush (ARM_BASE + 2)
@@ -393,3 +394,11 @@ TEXT runtime·osyield(SB),7,$0
        MOVW    $SYS_sched_yield, R7
        SWI     $0
        RET
+
+TEXT runtime·sched_getaffinity(SB),7,$0
+       MOVW    0(FP), R0
+       MOVW    4(FP), R1
+       MOVW    8(FP), R2
+       MOVW    $SYS_sched_getaffinity, R7
+       SWI     $0
+       RET
index 5db074175c91cdc99ed7e76877e0625fa209aa8e..f66d2dd4d256adab8b8358caa5372c2f1c230c23 100644 (file)
@@ -80,33 +80,23 @@ runtime·futexwakeup(uint32 *addr, uint32 cnt)
        *(int32*)0x1006 = 0x1006;
 }
 
+extern runtime·sched_getaffinity(uintptr pid, uintptr len, uintptr *buf);
 static int32
 getproccount(void)
 {
-       int32 fd, rd, cnt, cpustrlen;
-       byte *cpustr, *pos, *bufpos;
-       byte buf[256];
+       uintptr buf[16], t;
+       int32 r, cnt, i;
 
-       fd = runtime·open((byte*)"/proc/stat", O_RDONLY|O_CLOEXEC, 0);
-       if(fd == -1)
-               return 1;
        cnt = 0;
-       bufpos = buf;
-       cpustr = (byte*)"\ncpu";
-       cpustrlen = runtime·findnull(cpustr);
-       for(;;) {
-               rd = runtime·read(fd, bufpos, sizeof(buf)-cpustrlen);
-               if(rd == -1)
-                       break;
-               bufpos[rd] = 0;
-               for(pos=buf; pos=runtime·strstr(pos, cpustr); cnt++, pos++) {
-               }
-               if(rd < cpustrlen)
-                       break;
-               runtime·memmove(buf, bufpos+rd-cpustrlen+1, cpustrlen-1);
-               bufpos = buf+cpustrlen-1;
+       r = runtime·sched_getaffinity(0, sizeof(buf), buf);
+       if(r > 0)
+       for(i = 0; i < r/sizeof(buf[0]); i++) {
+               t = buf[i];
+               t = t - ((t >> 1) & 0x5555555555555555ULL);
+               t = (t & 0x3333333333333333ULL) + ((t >> 2) & 0x3333333333333333ULL);
+               cnt += (int32)((((t + (t >> 4)) & 0xF0F0F0F0F0F0F0FULL) * 0x101010101010101ULL) >> 56);
        }
-       runtime·close(fd);
+
        return cnt ? cnt : 1;
 }