1 // Copyright 2011 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 thrsleep(ident
uintptr, clock_id
int32, tsp
*timespec
, lock
uintptr, abort
*uint32) int32
22 func thrwakeup(ident
uintptr, n
int32) 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 woken by semawakeup or timeout; or abort if waitsemacount != 0.
54 // From OpenBSD's __thrsleep(2) manual:
55 // "The abort argument, if not NULL, points to an int that will
56 // be examined [...] immediately before blocking. If that int
57 // is non-zero then __thrsleep() will immediately return EINTR
59 ret
:= thrsleep(uintptr(unsafe
.Pointer(&_g_
.m
.mos
.waitsemacount
)), _CLOCK_MONOTONIC
, tsp
, 0, &_g_
.m
.mos
.waitsemacount
)
60 if ret
== _EWOULDBLOCK
{
67 func semawakeup(mp
*m
) {
68 atomic
.Xadd(&mp
.mos
.waitsemacount
, 1)
69 ret
:= thrwakeup(uintptr(unsafe
.Pointer(&mp
.mos
.waitsemacount
)), 1)
70 if ret
!= 0 && ret
!= _ESRCH
{
71 // semawakeup can be called on signal stack.
73 print("thrwakeup addr=", &mp
.mos
.waitsemacount
, " sem=", mp
.mos
.waitsemacount
, " ret=", ret
, "\n")