From d28acc42ec0f8dff9471e4663cfe55aa5da86656 Mon Sep 17 00:00:00 2001 From: Russ Cox Date: Mon, 4 Aug 2008 16:43:49 -0700 Subject: first cut at multithreading. works on Linux. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * kick off new os procs (machs) as needed * add sys·sleep for testing * add Lock, Rendez * properly lock mal, sys·newproc, scheduler * linux syscall arg #4 is in R10, not CX * chans are not multithread-safe yet * multithreading disabled by default; set $gomaxprocs=2 (or 1000) to turn it on This should build on OS X but may not. Rob and I will fix soon after submitting. TBR=r OCL=13784 CL=13842 --- src/runtime/sys_amd64_linux.s | 88 ++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 82 insertions(+), 6 deletions(-) (limited to 'src/runtime/sys_amd64_linux.s') diff --git a/src/runtime/sys_amd64_linux.s b/src/runtime/sys_amd64_linux.s index 106159dc8e..60091e5c84 100644 --- a/src/runtime/sys_amd64_linux.s +++ b/src/runtime/sys_amd64_linux.s @@ -8,7 +8,13 @@ TEXT sys·exit(SB),1,$0-8 MOVL 8(SP), DI - MOVL $60, AX + MOVL $231, AX // force all os threads to exit + SYSCALL + RET + +TEXT exit1(SB),1,$0-8 + MOVL 8(SP), DI + MOVL $60, AX // exit the current os thread SYSCALL RET @@ -61,8 +67,7 @@ TEXT sys·rt_sigaction(SB),1,$0-32 MOVL 8(SP), DI MOVQ 16(SP), SI MOVQ 24(SP), DX - MOVQ 32(SP), CX - MOVL CX, R10 + MOVQ 32(SP), R10 MOVL $13, AX // syscall entry SYSCALL RET @@ -74,11 +79,11 @@ TEXT sigtramp(SB),1,$24-16 CALL sighandler(SB) RET -TEXT sys·mmap(SB),1,$0-32 +TEXT sys·mmap(SB),7,$0-32 MOVQ 8(SP), DI MOVL 16(SP), SI MOVL 20(SP), DX - MOVL 24(SP), CX + MOVL 24(SP), R10 MOVL 28(SP), R8 MOVL 32(SP), R9 @@ -102,7 +107,7 @@ TEXT notok(SB),7,$0 MOVQ BP, (BP) RET -TEXT sys·memclr(SB),1,$0-16 +TEXT sys·memclr(SB),7,$0-16 MOVQ 8(SP), DI // arg 1 addr MOVL 16(SP), CX // arg 2 count (cannot be zero) ADDL $7, CX @@ -123,3 +128,74 @@ TEXT sys·setcallerpc+0(SB),1,$0 MOVQ x+8(FP), BX MOVQ BX, -8(AX) // set calling pc RET + +// int64 futex(int32 *uaddr, int32 op, int32 val, +// struct timespec *timeout, int32 *uaddr2, int32 val2); +TEXT futex(SB),1,$0 + MOVQ 8(SP), DI + MOVL 16(SP), SI + MOVL 20(SP), DX + MOVQ 24(SP), R10 + MOVQ 32(SP), R8 + MOVL 40(SP), R9 + MOVL $202, AX + SYSCALL + RET + +// int64 clone(int32 flags, void *stack, M *m, G *g, void (*fn)(void*), void *arg); +TEXT clone(SB),7,$0 + MOVL 8(SP), DI + MOVQ 16(SP), SI + + // Copy m, g, fn, arg off parent stack for use by child. + // Careful: Linux system call clobbers CX and R11. + MOVQ 24(SP), R8 + MOVQ 32(SP), R9 + MOVQ 40(SP), R12 + MOVQ 48(SP), R13 + + MOVL $56, AX + SYSCALL + + // In parent, return. + CMPQ AX, $0 + JEQ 2(PC) + RET + + // In child, call fn(arg) on new stack + MOVQ SI, SP + MOVQ R8, R14 // m + MOVQ R9, R15 // g + PUSHQ R13 + CALL R12 + + // It shouldn't return. If it does, exit + MOVL $111, DI + MOVL $60, AX + SYSCALL + JMP -3(PC) // keep exiting + +// int64 select(int32, void*, void*, void*, void*) +TEXT select(SB),1,$0 + MOVL 8(SP), DI + MOVQ 16(SP), SI + MOVQ 24(SP), DX + MOVQ 32(SP), R10 + MOVQ 40(SP), R8 + MOVL $23, AX + SYSCALL + RET + +// Linux allocates each thread its own pid, like Plan 9. +// But the getpid() system call returns the pid of the +// original thread (the one that exec started with), +// no matter which thread asks. This system call, +// which Linux calls gettid, returns the actual pid of +// the calling thread, not the fake one. +// +// int32 getprocid(void) +TEXT getprocid(SB),1,$0 + MOVL $186, AX + SYSCALL + RET + -- cgit v1.3-5-g9baa