Commit ec9aae77 authored by Matthew Dempsky's avatar Matthew Dempsky

runtime: move m's OS-specific semaphore fields into mOS

Allows removing fields that aren't relevant to a particular OS or
changing their types to match the underlying OS system calls they'll
be used for.

Change-Id: I5cea89ee77b4e7b985bff41337e561887c3272ff
Reviewed-on: https://go-review.googlesource.com/16176Reviewed-by: 's avatarIan Lance Taylor <iant@golang.org>
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
parent d42cc102
......@@ -13,18 +13,16 @@ import (
// This implementation depends on OS-specific implementations of
//
// uintptr runtime·semacreate(void)
// Create a semaphore, which will be assigned to m->waitsema.
// The zero value is treated as absence of any semaphore,
// so be sure to return a non-zero value.
// func semacreate(mp *m)
// Create a semaphore for mp, if it does not already have one.
//
// int32 runtime·semasleep(int64 ns)
// If ns < 0, acquire m->waitsema and return 0.
// If ns >= 0, try to acquire m->waitsema for at most ns nanoseconds.
// func semasleep(ns int64) int32
// If ns < 0, acquire m's semaphore and return 0.
// If ns >= 0, try to acquire m's semaphore for at most ns nanoseconds.
// Return 0 if the semaphore was acquired, -1 if interrupted or timed out.
//
// int32 runtime·semawakeup(M *mp)
// Wake up mp, which is or will soon be sleeping on mp->waitsema.
// func semawakeup(mp *m)
// Wake up mp, which is or will soon be sleeping on its semaphore.
//
const (
locked uintptr = 1
......@@ -45,9 +43,7 @@ func lock(l *mutex) {
if atomic.Casuintptr(&l.key, 0, locked) {
return
}
if gp.m.waitsema == 0 {
gp.m.waitsema = semacreate()
}
semacreate(gp.m)
// On uniprocessor's, no point spinning.
// On multiprocessors, spin for ACTIVE_SPIN attempts.
......@@ -157,9 +153,7 @@ func notesleep(n *note) {
if gp != gp.m.g0 {
throw("notesleep not on g0")
}
if gp.m.waitsema == 0 {
gp.m.waitsema = semacreate()
}
semacreate(gp.m)
if !atomic.Casuintptr(&n.key, 0, uintptr(unsafe.Pointer(gp.m))) {
// Must be locked (got wakeup).
if n.key != locked {
......@@ -248,9 +242,7 @@ func notetsleep(n *note, ns int64) bool {
if gp != gp.m.g0 && gp.m.preemptoff != "" {
throw("notetsleep not on g0")
}
if gp.m.waitsema == 0 {
gp.m.waitsema = semacreate()
}
semacreate(gp.m)
return notetsleep_internal(n, ns, nil, 0)
}
......@@ -261,9 +253,7 @@ func notetsleepg(n *note, ns int64) bool {
if gp == gp.m.g0 {
throw("notetsleepg on g0")
}
if gp.m.waitsema == 0 {
gp.m.waitsema = semacreate()
}
semacreate(gp.m)
entersyscallblock(0)
ok := notetsleep_internal(n, ns, nil, 0)
exitsyscall(0)
......
......@@ -17,16 +17,17 @@ func unimplemented(name string) {
//go:nosplit
func semawakeup(mp *m) {
mach_semrelease(uint32(mp.waitsema))
mach_semrelease(mp.waitsema)
}
//go:nosplit
func semacreate() uintptr {
var x uintptr
func semacreate(mp *m) {
if mp.waitsema != 0 {
return
}
systemstack(func() {
x = uintptr(mach_semcreate())
mp.waitsema = mach_semcreate()
})
return x
}
// BSD interface for threading.
......@@ -370,7 +371,7 @@ func semasleep1(ns int64) int32 {
if ns >= 0 {
var nsecs int32
secs := timediv(ns, 1000000000, &nsecs)
r := mach_semaphore_timedwait(uint32(_g_.m.waitsema), uint32(secs), uint32(nsecs))
r := mach_semaphore_timedwait(_g_.m.waitsema, uint32(secs), uint32(nsecs))
if r == _KERN_ABORTED || r == _KERN_OPERATION_TIMED_OUT {
return -1
}
......@@ -381,7 +382,7 @@ func semasleep1(ns int64) int32 {
}
for {
r := mach_semaphore_wait(uint32(_g_.m.waitsema))
r := mach_semaphore_wait(_g_.m.waitsema)
if r == 0 {
break
}
......
......@@ -83,8 +83,10 @@ func newosproc(mp *m, stk unsafe.Pointer) {
}
//go:nosplit
func semacreate() uintptr {
var cond uintptr
func semacreate(mp *m) {
if mp.waitsema != 0 {
return
}
systemstack(func() {
mu := nacl_mutex_create(0)
if mu < 0 {
......@@ -93,14 +95,12 @@ func semacreate() uintptr {
}
c := nacl_cond_create(0)
if c < 0 {
print("nacl_cond_create: error ", -cond, "\n")
print("nacl_cond_create: error ", -c, "\n")
throw("semacreate")
}
cond = uintptr(c)
_g_ := getg()
_g_.m.waitsemalock = uint32(mu)
mp.waitsema = c
mp.waitsemalock = mu
})
return cond
}
//go:nosplit
......@@ -109,13 +109,13 @@ func semasleep(ns int64) int32 {
systemstack(func() {
_g_ := getg()
if nacl_mutex_lock(int32(_g_.m.waitsemalock)) < 0 {
if nacl_mutex_lock(_g_.m.waitsemalock) < 0 {
throw("semasleep")
}
for _g_.m.waitsemacount == 0 {
if ns < 0 {
if nacl_cond_wait(int32(_g_.m.waitsema), int32(_g_.m.waitsemalock)) < 0 {
if nacl_cond_wait(_g_.m.waitsema, _g_.m.waitsemalock) < 0 {
throw("semasleep")
}
} else {
......@@ -123,9 +123,9 @@ func semasleep(ns int64) int32 {
end := ns + nanotime()
ts.tv_sec = end / 1e9
ts.tv_nsec = int32(end % 1e9)
r := nacl_cond_timed_wait_abs(int32(_g_.m.waitsema), int32(_g_.m.waitsemalock), &ts)
r := nacl_cond_timed_wait_abs(_g_.m.waitsema, _g_.m.waitsemalock, &ts)
if r == -_ETIMEDOUT {
nacl_mutex_unlock(int32(_g_.m.waitsemalock))
nacl_mutex_unlock(_g_.m.waitsemalock)
ret = -1
return
}
......@@ -136,7 +136,7 @@ func semasleep(ns int64) int32 {
}
_g_.m.waitsemacount = 0
nacl_mutex_unlock(int32(_g_.m.waitsemalock))
nacl_mutex_unlock(_g_.m.waitsemalock)
ret = 0
})
return ret
......@@ -145,15 +145,15 @@ func semasleep(ns int64) int32 {
//go:nosplit
func semawakeup(mp *m) {
systemstack(func() {
if nacl_mutex_lock(int32(mp.waitsemalock)) < 0 {
if nacl_mutex_lock(mp.waitsemalock) < 0 {
throw("semawakeup")
}
if mp.waitsemacount != 0 {
throw("semawakeup")
}
mp.waitsemacount = 1
nacl_cond_signal(int32(mp.waitsema))
nacl_mutex_unlock(int32(mp.waitsemalock))
nacl_cond_signal(mp.waitsema)
nacl_mutex_unlock(mp.waitsemalock)
})
}
......
......@@ -40,8 +40,7 @@ func getncpu() int32 {
}
//go:nosplit
func semacreate() uintptr {
return 1
func semacreate(mp *m) {
}
//go:nosplit
......
......@@ -47,8 +47,7 @@ func getncpu() int32 {
}
//go:nosplit
func semacreate() uintptr {
return 1
func semacreate(mp *m) {
}
//go:nosplit
......
......@@ -205,8 +205,7 @@ func newosproc(mp *m, stk unsafe.Pointer) {
}
//go:nosplit
func semacreate() uintptr {
return 1
func semacreate(mp *m) {
}
//go:nosplit
......
......@@ -365,8 +365,11 @@ func semawakeup(mp *m) {
}
//go:nosplit
func semacreate() uintptr {
return stdcall4(_CreateEventA, 0, 0, 0, 0)
func semacreate(mp *m) {
if mp.waitsema != 0 {
return
}
mp.waitsema = stdcall4(_CreateEventA, 0, 0, 0, 0)
}
// May run with m.p==nil, so write barriers are not allowed.
......
......@@ -314,7 +314,11 @@ func unblocksig(sig int32) {
}
//go:nosplit
func semacreate() uintptr {
func semacreate(mp *m) {
if mp.waitsema != 0 {
return
}
var sem *semt
_g_ := getg()
......@@ -331,7 +335,7 @@ func semacreate() uintptr {
if sem_init(sem, 0, 0) != 0 {
throw("sem_init")
}
return uintptr(unsafe.Pointer(sem))
mp.waitsema = uintptr(unsafe.Pointer(sem))
}
//go:nosplit
......
......@@ -6,7 +6,9 @@ package runtime
import "unsafe"
type mOS struct{}
type mOS struct {
waitsema uint32 // semaphore for parking on locks
}
func bsdthread_create(stk, arg unsafe.Pointer, fn uintptr) int32
func bsdthread_register() int32
......
......@@ -6,7 +6,11 @@ package runtime
import "unsafe"
type mOS struct{}
type mOS struct {
waitsema int32 // semaphore for parking on locks
waitsemacount int32
waitsemalock int32
}
func nacl_exception_stack(p uintptr, size int32) int32
func nacl_exception_handler(fn uintptr, arg unsafe.Pointer) int32
......
......@@ -6,7 +6,9 @@ package runtime
import "unsafe"
type mOS struct{}
type mOS struct {
waitsemacount uint32
}
//go:noescape
func setitimer(mode int32, new, old *itimerval)
......
......@@ -4,7 +4,9 @@
package runtime
type mOS struct{}
type mOS struct {
waitsemacount uint32
}
//go:noescape
func setitimer(mode int32, new, old *itimerval)
......
......@@ -7,8 +7,9 @@ package runtime
import "unsafe"
type mOS struct {
notesig *int8
errstr *byte
waitsemacount uint32
notesig *int8
errstr *byte
}
func closefd(fd int32) int32
......
......@@ -16,7 +16,8 @@ type mscratch struct {
}
type mOS struct {
perrno *int32 // pointer to tls errno
waitsema uintptr // semaphore for parking on locks
perrno *int32 // pointer to tls errno
// these are here because they are too large to be on the stack
// of low-level NOSPLIT functions.
//LibCall libcall;
......
......@@ -6,7 +6,9 @@ package runtime
import "unsafe"
type mOS struct{}
type mOS struct {
waitsema uintptr // semaphore for parking on locks
}
type stdFunction *byte
......
......@@ -308,9 +308,6 @@ type m struct {
fflag uint32 // floating point compare flags
locked uint32 // tracking for lockosthread
nextwaitm uintptr // next m waiting for lock
waitsema uintptr // semaphore for parking on locks
waitsemacount uint32
waitsemalock uint32
gcstats gcstats
needextram bool
traceback uint8
......
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