aboutsummaryrefslogtreecommitdiff
path: root/libgo/go/runtime/os_aix.go
diff options
context:
space:
mode:
Diffstat (limited to 'libgo/go/runtime/os_aix.go')
-rw-r--r--libgo/go/runtime/os_aix.go98
1 files changed, 98 insertions, 0 deletions
diff --git a/libgo/go/runtime/os_aix.go b/libgo/go/runtime/os_aix.go
new file mode 100644
index 0000000..246b9c3
--- /dev/null
+++ b/libgo/go/runtime/os_aix.go
@@ -0,0 +1,98 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package runtime
+
+import "unsafe"
+
+type mOS struct {
+ waitsema uintptr // semaphore for parking on locks
+}
+
+//extern malloc
+func libc_malloc(uintptr) unsafe.Pointer
+
+//go:noescape
+//extern sem_init
+func sem_init(sem *semt, pshared int32, value uint32) int32
+
+//go:noescape
+//extern sem_wait
+func sem_wait(sem *semt) int32
+
+//go:noescape
+//extern sem_post
+func sem_post(sem *semt) int32
+
+//go:noescape
+//extern sem_timedwait
+func sem_timedwait(sem *semt, timeout *timespec) int32
+
+//go:noescape
+//extern clock_gettime
+func clock_gettime(clock_id int64, timeout *timespec) int32
+
+//go:nosplit
+func semacreate(mp *m) {
+ if mp.mos.waitsema != 0 {
+ return
+ }
+
+ var sem *semt
+
+ // Call libc's malloc rather than malloc. This will
+ // allocate space on the C heap. We can't call malloc
+ // here because it could cause a deadlock.
+ sem = (*semt)(libc_malloc(unsafe.Sizeof(*sem)))
+ if sem_init(sem, 0, 0) != 0 {
+ throw("sem_init")
+ }
+ mp.mos.waitsema = uintptr(unsafe.Pointer(sem))
+}
+
+//go:nosplit
+func semasleep(ns int64) int32 {
+ _m_ := getg().m
+ if ns >= 0 {
+ const CLOCK_REALTIME int64 = 9
+ var ts timespec
+
+ if clock_gettime(CLOCK_REALTIME, &ts) != 0 {
+ throw("clock_gettime")
+ }
+ ts.tv_sec += timespec_sec_t(ns / 1000000000)
+ ts.tv_nsec += timespec_nsec_t(ns % 1000000000)
+ if ts.tv_nsec >= 1000000000 {
+ ts.tv_sec += timespec_sec_t(1)
+ ts.tv_nsec -= timespec_nsec_t(1000000000)
+ }
+
+ if sem_timedwait((*semt)(unsafe.Pointer(_m_.mos.waitsema)), &ts) != 0 {
+ err := errno()
+ if err == _ETIMEDOUT || err == _EAGAIN || err == _EINTR {
+ return -1
+ }
+ throw("sem_timedwait")
+ }
+ return 0
+ }
+ for {
+ r1 := sem_wait((*semt)(unsafe.Pointer(_m_.mos.waitsema)))
+ if r1 == 0 {
+ break
+ }
+ if errno() == _EINTR {
+ continue
+ }
+ throw("sem_wait")
+ }
+ return 0
+}
+
+//go:nosplit
+func semawakeup(mp *m) {
+ if sem_post((*semt)(unsafe.Pointer(mp.mos.waitsema))) != 0 {
+ throw("sem_post")
+ }
+}