1 // Copyright 2017 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.
10 waitsema
uintptr // semaphore for parking on locks
14 func libc_malloc(uintptr) unsafe
.Pointer
18 func sem_init(sem
*semt
, pshared
int32, value
uint32) int32
22 func sem_wait(sem
*semt
) int32
26 func sem_post(sem
*semt
) int32
29 //extern sem_timedwait
30 func sem_timedwait(sem
*semt
, timeout
*timespec
) int32
33 //extern clock_gettime
34 func clock_gettime(clock_id
int64, timeout
*timespec
) int32
37 func semacreate(mp
*m
) {
38 if mp
.mos
.waitsema
!= 0 {
44 // Call libc's malloc rather than malloc. This will
45 // allocate space on the C heap. We can't call malloc
46 // here because it could cause a deadlock.
47 sem
= (*semt
)(libc_malloc(unsafe
.Sizeof(*sem
)))
48 if sem_init(sem
, 0, 0) != 0 {
51 mp
.mos
.waitsema
= uintptr(unsafe
.Pointer(sem
))
55 func semasleep(ns
int64) int32 {
58 const CLOCK_REALTIME
int64 = 9
61 if clock_gettime(CLOCK_REALTIME
, &ts
) != 0 {
62 throw("clock_gettime")
64 ts
.tv_sec
+= timespec_sec_t(ns
/ 1000000000)
65 ts
.tv_nsec
+= timespec_nsec_t(ns
% 1000000000)
66 if ts
.tv_nsec
>= 1000000000 {
67 ts
.tv_sec
+= timespec_sec_t(1)
68 ts
.tv_nsec
-= timespec_nsec_t(1000000000)
71 if sem_timedwait((*semt
)(unsafe
.Pointer(_m_
.mos
.waitsema
)), &ts
) != 0 {
73 if err
== _ETIMEDOUT || err
== _EAGAIN || err
== _EINTR
{
76 throw("sem_timedwait")
81 r1
:= sem_wait((*semt
)(unsafe
.Pointer(_m_
.mos
.waitsema
)))
85 if errno() == _EINTR
{
94 func semawakeup(mp
*m
) {
95 if sem_post((*semt
)(unsafe
.Pointer(mp
.mos
.waitsema
))) != 0 {