Commit 72c29fc8 authored by Keith Randall's avatar Keith Randall

runtime: move darwin kevent calls to libc

kqueue, kevent, closeonexec, setitimer, with sysctl and fcntl helpers.

TODO:arm,arm64

Change-Id: I9386f377186d6ac7cb99064c524a67e0c8282eba
Reviewed-on: https://go-review.googlesource.com/118561Reviewed-by: default avatarIan Lance Taylor <iant@golang.org>
Run-TryBot: Ian Lance Taylor <iant@golang.org>
parent 537fb06c
...@@ -25,6 +25,7 @@ package runtime ...@@ -25,6 +25,7 @@ package runtime
#include <sys/event.h> #include <sys/event.h>
#include <sys/mman.h> #include <sys/mman.h>
#include <pthread.h> #include <pthread.h>
#include <fcntl.h>
*/ */
import "C" import "C"
...@@ -146,6 +147,9 @@ const ( ...@@ -146,6 +147,9 @@ const (
EVFILT_WRITE = C.EVFILT_WRITE EVFILT_WRITE = C.EVFILT_WRITE
PTHREAD_CREATE_DETACHED = C.PTHREAD_CREATE_DETACHED PTHREAD_CREATE_DETACHED = C.PTHREAD_CREATE_DETACHED
F_SETFD = C.F_SETFD
FD_CLOEXEC = C.FD_CLOEXEC
) )
type MachBody C.mach_msg_body_t type MachBody C.mach_msg_body_t
......
...@@ -123,6 +123,9 @@ const ( ...@@ -123,6 +123,9 @@ const (
_EVFILT_WRITE = -0x2 _EVFILT_WRITE = -0x2
_PTHREAD_CREATE_DETACHED = 0x2 _PTHREAD_CREATE_DETACHED = 0x2
_F_SETFD = 0x2
_FD_CLOEXEC = 0x1
) )
type machbody struct { type machbody struct {
......
...@@ -123,6 +123,9 @@ const ( ...@@ -123,6 +123,9 @@ const (
_EVFILT_WRITE = -0x2 _EVFILT_WRITE = -0x2
_PTHREAD_CREATE_DETACHED = 0x2 _PTHREAD_CREATE_DETACHED = 0x2
_F_SETFD = 0x2
_FD_CLOEXEC = 0x1
) )
type machbody struct { type machbody struct {
......
...@@ -10,12 +10,6 @@ package runtime ...@@ -10,12 +10,6 @@ package runtime
import "unsafe" import "unsafe"
func kqueue() int32
//go:noescape
func kevent(kq int32, ch *keventt, nch int32, ev *keventt, nev int32, ts *timespec) int32
func closeonexec(fd int32)
var ( var (
kq int32 = -1 kq int32 = -1
) )
......
...@@ -18,9 +18,6 @@ func mach_reply_port() uint32 ...@@ -18,9 +18,6 @@ func mach_reply_port() uint32
func mach_task_self() uint32 func mach_task_self() uint32
func mach_thread_self() uint32 func mach_thread_self() uint32
//go:noescape
func sysctl(mib *uint32, miblen uint32, out *byte, size *uintptr, dst *byte, ndst uintptr) int32
func unimplemented(name string) { func unimplemented(name string) {
println(name, "not implemented") println(name, "not implemented")
*(*int)(unsafe.Pointer(uintptr(1231))) = 1231 *(*int)(unsafe.Pointer(uintptr(1231))) = 1231
...@@ -498,9 +495,6 @@ const ( ...@@ -498,9 +495,6 @@ const (
_SS_DISABLE = 4 _SS_DISABLE = 4
) )
//go:noescape
func setitimer(mode int32, new, old *itimerval)
//extern SigTabTT runtime·sigtab[]; //extern SigTabTT runtime·sigtab[];
type sigset uint32 type sigset uint32
......
...@@ -49,6 +49,12 @@ func sys_umtx_wakeup(addr *uint32, val int32) int32 ...@@ -49,6 +49,12 @@ func sys_umtx_wakeup(addr *uint32, val int32) int32
func osyield() func osyield()
func kqueue() int32
//go:noescape
func kevent(kq int32, ch *keventt, nch int32, ev *keventt, nev int32, ts *timespec) int32
func closeonexec(fd int32)
const stackSystem = 0 const stackSystem = 0
// From DragonFly's <sys/sysctl.h> // From DragonFly's <sys/sysctl.h>
......
...@@ -34,6 +34,12 @@ func sys_umtx_op(addr *uint32, mode int32, val uint32, uaddr1 uintptr, ut *umtx_ ...@@ -34,6 +34,12 @@ func sys_umtx_op(addr *uint32, mode int32, val uint32, uaddr1 uintptr, ut *umtx_
func osyield() func osyield()
func kqueue() int32
//go:noescape
func kevent(kq int32, ch *keventt, nch int32, ev *keventt, nev int32, ts *timespec) int32
func closeonexec(fd int32)
// From FreeBSD's <sys/sysctl.h> // From FreeBSD's <sys/sysctl.h>
const ( const (
_CTL_HW = 6 _CTL_HW = 6
......
...@@ -68,6 +68,12 @@ func lwp_self() int32 ...@@ -68,6 +68,12 @@ func lwp_self() int32
func osyield() func osyield()
func kqueue() int32
//go:noescape
func kevent(kq int32, ch *keventt, nch int32, ev *keventt, nev int32, ts *timespec) int32
func closeonexec(fd int32)
const ( const (
_ESRCH = 3 _ESRCH = 3
_ETIMEDOUT = 60 _ETIMEDOUT = 60
......
...@@ -55,6 +55,12 @@ func thrwakeup(ident uintptr, n int32) int32 ...@@ -55,6 +55,12 @@ func thrwakeup(ident uintptr, n int32) int32
func osyield() func osyield()
func kqueue() int32
//go:noescape
func kevent(kq int32, ch *keventt, nch int32, ev *keventt, nev int32, ts *timespec) int32
func closeonexec(fd int32)
const ( const (
_ESRCH = 3 _ESRCH = 3
_EAGAIN = 35 _EAGAIN = 35
......
...@@ -214,10 +214,51 @@ func raiseproc(sig uint32) { ...@@ -214,10 +214,51 @@ func raiseproc(sig uint32) {
} }
func raiseproc_trampoline() func raiseproc_trampoline()
//go:nosplit
//go:cgo_unsafe_args
func setitimer(mode int32, new, old *itimerval) {
asmcgocall(unsafe.Pointer(funcPC(setitimer_trampoline)), unsafe.Pointer(&mode))
}
func setitimer_trampoline()
//go:nosplit
//go:cgo_unsafe_args
func sysctl(mib *uint32, miblen uint32, out *byte, size *uintptr, dst *byte, ndst uintptr) int32 {
return asmcgocall(unsafe.Pointer(funcPC(sysctl_trampoline)), unsafe.Pointer(&mib))
}
func sysctl_trampoline()
//go:nosplit
//go:cgo_unsafe_args
func fcntl(fd, cmd, arg int32) int32 {
return asmcgocall(unsafe.Pointer(funcPC(fcntl_trampoline)), unsafe.Pointer(&fd))
}
func fcntl_trampoline()
//go:nosplit
//go:cgo_unsafe_args
func kqueue() int32 {
v := asmcgocall(unsafe.Pointer(funcPC(kqueue_trampoline)), nil)
return v
}
func kqueue_trampoline()
//go:nosplit
//go:cgo_unsafe_args
func kevent(kq int32, ch *keventt, nch int32, ev *keventt, nev int32, ts *timespec) int32 {
return asmcgocall(unsafe.Pointer(funcPC(kevent_trampoline)), unsafe.Pointer(&kq))
}
func kevent_trampoline()
// Not used on Darwin, but must be defined. // Not used on Darwin, but must be defined.
func exitThread(wait *uint32) { func exitThread(wait *uint32) {
} }
//go:nosplit
func closeonexec(fd int32) {
fcntl(fd, _F_SETFD, _FD_CLOEXEC)
}
// Tell the linker that the libc_* functions are to be found // Tell the linker that the libc_* functions are to be found
// in a system library, with the libc_ prefix missing. // in a system library, with the libc_ prefix missing.
...@@ -247,6 +288,11 @@ func exitThread(wait *uint32) { ...@@ -247,6 +288,11 @@ func exitThread(wait *uint32) {
//go:cgo_import_dynamic libc_sigaltstack sigaltstack "/usr/lib/libSystem.B.dylib" //go:cgo_import_dynamic libc_sigaltstack sigaltstack "/usr/lib/libSystem.B.dylib"
//go:cgo_import_dynamic libc_getpid getpid "/usr/lib/libSystem.B.dylib" //go:cgo_import_dynamic libc_getpid getpid "/usr/lib/libSystem.B.dylib"
//go:cgo_import_dynamic libc_kill kill "/usr/lib/libSystem.B.dylib" //go:cgo_import_dynamic libc_kill kill "/usr/lib/libSystem.B.dylib"
//go:cgo_import_dynamic libc_setitimer setitimer "/usr/lib/libSystem.B.dylib"
//go:cgo_import_dynamic libc_sysctl sysctl "/usr/lib/libSystem.B.dylib"
//go:cgo_import_dynamic libc_fcntl fcntl "/usr/lib/libSystem.B.dylib"
//go:cgo_import_dynamic libc_kqueue kqueue "/usr/lib/libSystem.B.dylib"
//go:cgo_import_dynamic libc_kevent kevent "/usr/lib/libSystem.B.dylib"
// Magic incantation to get libSystem actually dynamically linked. // Magic incantation to get libSystem actually dynamically linked.
// TODO: Why does the code require this? See cmd/compile/internal/ld/go.go:210 // TODO: Why does the code require this? See cmd/compile/internal/ld/go.go:210
......
...@@ -150,9 +150,20 @@ TEXT runtime·munmap_trampoline(SB),NOSPLIT,$0 ...@@ -150,9 +150,20 @@ TEXT runtime·munmap_trampoline(SB),NOSPLIT,$0
POPL BP POPL BP
RET RET
TEXT runtime·setitimer(SB),NOSPLIT,$0 TEXT runtime·setitimer_trampoline(SB),NOSPLIT,$0
MOVL $83, AX PUSHL BP
INT $0x80 MOVL SP, BP
SUBL $24, SP
MOVL 32(SP), CX
MOVL 0(CX), AX // arg 1 mode
MOVL AX, 0(SP)
MOVL 4(CX), AX // arg 2 new
MOVL AX, 4(SP)
MOVL 8(CX), AX // arg 3 old
MOVL AX, 8(SP)
CALL libc_setitimer(SB)
MOVL BP, SP
POPL BP
RET RET
TEXT runtime·walltime_trampoline(SB),NOSPLIT,$0 TEXT runtime·walltime_trampoline(SB),NOSPLIT,$0
...@@ -398,46 +409,79 @@ TEXT runtime·setldt(SB),NOSPLIT,$32 ...@@ -398,46 +409,79 @@ TEXT runtime·setldt(SB),NOSPLIT,$32
// Nothing to do on Darwin, pthread already set thread-local storage up. // Nothing to do on Darwin, pthread already set thread-local storage up.
RET RET
TEXT runtime·sysctl(SB),NOSPLIT,$0 TEXT runtime·sysctl_trampoline(SB),NOSPLIT,$0
MOVL $202, AX PUSHL BP
INT $0x80 MOVL SP, BP
JAE 4(PC) SUBL $24, SP
NEGL AX MOVL 32(SP), CX
MOVL AX, ret+24(FP) MOVL 0(CX), AX // arg 1 mib
MOVL AX, 0(SP)
MOVL 4(CX), AX // arg 2 miblen
MOVL AX, 4(SP)
MOVL 8(CX), AX // arg 3 out
MOVL AX, 8(SP)
MOVL 12(CX), AX // arg 4 size
MOVL AX, 12(SP)
MOVL 16(CX), AX // arg 5 dst
MOVL AX, 16(SP)
MOVL 20(CX), AX // arg 6 ndst
MOVL AX, 20(SP)
CALL libc_sysctl(SB)
MOVL BP, SP
POPL BP
RET RET
MOVL $0, AX
MOVL AX, ret+24(FP) TEXT runtime·kqueue_trampoline(SB),NOSPLIT,$0
PUSHL BP
MOVL SP, BP
SUBL $8, SP
CALL libc_kqueue(SB)
MOVL BP, SP
POPL BP
RET RET
// func kqueue() int32 TEXT runtime·kevent_trampoline(SB),NOSPLIT,$0
TEXT runtime·kqueue(SB),NOSPLIT,$0 PUSHL BP
MOVL $362, AX MOVL SP, BP
INT $0x80 SUBL $24, SP
JAE 2(PC) MOVL 32(SP), CX
NEGL AX MOVL 0(CX), AX // arg 1 kq
MOVL AX, ret+0(FP) MOVL AX, 0(SP)
MOVL 4(CX), AX // arg 2 ch
MOVL AX, 4(SP)
MOVL 8(CX), AX // arg 3 nch
MOVL AX, 8(SP)
MOVL 12(CX), AX // arg 4 ev
MOVL AX, 12(SP)
MOVL 16(CX), AX // arg 5 nev
MOVL AX, 16(SP)
MOVL 20(CX), AX // arg 6 ts
MOVL AX, 20(SP)
CALL libc_kevent(SB)
CMPL AX, $-1
JNE ok
CALL libc_error(SB)
MOVL (AX), AX // errno
NEGL AX // caller wants it as a negative error code
ok:
MOVL BP, SP
POPL BP
RET RET
// func kevent(kq int32, ch *keventt, nch int32, ev *keventt, nev int32, ts *timespec) int32 TEXT runtime·fcntl_trampoline(SB),NOSPLIT,$0
TEXT runtime·kevent(SB),NOSPLIT,$0 PUSHL BP
MOVL $363, AX MOVL SP, BP
INT $0x80 SUBL $24, SP
JAE 2(PC) MOVL 32(SP), CX
NEGL AX MOVL 0(CX), AX // arg 1 fd
MOVL AX, ret+24(FP) MOVL AX, 0(SP)
RET MOVL 4(CX), AX // arg 2 cmd
MOVL AX, 4(SP)
// func closeonexec(fd int32) MOVL 8(CX), AX // arg 3 arg
TEXT runtime·closeonexec(SB),NOSPLIT,$32 MOVL AX, 8(SP)
MOVL $92, AX // fcntl CALL libc_fcntl(SB)
// 0(SP) is where the caller PC would be; kernel skips it MOVL BP, SP
MOVL fd+0(FP), BX POPL BP
MOVL BX, 4(SP) // fd
MOVL $2, 8(SP) // F_SETFD
MOVL $1, 12(SP) // FD_CLOEXEC
INT $0x80
JAE 2(PC)
NEGL AX
RET RET
// mstart_stub is the first function executed on a new thread started by pthread_create. // mstart_stub is the first function executed on a new thread started by pthread_create.
......
...@@ -63,12 +63,14 @@ TEXT runtime·write_trampoline(SB),NOSPLIT,$0 ...@@ -63,12 +63,14 @@ TEXT runtime·write_trampoline(SB),NOSPLIT,$0
POPQ BP POPQ BP
RET RET
TEXT runtime·setitimer(SB), NOSPLIT, $0 TEXT runtime·setitimer_trampoline(SB),NOSPLIT,$0
MOVL mode+0(FP), DI PUSHQ BP
MOVQ new+8(FP), SI MOVQ SP, BP
MOVQ old+16(FP), DX MOVQ 8(DI), SI // arg 2 new
MOVL $(0x2000000+83), AX // syscall entry MOVQ 16(DI), DX // arg 3 old
SYSCALL MOVL 0(DI), DI // arg 1 which
CALL libc_setitimer(SB)
POPQ BP
RET RET
TEXT runtime·madvise_trampoline(SB), NOSPLIT, $0 TEXT runtime·madvise_trampoline(SB), NOSPLIT, $0
...@@ -338,57 +340,53 @@ TEXT runtime·settls(SB),NOSPLIT,$32 ...@@ -338,57 +340,53 @@ TEXT runtime·settls(SB),NOSPLIT,$32
// Nothing to do on Darwin, pthread already set thread-local storage up. // Nothing to do on Darwin, pthread already set thread-local storage up.
RET RET
TEXT runtime·sysctl(SB),NOSPLIT,$0 TEXT runtime·sysctl_trampoline(SB),NOSPLIT,$0
MOVQ mib+0(FP), DI PUSHQ BP
MOVL miblen+8(FP), SI MOVQ SP, BP
MOVQ out+16(FP), DX MOVL 8(DI), SI // arg 2 miblen
MOVQ size+24(FP), R10 MOVQ 16(DI), DX // arg 3 out
MOVQ dst+32(FP), R8 MOVQ 24(DI), CX // arg 4 size
MOVQ ndst+40(FP), R9 MOVQ 32(DI), R8 // arg 5 dst
MOVL $(0x2000000+202), AX // syscall entry MOVQ 40(DI), R9 // arg 6 ndst
SYSCALL MOVQ 0(DI), DI // arg 1 mib
JCC 4(PC) CALL libc_sysctl(SB)
NEGQ AX POPQ BP
MOVL AX, ret+48(FP)
RET
MOVL $0, AX
MOVL AX, ret+48(FP)
RET RET
// func kqueue() int32 TEXT runtime·kqueue_trampoline(SB),NOSPLIT,$0
TEXT runtime·kqueue(SB),NOSPLIT,$0 PUSHQ BP
MOVQ $0, DI MOVQ SP, BP
MOVQ $0, SI CALL libc_kqueue(SB)
MOVQ $0, DX POPQ BP
MOVL $(0x2000000+362), AX
SYSCALL
JCC 2(PC)
NEGQ AX
MOVL AX, ret+0(FP)
RET RET
// func kevent(kq int32, ch *keventt, nch int32, ev *keventt, nev int32, ts *timespec) int32 TEXT runtime·kevent_trampoline(SB),NOSPLIT,$0
TEXT runtime·kevent(SB),NOSPLIT,$0 PUSHQ BP
MOVL kq+0(FP), DI MOVQ SP, BP
MOVQ ch+8(FP), SI MOVQ 8(DI), SI // arg 2 keventt
MOVL nch+16(FP), DX MOVL 16(DI), DX // arg 3 nch
MOVQ ev+24(FP), R10 MOVQ 24(DI), CX // arg 4 ev
MOVL nev+32(FP), R8 MOVL 32(DI), R8 // arg 5 nev
MOVQ ts+40(FP), R9 MOVQ 40(DI), R9 // arg 6 ts
MOVL $(0x2000000+363), AX MOVL 0(DI), DI // arg 1 kq
SYSCALL CALL libc_kevent(SB)
JCC 2(PC) CMPQ AX, $-1
NEGQ AX JNE ok
MOVL AX, ret+48(FP) CALL libc_error(SB)
MOVQ (AX), AX // errno
NEGQ AX // caller wants it as a negative error code
ok:
POPQ BP
RET RET
// func closeonexec(fd int32) TEXT runtime·fcntl_trampoline(SB),NOSPLIT,$0
TEXT runtime·closeonexec(SB),NOSPLIT,$0 PUSHQ BP
MOVL fd+0(FP), DI // fd MOVQ SP, BP
MOVQ $2, SI // F_SETFD MOVL 4(DI), SI // arg 2 cmd
MOVQ $1, DX // FD_CLOEXEC MOVL 8(DI), DX // arg 3 arg
MOVL $(0x2000000+92), AX // fcntl MOVL 0(DI), DI // arg 1 fd
SYSCALL CALL libc_fcntl(SB)
POPQ BP
RET RET
// mstart_stub is the first function executed on a new thread started by pthread_create. // mstart_stub is the first function executed on a new thread started by pthread_create.
......
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