1 // Copyright 2018 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.
14 func sysconf(int32) _C_long
17 waitsema
uintptr // semaphore for parking on locks
20 func getProcID() uint64 {
21 return uint64(gettid())
25 func libc_malloc(uintptr) unsafe
.Pointer
29 func sem_init(sem
*semt
, pshared
int32, value
uint32) int32
33 func sem_wait(sem
*semt
) int32
37 func sem_post(sem
*semt
) int32
40 //extern sem_timedwait
41 func sem_timedwait(sem
*semt
, timeout
*timespec
) int32
44 //extern clock_gettime
45 func clock_gettime(clock_id
int64, timeout
*timespec
) int32
48 func semacreate(mp
*m
) {
55 // Call libc's malloc rather than malloc. This will
56 // allocate space on the C heap. We can't call malloc
57 // here because it could cause a deadlock.
58 sem
= (*semt
)(libc_malloc(unsafe
.Sizeof(*sem
)))
59 if sem_init(sem
, 0, 0) != 0 {
62 mp
.waitsema
= uintptr(unsafe
.Pointer(sem
))
66 func semasleep(ns
int64) int32 {
71 if clock_gettime(_CLOCK_REALTIME
, &ts
) != 0 {
72 throw("clock_gettime")
75 sec
:= int64(ts
.tv_sec
) + ns
/1e9
76 nsec
:= int64(ts
.tv_nsec
) + ns%1e9
81 if sec
!= int64(timespec_sec_t(sec
)) {
82 // Handle overflows (timespec_sec_t is 32-bit in 32-bit applications)
85 ts
.tv_sec
= timespec_sec_t(sec
)
86 ts
.tv_nsec
= timespec_nsec_t(nsec
)
88 if sem_timedwait((*semt
)(unsafe
.Pointer(mp
.waitsema
)), &ts
) != 0 {
90 if err
== _ETIMEDOUT || err
== _EAGAIN || err
== _EINTR
{
93 println("sem_timedwait err ", err
, " ts.tv_sec ", ts
.tv_sec
, " ts.tv_nsec ", ts
.tv_nsec
, " ns ", ns
, " id ", mp
.id
)
94 throw("sem_timedwait")
99 r1
:= sem_wait((*semt
)(unsafe
.Pointer(mp
.waitsema
)))
103 if errno() == _EINTR
{
112 func semawakeup(mp
*m
) {
113 if sem_post((*semt
)(unsafe
.Pointer(mp
.waitsema
))) != 0 {
119 ncpu
= int32(sysconf(__SC_NPROCESSORS_ONLN
))
120 physPageSize
= uintptr(sysconf(__SC_PAGE_SIZE
))
123 func setProcessCPUProfiler(hz
int32) {
124 setProcessCPUProfilerTimer(hz
)
127 func setThreadCPUProfiler(hz
int32) {
128 setThreadCPUProfilerHz(hz
)
132 func validSIGPROF(mp
*m
, c
*sigctxt
) bool {
138 _CLOCK_MONOTONIC
= 10