runtime: correct semaphore implementation on netbsd
authorNikhil Benesch <nikhil.benesch@gmail.com>
Tue, 13 Oct 2020 07:17:55 +0000 (07:17 +0000)
committerIan Lance Taylor <iant@golang.org>
Wed, 14 Oct 2020 20:56:01 +0000 (13:56 -0700)
NetBSD's semaphores use the underlying lighweight process mechanism
(LWP) on NetBSD, rather than pthreads. This means the m.prodcid needs
to be set to the LWP ID rather than the pthread ID in order for unpark
notifications to get sent to the right place.

Introduce a new getProcID() method that selects the correct ID for the
platform.

Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/261742

gcc/go/gofrontend/MERGE
libgo/go/runtime/os_aix.go
libgo/go/runtime/os_gccgo.go
libgo/go/runtime/os_hurd.go
libgo/go/runtime/os_linux.go
libgo/go/runtime/os_netbsd.go
libgo/go/runtime/os_solaris.go

index 2c7a9bde825e401d219c106d0beac9ee82077055..c37df37db5166e150d60e8a11b41d180d61b93df 100644 (file)
@@ -1,4 +1,4 @@
-6cb7b9e924d84125f21f4a2a96aa0d59466056fe
+c5505c4e626fa4217911443b4db8b065855a0206
 
 The first line of this file holds the git revision number of the last
 merge done from the gofrontend repository.
index 951aeb6cffd7d59517dc2ac677c99c64d0ac8527..f49b83ccbe4e89cb34c38923a88dff4f5c94529d 100644 (file)
@@ -21,6 +21,10 @@ type mOS struct {
        waitsema uintptr // semaphore for parking on locks
 }
 
+func getProcID() uint64 {
+       return uint64(gettid())
+}
+
 //extern malloc
 func libc_malloc(uintptr) unsafe.Pointer
 
index ab190229860b243133aba099bfbbfd138950d028..a8859c085a33762771759932edc111ec91edc578 100644 (file)
@@ -27,8 +27,7 @@ func mpreinit(mp *m) {
 func minit() {
        minitSignals()
 
-       // FIXME: only works on linux for now.
-       getg().m.procid = uint64(gettid())
+       getg().m.procid = getProcID()
 }
 
 // Called from dropm to undo the effect of an minit.
index b3c6f8062ca1c53155b918196084c79435bc876a..1613b410e2ccceafd37bae86cf153a59f735eb0d 100644 (file)
@@ -18,6 +18,10 @@ type mOS struct {
        waitsema uintptr // semaphore for parking on locks
 }
 
+func getProcID() uint64 {
+       return uint64(gettid())
+}
+
 //extern malloc
 func libc_malloc(uintptr) unsafe.Pointer
 
index 5d5506467156e65fc93778088ab3f7d7cf3d4c3e..627b6d6d43caf27ef8edf52e29f2f8b2c40da4bd 100644 (file)
@@ -13,6 +13,10 @@ type mOS struct {
        unused byte
 }
 
+func getProcID() uint64 {
+       return uint64(gettid())
+}
+
 func futex(addr unsafe.Pointer, op int32, val uint32, ts, addr2 unsafe.Pointer, val3 uint32) int32 {
        return int32(syscall(_SYS_futex, uintptr(addr), uintptr(op), uintptr(val), uintptr(ts), uintptr(addr2), uintptr(val3)))
 }
index 69d2c7104498afae36acb5d7cacd5f47b4d10896..89a8d076f12755de643a5ed0cff9cc9b3716c103 100644 (file)
@@ -14,12 +14,19 @@ type mOS struct {
        waitsemacount uint32
 }
 
+func getProcID() uint64 {
+       return uint64(lwp_self())
+}
+
+//extern _lwp_self
+func lwp_self() int32
+
 //go:noescape
-//extern lwp_park
+//extern _lwp_park
 func lwp_park(ts int32, rel int32, abstime *timespec, unpark int32, hint, unparkhint unsafe.Pointer) int32
 
 //go:noescape
-//extern lwp_unpark
+//extern _lwp_unpark
 func lwp_unpark(lwp int32, hint unsafe.Pointer) int32
 
 //go:noescape
@@ -88,7 +95,7 @@ func semasleep(ns int64) int32 {
                        tsp = &ts
                }
                ret := lwp_park(_CLOCK_MONOTONIC, _TIMER_RELTIME, tsp, 0, unsafe.Pointer(&_g_.m.waitsemacount), nil)
-               if ret == _ETIMEDOUT {
+               if ret != 0 && errno() == _ETIMEDOUT {
                        return -1
                }
        }
@@ -101,10 +108,10 @@ func semawakeup(mp *m) {
        // "If the target LWP is not currently waiting, it will return
        // immediately upon the next call to _lwp_park()."
        ret := lwp_unpark(int32(mp.procid), unsafe.Pointer(&mp.waitsemacount))
-       if ret != 0 && ret != _ESRCH {
+       if ret != 0 && errno() != _ESRCH {
                // semawakeup can be called on signal stack.
                systemstack(func() {
-                       print("thrwakeup addr=", &mp.waitsemacount, " sem=", mp.waitsemacount, " ret=", ret, "\n")
+                       print("thrwakeup addr=", &mp.waitsemacount, " sem=", mp.waitsemacount, " errno=", errno(), "\n")
                })
        }
 }
index 63b5cd70c8cf0a27074ddec05867da6472e58982..c568629e566b32a727bcd328e3d99f61daabde59 100644 (file)
@@ -10,6 +10,10 @@ type mOS struct {
        waitsema uintptr // semaphore for parking on locks
 }
 
+func getProcID() uint64 {
+       return uint64(gettid())
+}
+
 //extern malloc
 func libc_malloc(uintptr) unsafe.Pointer