Commit 689d5b91 authored by Joel Sing's avatar Joel Sing

runtime: use __tfork() syscall on openbsd

Switch from using the rfork() syscall on OpenBSD, to the __tfork()
syscall.  The __tfork() syscall is the preferred way of creating
system threads and the rfork() syscall has recently been removed.

Note: this will break compatibility with OpenBSD releases prior to 5.1.

R=golang-dev, bradfitz, devon.odell, rsc
CC=golang-dev
https://golang.org/cl/6037048
parent fdce27f7
...@@ -187,40 +187,42 @@ TEXT runtime·sigtramp(SB),7,$44 ...@@ -187,40 +187,42 @@ TEXT runtime·sigtramp(SB),7,$44
MOVL $0xf1, 0xf1 // crash MOVL $0xf1, 0xf1 // crash
RET RET
// int32 rfork_thread(int32 flags, void *stack, M *m, G *g, void (*fn)(void)); // int32 tfork_thread(void *param, void *stack, M *m, G *g, void (*fn)(void));
TEXT runtime·rfork_thread(SB),7,$8 TEXT runtime·tfork_thread(SB),7,$8
MOVL flags+8(SP), AX
MOVL stack+12(SP), CX
// Copy m, g, fn off parent stack for use by child. // Copy m, g, fn off parent stack and onto the child stack.
MOVL stack+8(FP), CX
SUBL $16, CX SUBL $16, CX
MOVL mm+16(SP), SI MOVL mm+12(FP), SI
MOVL SI, 0(CX) MOVL SI, 0(CX)
MOVL gg+20(SP), SI MOVL gg+16(FP), SI
MOVL SI, 4(CX) MOVL SI, 4(CX)
MOVL fn+24(SP), SI MOVL fn+20(FP), SI
MOVL SI, 8(CX) MOVL SI, 8(CX)
MOVL $1234, 12(CX) MOVL $1234, 12(CX)
MOVL CX, SI MOVL CX, SI
MOVL $0, 0(SP) // syscall gap MOVL $0, 0(SP) // syscall gap
MOVL AX, 4(SP) // arg 1 - flags MOVL params+4(FP), AX
MOVL $251, AX // sys_rfork MOVL AX, 4(SP) // arg 1 - param
MOVL $328, AX // sys___tfork
INT $0x80 INT $0x80
// Return if rfork syscall failed // Return if tfork syscall failed.
JCC 4(PC) JCC 5(PC)
NEGL AX NEGL AX
MOVL AX, 48(SP) MOVL ret+0(FP), DX
MOVL AX, 0(DX)
RET RET
// In parent, return. // In parent, return.
CMPL AX, $0 CMPL AX, $0
JEQ 3(PC) JEQ 4(PC)
MOVL AX, 48(SP) MOVL ret+0(FP), DX
MOVL AX, 0(DX)
RET RET
// In child, on new stack. // In child, switch to new stack.
MOVL SI, SP MOVL SI, SP
// Paranoia: check that SP is as we expect. // Paranoia: check that SP is as we expect.
...@@ -229,17 +231,12 @@ TEXT runtime·rfork_thread(SB),7,$8 ...@@ -229,17 +231,12 @@ TEXT runtime·rfork_thread(SB),7,$8
JEQ 2(PC) JEQ 2(PC)
INT $3 INT $3
// Reload registers // Reload registers.
MOVL 0(SP), BX // m MOVL 0(SP), BX // m
MOVL 4(SP), DX // g MOVL 4(SP), DX // g
MOVL 8(SP), SI // fn MOVL 8(SP), SI // fn
// Initialize m->procid to thread ID // Set FS to point at m->tls.
MOVL $299, AX // sys_getthrid
INT $0x80
MOVL AX, m_procid(BX)
// Set FS to point at m->tls
LEAL m_tls(BX), BP LEAL m_tls(BX), BP
PUSHAL // save registers PUSHAL // save registers
PUSHL BP PUSHL BP
...@@ -256,12 +253,12 @@ TEXT runtime·rfork_thread(SB),7,$8 ...@@ -256,12 +253,12 @@ TEXT runtime·rfork_thread(SB),7,$8
MOVL 0(DX), DX // paranoia; check they are not nil MOVL 0(DX), DX // paranoia; check they are not nil
MOVL 0(BX), BX MOVL 0(BX), BX
// more paranoia; check that stack splitting code works // More paranoia; check that stack splitting code works.
PUSHAL PUSHAL
CALL runtime·emptyfunc(SB) CALL runtime·emptyfunc(SB)
POPAL POPAL
// Call fn // Call fn.
CALL SI CALL SI
CALL runtime·exit1(SB) CALL runtime·exit1(SB)
......
...@@ -8,20 +8,20 @@ ...@@ -8,20 +8,20 @@
#include "zasm_GOOS_GOARCH.h" #include "zasm_GOOS_GOARCH.h"
// int64 rfork_thread(int32 flags, void *stack, M *m, G *g, void (*fn)(void)); // int64 tfork_thread(void *param, void *stack, M *m, G *g, void (*fn)(void));
TEXT runtime·rfork_thread(SB),7,$0 TEXT runtime·tfork_thread(SB),7,$32
MOVL flags+8(SP), DI
MOVQ stack+16(SP), SI
// Copy m, g, fn off parent stack for use by child. // Copy stack, m, g and fn off parent stack for use by child.
MOVQ mm+24(SP), R8 MOVQ stack+8(FP), SI
MOVQ gg+32(SP), R9 MOVQ mm+16(FP), R8
MOVQ fn+40(SP), R12 MOVQ gg+24(FP), R9
MOVQ fn+32(FP), R12
MOVL $251, AX // sys_rfork MOVQ param+0(FP), DI
MOVL $328, AX // sys___tfork
SYSCALL SYSCALL
// Return if rfork syscall failed // Return if tfork syscall failed.
JCC 3(PC) JCC 3(PC)
NEGL AX NEGL AX
RET RET
...@@ -31,19 +31,14 @@ TEXT runtime·rfork_thread(SB),7,$0 ...@@ -31,19 +31,14 @@ TEXT runtime·rfork_thread(SB),7,$0
JEQ 2(PC) JEQ 2(PC)
RET RET
// In child, on new stack. // In child, switch to new stack.
MOVQ SI, SP MOVQ SI, SP
// Initialize m->procid to thread ID
MOVL $299, AX // sys_getthrid
SYSCALL
MOVQ AX, m_procid(R8)
// Set FS to point at m->tls. // Set FS to point at m->tls.
LEAQ m_tls(R8), DI LEAQ m_tls(R8), DI
CALL runtime·settls(SB) CALL runtime·settls(SB)
// In child, set up new stack // In child, set up new stack.
get_tls(CX) get_tls(CX)
MOVQ R8, m(CX) MOVQ R8, m(CX)
MOVQ R9, g(CX) MOVQ R9, g(CX)
......
...@@ -23,7 +23,7 @@ extern SigTab runtime·sigtab[]; ...@@ -23,7 +23,7 @@ extern SigTab runtime·sigtab[];
static Sigset sigset_all = ~(Sigset)0; static Sigset sigset_all = ~(Sigset)0;
static Sigset sigset_none; static Sigset sigset_none;
extern int64 runtime·rfork_thread(int32 flags, void *stack, M *m, G *g, void (*fn)(void)); extern int64 runtime·tfork_thread(void *param, void *stack, M *m, G *g, void (*fn)(void));
extern int32 runtime·thrsleep(void *ident, int32 clock_id, void *tsp, void *lock, const int32 *abort); extern int32 runtime·thrsleep(void *ident, int32 clock_id, void *tsp, void *lock, const int32 *abort);
extern int32 runtime·thrwakeup(void *ident, int32 n); extern int32 runtime·thrwakeup(void *ident, int32 n);
...@@ -122,22 +122,14 @@ runtime·semawakeup(M *mp) ...@@ -122,22 +122,14 @@ runtime·semawakeup(M *mp)
runtime·atomicstore(&mp->waitsemalock, 0); runtime·atomicstore(&mp->waitsemalock, 0);
} }
// From OpenBSD's sys/param.h
#define RFPROC (1<<4) /* change child (else changes curproc) */
#define RFMEM (1<<5) /* share `address space' */
#define RFNOWAIT (1<<6) /* parent need not wait() on child */
#define RFTHREAD (1<<13) /* create a thread, not a process */
void void
runtime·newosproc(M *m, G *g, void *stk, void (*fn)(void)) runtime·newosproc(M *m, G *g, void *stk, void (*fn)(void))
{ {
Tfork param;
Sigset oset; Sigset oset;
int32 flags;
int32 ret; int32 ret;
flags = RFPROC | RFTHREAD | RFMEM | RFNOWAIT; if(0) {
if (0) {
runtime·printf( runtime·printf(
"newosproc stk=%p m=%p g=%p fn=%p id=%d/%d ostk=%p\n", "newosproc stk=%p m=%p g=%p fn=%p id=%d/%d ostk=%p\n",
stk, m, g, fn, m->id, m->tls[0], &m); stk, m, g, fn, m->id, m->tls[0], &m);
...@@ -145,8 +137,12 @@ runtime·newosproc(M *m, G *g, void *stk, void (*fn)(void)) ...@@ -145,8 +137,12 @@ runtime·newosproc(M *m, G *g, void *stk, void (*fn)(void))
m->tls[0] = m->id; // so 386 asm can find it m->tls[0] = m->id; // so 386 asm can find it
param.tf_tcb = (byte*)&m->tls[0];
param.tf_tid = (int32*)&m->procid;
param.tf_flags = (int32)0;
oset = runtime·sigprocmask(SIG_SETMASK, sigset_all); oset = runtime·sigprocmask(SIG_SETMASK, sigset_all);
ret = runtime·rfork_thread(flags, stk, m, g, fn); ret = runtime·tfork_thread((byte*)&param, stk, m, g, fn);
runtime·sigprocmask(SIG_SETMASK, oset); runtime·sigprocmask(SIG_SETMASK, oset);
if(ret < 0) { if(ret < 0) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment