Skip to content

Commit 21656d0

Browse files
committed
runtime: convert exit to use pthread library on Darwin
Now we no longer need to mess with TLS on Darwin 386/amd64, we always rely on the pthread library to set it up. We now just use one entry in the TLS for the G. Return from mstart to let the pthread library clean up the OS thread. Change-Id: Iccf58049d545515d9b1d090b161f420e40ffd244 Reviewed-on: https://go-review.googlesource.com/110215 Reviewed-by: Ian Lance Taylor <[email protected]>
1 parent 6f7ec48 commit 21656d0

File tree

7 files changed

+62
-132
lines changed

7 files changed

+62
-132
lines changed

src/runtime/asm_386.s

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -228,6 +228,10 @@ needtls:
228228
// skip runtime·ldt0setup(SB) and tls test on Plan 9 in all cases
229229
JMP ok
230230
#endif
231+
#ifdef GOOS_darwin
232+
// skip runtime·ldt0setup(SB) on Darwin
233+
JMP ok
234+
#endif
231235

232236
// set up %gs
233237
CALL runtime·ldt0setup(SB)

src/runtime/asm_amd64.s

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,10 @@ needtls:
188188
// skip TLS setup on Solaris
189189
JMP ok
190190
#endif
191+
#ifdef GOOS_darwin
192+
// skip TLS setup on Darwin
193+
JMP ok
194+
#endif
191195

192196
LEAQ runtime·m0+m_tls(SB), DI
193197
CALL runtime·settls(SB)

src/runtime/os_darwin.go

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -135,11 +135,14 @@ func newosproc(mp *m) {
135135
exit(1)
136136
}
137137

138-
// Set the stack we want to use.
139-
if pthread_attr_setstack(&attr, unsafe.Pointer(mp.g0.stack.lo), mp.g0.stack.hi-mp.g0.stack.lo) != 0 {
138+
// Set the stack size we want to use. 64KB for now.
139+
// TODO: just use OS default size?
140+
const stackSize = 1 << 16
141+
if pthread_attr_setstacksize(&attr, stackSize) != 0 {
140142
write(2, unsafe.Pointer(&failthreadcreate[0]), int32(len(failthreadcreate)))
141143
exit(1)
142144
}
145+
//mSysStatInc(&memstats.stacks_sys, stackSize) //TODO: do this?
143146

144147
// Tell the pthread library we won't join with this thread.
145148
if pthread_attr_setdetachstate(&attr, _PTHREAD_CREATE_DETACHED) != 0 {
@@ -169,12 +172,6 @@ func mstart_stub()
169172
//
170173
//go:nosplit
171174
func newosproc0(stacksize uintptr, fn uintptr) {
172-
stack := sysAlloc(stacksize, &memstats.stacks_sys)
173-
if stack == nil {
174-
write(2, unsafe.Pointer(&failallocatestack[0]), int32(len(failallocatestack)))
175-
exit(1)
176-
}
177-
178175
// Initialize an attribute object.
179176
var attr pthreadattr
180177
var err int32
@@ -185,10 +182,11 @@ func newosproc0(stacksize uintptr, fn uintptr) {
185182
}
186183

187184
// Set the stack we want to use.
188-
if pthread_attr_setstack_trampoline(&attr, stack, stacksize) != 0 {
185+
if pthread_attr_setstacksize_trampoline(&attr, stacksize) != 0 {
189186
write(2, unsafe.Pointer(&failthreadcreate[0]), int32(len(failthreadcreate)))
190187
exit(1)
191188
}
189+
mSysStatInc(&memstats.stacks_sys, stacksize)
192190

193191
// Tell the pthread library we won't join with this thread.
194192
if pthread_attr_setdetachstate_trampoline(&attr, _PTHREAD_CREATE_DETACHED) != 0 {

src/runtime/proc.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1195,8 +1195,8 @@ func mstart() {
11951195
mstart1()
11961196

11971197
// Exit this thread.
1198-
if GOOS == "windows" || GOOS == "solaris" || GOOS == "plan9" {
1199-
// Window, Solaris and Plan 9 always system-allocate
1198+
if GOOS == "windows" || GOOS == "solaris" || GOOS == "plan9" || (GOOS == "darwin" && (GOARCH == "amd64" || GOARCH == "386")) {
1199+
// Window, Solaris, Darwin and Plan 9 always system-allocate
12001200
// the stack, but put it in _g_.stack before mstart,
12011201
// so the logic above hasn't set osStack yet.
12021202
osStack = true
@@ -1517,9 +1517,9 @@ func allocm(_p_ *p, fn func()) *m {
15171517
mp.mstartfn = fn
15181518
mcommoninit(mp)
15191519

1520-
// In case of cgo or Solaris, pthread_create will make us a stack.
1520+
// In case of cgo or Solaris or Darwin, pthread_create will make us a stack.
15211521
// Windows and Plan 9 will layout sched stack on OS stack.
1522-
if iscgo || GOOS == "solaris" || GOOS == "windows" || GOOS == "plan9" {
1522+
if iscgo || GOOS == "solaris" || GOOS == "windows" || GOOS == "plan9" || (GOOS == "darwin" && (GOARCH == "386" || GOARCH == "amd64")) {
15231523
mp.g0 = malg(-1)
15241524
} else {
15251525
mp.g0 = malg(8192 * sys.StackGuardMultiplier)

src/runtime/sys_darwin.go

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,15 +21,15 @@ func pthread_attr_init(attr *pthreadattr) (errno int32) {
2121
func pthread_attr_init_trampoline(attr *pthreadattr) int32
2222

2323
//go:nowritebarrier
24-
func pthread_attr_setstack(attr *pthreadattr, addr unsafe.Pointer, size uintptr) (errno int32) {
24+
func pthread_attr_setstacksize(attr *pthreadattr, size uintptr) (errno int32) {
2525
systemstack(func() {
26-
errno = pthread_attr_setstack_trampoline(attr, addr, size)
26+
errno = pthread_attr_setstacksize_trampoline(attr, size)
2727
})
2828
return
2929
}
3030

3131
//go:noescape
32-
func pthread_attr_setstack_trampoline(attr *pthreadattr, addr unsafe.Pointer, size uintptr) int32
32+
func pthread_attr_setstacksize_trampoline(attr *pthreadattr, size uintptr) int32
3333

3434
//go:nowritebarrier
3535
func pthread_attr_setdetachstate(attr *pthreadattr, state int) (errno int32) {
@@ -57,9 +57,10 @@ func pthread_create_trampoline(t *pthread, attr *pthreadattr, start uintptr, arg
5757
// in a system library, with the libc_ prefix missing.
5858

5959
//go:cgo_import_dynamic libc_pthread_attr_init pthread_attr_init "/usr/lib/libSystem.B.dylib"
60-
//go:cgo_import_dynamic libc_pthread_attr_setstack pthread_attr_setstack "/usr/lib/libSystem.B.dylib"
60+
//go:cgo_import_dynamic libc_pthread_attr_setstacksize pthread_attr_setstacksize "/usr/lib/libSystem.B.dylib"
6161
//go:cgo_import_dynamic libc_pthread_attr_setdetachstate pthread_attr_setdetachstate "/usr/lib/libSystem.B.dylib"
6262
//go:cgo_import_dynamic libc_pthread_create pthread_create "/usr/lib/libSystem.B.dylib"
63+
//go:cgo_import_dynamic libc_exit exit "/usr/lib/libSystem.B.dylib"
6364

6465
// Magic incantation to get libSystem actually dynamically linked.
6566
// TODO: Why does the code require this? See cmd/compile/internal/ld/go.go:210

src/runtime/sys_darwin_386.s

Lines changed: 21 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -11,46 +11,23 @@
1111
#include "textflag.h"
1212

1313
// Exit the entire program (like C exit)
14-
TEXT runtime·exit(SB),NOSPLIT,$0
15-
MOVL $1, AX
16-
INT $0x80
17-
MOVL $0xf1, 0xf1 // crash
18-
RET
19-
20-
// Exit this OS thread (like pthread_exit, which eventually
21-
// calls __bsdthread_terminate).
22-
TEXT exit1<>(SB),NOSPLIT,$16-0
23-
// __bsdthread_terminate takes 4 word-size arguments.
24-
// Set them all to 0. (None are an exit status.)
25-
MOVL $0, 0(SP)
26-
MOVL $0, 4(SP)
27-
MOVL $0, 8(SP)
28-
MOVL $0, 12(SP)
29-
MOVL $361, AX
30-
INT $0x80
31-
JAE 2(PC)
14+
TEXT runtime·exit(SB),NOSPLIT,$0-4
15+
MOVL code+0(FP), AX
16+
PUSHL BP
17+
MOVL SP, BP
18+
SUBL $4, SP // allocate space for callee args
19+
ANDL $~15, SP // align stack
20+
MOVL AX, 0(SP)
21+
CALL libc_exit(SB)
3222
MOVL $0xf1, 0xf1 // crash
23+
MOVL BP, SP
24+
POPL BP
3325
RET
3426

35-
GLOBL exitStack<>(SB),RODATA,$(4*4)
36-
DATA exitStack<>+0x00(SB)/4, $0
37-
DATA exitStack<>+0x04(SB)/4, $0
38-
DATA exitStack<>+0x08(SB)/4, $0
39-
DATA exitStack<>+0x0c(SB)/4, $0
40-
41-
// func exitThread(wait *uint32)
27+
// Not used on Darwin.
4228
TEXT runtime·exitThread(SB),NOSPLIT,$0-4
43-
MOVL wait+0(FP), AX
44-
// We're done using the stack.
45-
MOVL $0, (AX)
46-
// __bsdthread_terminate takes 4 arguments, which it expects
47-
// on the stack. They should all be 0, so switch over to a
48-
// fake stack of 0s. It won't write to the stack.
49-
MOVL $exitStack<>(SB), SP
50-
MOVL $361, AX // __bsdthread_terminate
51-
INT $0x80
5229
MOVL $0xf1, 0xf1 // crash
53-
JMP 0(PC)
30+
RET
5431

5532
TEXT runtime·open(SB),NOSPLIT,$0
5633
MOVL $5, AX
@@ -437,38 +414,8 @@ TEXT runtime·mach_semaphore_signal_all(SB),NOSPLIT,$0
437414
RET
438415

439416
// func setldt(entry int, address int, limit int)
440-
// entry and limit are ignored.
441417
TEXT runtime·setldt(SB),NOSPLIT,$32
442-
MOVL address+4(FP), BX // aka base
443-
444-
/*
445-
* When linking against the system libraries,
446-
* we use its pthread_create and let it set up %gs
447-
* for us. When we do that, the private storage
448-
* we get is not at 0(GS) but at 0x18(GS).
449-
* The linker rewrites 0(TLS) into 0x18(GS) for us.
450-
* To accommodate that rewrite, we translate the
451-
* address here so that 0x18(GS) maps to 0(address).
452-
*
453-
* Constant must match the one in cmd/link/internal/ld/sym.go.
454-
*/
455-
SUBL $0x18, BX
456-
457-
/*
458-
* Must set up as USER_CTHREAD segment because
459-
* Darwin forces that value into %gs for signal handlers,
460-
* and if we don't set one up, we'll get a recursive
461-
* fault trying to get into the signal handler.
462-
* Since we have to set one up anyway, it might as
463-
* well be the value we want. So don't bother with
464-
* i386_set_ldt.
465-
*/
466-
MOVL BX, 4(SP)
467-
MOVL $3, AX // thread_fast_set_cthread_self - machdep call #3
468-
INT $0x82 // sic: 0x82, not 0x80, for machdep call
469-
470-
XORL AX, AX
471-
MOVW GS, AX
418+
// Nothing to do on Darwin, pthread already set thread-local storage up.
472419
RET
473420

474421
TEXT runtime·sysctl(SB),NOSPLIT,$0
@@ -531,11 +478,11 @@ TEXT runtime·mstart_stub(SB),NOSPLIT,$0
531478
// Someday the convention will be D is always cleared.
532479
CLD
533480

534-
CALL runtime·stackcheck(SB) // just in case
535481
CALL runtime·mstart(SB)
536482

537-
// mstart shouldn't ever return, and if it does, we shouldn't ever join to this thread
538-
// to get its return status. But tell pthread everything is ok, just in case.
483+
// Go is all done with this OS thread.
484+
// Tell pthread everything is ok (we never join with this thread, so
485+
// the value here doesn't really matter).
539486
XORL AX, AX
540487
RET
541488

@@ -565,26 +512,24 @@ TEXT runtime·pthread_attr_init_trampoline(SB),NOSPLIT,$0-8
565512
MOVL AX, ret+4(FP)
566513
RET
567514

568-
TEXT runtime·pthread_attr_setstack_trampoline(SB),NOSPLIT,$0-16
515+
TEXT runtime·pthread_attr_setstacksize_trampoline(SB),NOSPLIT,$0-12
569516
MOVL attr+0(FP), AX
570-
MOVL addr+4(FP), CX
571-
MOVL size+8(FP), DX
517+
MOVL size+4(FP), CX
572518

573519
PUSHL BP
574520
MOVL SP, BP
575521

576-
SUBL $12, SP
522+
SUBL $8, SP
577523
ANDL $~15, SP
578524

579525
MOVL AX, 0(SP)
580526
MOVL CX, 4(SP)
581-
MOVL DX, 8(SP)
582-
CALL libc_pthread_attr_setstack(SB)
527+
CALL libc_pthread_attr_setstacksize(SB)
583528

584529
MOVL BP, SP
585530
POPL BP
586531

587-
MOVL AX, ret+12(FP)
532+
MOVL AX, ret+8(FP)
588533
RET
589534

590535
TEXT runtime·pthread_attr_setdetachstate_trampoline(SB),NOSPLIT,$0-12

src/runtime/sys_darwin_amd64.s

Lines changed: 17 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -16,35 +16,22 @@
1616
#include "textflag.h"
1717

1818
// Exit the entire program (like C exit)
19-
TEXT runtime·exit(SB),NOSPLIT,$0
19+
TEXT runtime·exit(SB),NOSPLIT,$0-4
2020
MOVL code+0(FP), DI // arg 1 exit status
21-
MOVL $(0x2000000+1), AX // syscall entry
22-
SYSCALL
21+
PUSHQ BP
22+
MOVQ SP, BP
23+
ANDQ $~15, SP // align stack
24+
CALL libc_exit(SB)
2325
MOVL $0xf1, 0xf1 // crash
26+
MOVQ BP, SP
27+
POPQ BP
2428
RET
2529

26-
// Exit this OS thread (like pthread_exit, which eventually
27-
// calls __bsdthread_terminate).
28-
TEXT exit1<>(SB),NOSPLIT,$0
29-
// Because of exitThread below, this must not use the stack.
30-
// __bsdthread_terminate takes 4 word-size arguments.
31-
// Set them all to 0. (None are an exit status.)
32-
MOVL $0, DI
33-
MOVL $0, SI
34-
MOVL $0, DX
35-
MOVL $0, R10
36-
MOVL $(0x2000000+361), AX // syscall entry
37-
SYSCALL
30+
// Not used on Darwin.
31+
TEXT runtime·exitThread(SB),NOSPLIT,$0-8
3832
MOVL $0xf1, 0xf1 // crash
3933
RET
4034

41-
// func exitThread(wait *uint32)
42-
TEXT runtime·exitThread(SB),NOSPLIT,$0-8
43-
MOVQ wait+0(FP), AX
44-
// We're done using the stack.
45-
MOVL $0, (AX)
46-
JMP exit1<>(SB)
47-
4835
TEXT runtime·open(SB),NOSPLIT,$0
4936
MOVQ name+0(FP), DI // arg 1 pathname
5037
MOVL mode+8(FP), SI // arg 2 flags
@@ -490,16 +477,8 @@ TEXT runtime·mach_semaphore_signal_all(SB),NOSPLIT,$0
490477
MOVL AX, ret+8(FP)
491478
RET
492479

493-
// set tls base to DI
494480
TEXT runtime·settls(SB),NOSPLIT,$32
495-
/*
496-
* Same as in sys_darwin_386.s, but a different constant.
497-
* Constant must match the one in cmd/link/internal/ld/sym.go.
498-
*/
499-
SUBQ $0x30, DI
500-
501-
MOVL $(0x3000000+3), AX // thread_fast_set_cthread_self - machdep call #3
502-
SYSCALL
481+
// Nothing to do on Darwin, pthread already set thread-local storage up.
503482
RET
504483

505484
TEXT runtime·sysctl(SB),NOSPLIT,$0
@@ -571,11 +550,11 @@ TEXT runtime·mstart_stub(SB),NOSPLIT,$0
571550
// Someday the convention will be D is always cleared.
572551
CLD
573552

574-
CALL runtime·stackcheck(SB) // just in case
575553
CALL runtime·mstart(SB)
576554

577-
// mstart shouldn't ever return, and if it does, we shouldn't ever join to this thread
578-
// to get its return status. But tell pthread everything is ok, just in case.
555+
// Go is all done with this OS thread.
556+
// Tell pthread everything is ok (we never join with this thread, so
557+
// the value here doesn't really matter).
579558
XORL AX, AX
580559
RET
581560

@@ -591,17 +570,16 @@ TEXT runtime·pthread_attr_init_trampoline(SB),NOSPLIT,$0-12
591570
MOVL AX, ret+8(FP)
592571
RET
593572

594-
TEXT runtime·pthread_attr_setstack_trampoline(SB),NOSPLIT,$0-28
573+
TEXT runtime·pthread_attr_setstacksize_trampoline(SB),NOSPLIT,$0-20
595574
MOVQ attr+0(FP), DI
596-
MOVQ addr+8(FP), SI
597-
MOVQ size+16(FP), DX
575+
MOVQ size+8(FP), SI
598576
PUSHQ BP
599577
MOVQ SP, BP
600578
ANDQ $~15, SP
601-
CALL libc_pthread_attr_setstack(SB)
579+
CALL libc_pthread_attr_setstacksize(SB)
602580
MOVQ BP, SP
603581
POPQ BP
604-
MOVL AX, ret+24(FP)
582+
MOVL AX, ret+16(FP)
605583
RET
606584

607585
TEXT runtime·pthread_attr_setdetachstate_trampoline(SB),NOSPLIT,$0-20

0 commit comments

Comments
 (0)