summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/runtime/lock_sema.go32
-rw-r--r--src/runtime/os1_darwin.go15
-rw-r--r--src/runtime/os1_nacl.go30
-rw-r--r--src/runtime/os1_netbsd.go3
-rw-r--r--src/runtime/os1_openbsd.go3
-rw-r--r--src/runtime/os1_plan9.go3
-rw-r--r--src/runtime/os1_windows.go7
-rw-r--r--src/runtime/os3_solaris.go8
-rw-r--r--src/runtime/os_darwin.go4
-rw-r--r--src/runtime/os_nacl.go6
-rw-r--r--src/runtime/os_netbsd.go4
-rw-r--r--src/runtime/os_openbsd.go4
-rw-r--r--src/runtime/os_plan9.go5
-rw-r--r--src/runtime/os_solaris.go3
-rw-r--r--src/runtime/os_windows.go4
-rw-r--r--src/runtime/runtime2.go3
16 files changed, 70 insertions, 64 deletions
diff --git a/src/runtime/lock_sema.go b/src/runtime/lock_sema.go
index ebf786f0af..d39b010cf0 100644
--- a/src/runtime/lock_sema.go
+++ b/src/runtime/lock_sema.go
@@ -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)
diff --git a/src/runtime/os1_darwin.go b/src/runtime/os1_darwin.go
index be710599df..ba38a78ed1 100644
--- a/src/runtime/os1_darwin.go
+++ b/src/runtime/os1_darwin.go
@@ -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
}
diff --git a/src/runtime/os1_nacl.go b/src/runtime/os1_nacl.go
index 143752ada8..ad4329cecd 100644
--- a/src/runtime/os1_nacl.go
+++ b/src/runtime/os1_nacl.go
@@ -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)
})
}
diff --git a/src/runtime/os1_netbsd.go b/src/runtime/os1_netbsd.go
index b127c64ff4..3e77d248f7 100644
--- a/src/runtime/os1_netbsd.go
+++ b/src/runtime/os1_netbsd.go
@@ -40,8 +40,7 @@ func getncpu() int32 {
}
//go:nosplit
-func semacreate() uintptr {
- return 1
+func semacreate(mp *m) {
}
//go:nosplit
diff --git a/src/runtime/os1_openbsd.go b/src/runtime/os1_openbsd.go
index beda59789c..11034a64f6 100644
--- a/src/runtime/os1_openbsd.go
+++ b/src/runtime/os1_openbsd.go
@@ -47,8 +47,7 @@ func getncpu() int32 {
}
//go:nosplit
-func semacreate() uintptr {
- return 1
+func semacreate(mp *m) {
}
//go:nosplit
diff --git a/src/runtime/os1_plan9.go b/src/runtime/os1_plan9.go
index 07ad498fbc..bc7ce65daf 100644
--- a/src/runtime/os1_plan9.go
+++ b/src/runtime/os1_plan9.go
@@ -205,8 +205,7 @@ func newosproc(mp *m, stk unsafe.Pointer) {
}
//go:nosplit
-func semacreate() uintptr {
- return 1
+func semacreate(mp *m) {
}
//go:nosplit
diff --git a/src/runtime/os1_windows.go b/src/runtime/os1_windows.go
index bd514724f1..8134543578 100644
--- a/src/runtime/os1_windows.go
+++ b/src/runtime/os1_windows.go
@@ -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.
diff --git a/src/runtime/os3_solaris.go b/src/runtime/os3_solaris.go
index 792188fea6..3ac121a7b8 100644
--- a/src/runtime/os3_solaris.go
+++ b/src/runtime/os3_solaris.go
@@ -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
diff --git a/src/runtime/os_darwin.go b/src/runtime/os_darwin.go
index 0fedb707e9..7a70639b02 100644
--- a/src/runtime/os_darwin.go
+++ b/src/runtime/os_darwin.go
@@ -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
diff --git a/src/runtime/os_nacl.go b/src/runtime/os_nacl.go
index 58330d2810..69eaf4c14e 100644
--- a/src/runtime/os_nacl.go
+++ b/src/runtime/os_nacl.go
@@ -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
diff --git a/src/runtime/os_netbsd.go b/src/runtime/os_netbsd.go
index 659ec2d65a..988374120d 100644
--- a/src/runtime/os_netbsd.go
+++ b/src/runtime/os_netbsd.go
@@ -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)
diff --git a/src/runtime/os_openbsd.go b/src/runtime/os_openbsd.go
index 74a838fa41..12f4cd1a24 100644
--- a/src/runtime/os_openbsd.go
+++ b/src/runtime/os_openbsd.go
@@ -4,7 +4,9 @@
package runtime
-type mOS struct{}
+type mOS struct {
+ waitsemacount uint32
+}
//go:noescape
func setitimer(mode int32, new, old *itimerval)
diff --git a/src/runtime/os_plan9.go b/src/runtime/os_plan9.go
index 3b3e940cbc..6e6a55e636 100644
--- a/src/runtime/os_plan9.go
+++ b/src/runtime/os_plan9.go
@@ -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
diff --git a/src/runtime/os_solaris.go b/src/runtime/os_solaris.go
index 129653ef19..9dbe38a32a 100644
--- a/src/runtime/os_solaris.go
+++ b/src/runtime/os_solaris.go
@@ -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;
diff --git a/src/runtime/os_windows.go b/src/runtime/os_windows.go
index 22f7daad51..5dab1dec16 100644
--- a/src/runtime/os_windows.go
+++ b/src/runtime/os_windows.go
@@ -6,7 +6,9 @@ package runtime
import "unsafe"
-type mOS struct{}
+type mOS struct {
+ waitsema uintptr // semaphore for parking on locks
+}
type stdFunction *byte
diff --git a/src/runtime/runtime2.go b/src/runtime/runtime2.go
index 9ec0d1545e..1dbd3d2094 100644
--- a/src/runtime/runtime2.go
+++ b/src/runtime/runtime2.go
@@ -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