1 // Copyright 2014 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
8 "runtime/internal/atomic"
18 func lwp_park(abstime
*timespec
, unpark
int32, hint
, unparkhint unsafe
.Pointer
) int32
22 func lwp_unpark(lwp
int32, hint unsafe
.Pointer
) int32
25 func semacreate(mp
*m
) {
29 func semasleep(ns
int64) int32 {
32 // Compute sleep deadline.
38 ts
.set_sec(int64(timediv(ns
, 1000000000, &nsec
)))
44 v
:= atomic
.Load(&_g_
.m
.mos
.waitsemacount
)
46 if atomic
.Cas(&_g_
.m
.mos
.waitsemacount
, v
, v
-1) {
47 return 0 // semaphore acquired
52 // Sleep until unparked by semawakeup or timeout.
53 ret
:= lwp_park(tsp
, 0, unsafe
.Pointer(&_g_
.m
.mos
.waitsemacount
), nil)
54 if ret
== _ETIMEDOUT
{
61 func semawakeup(mp
*m
) {
62 atomic
.Xadd(&mp
.mos
.waitsemacount
, 1)
63 // From NetBSD's _lwp_unpark(2) manual:
64 // "If the target LWP is not currently waiting, it will return
65 // immediately upon the next call to _lwp_park()."
66 ret
:= lwp_unpark(int32(mp
.procid
), unsafe
.Pointer(&mp
.mos
.waitsemacount
))
67 if ret
!= 0 && ret
!= _ESRCH
{
68 // semawakeup can be called on signal stack.
70 print("thrwakeup addr=", &mp
.mos
.waitsemacount
, " sem=", mp
.mos
.waitsemacount
, " ret=", ret
, "\n")