2017-03-02 Richard Biener <rguenther@suse.de>
[official-gcc.git] / libgo / go / runtime / os_solaris.go
blobcf457680f71db17a737f08ccae20ba44869c6938
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.
5 package runtime
7 import "unsafe"
9 type mOS struct {
10 waitsema uintptr // semaphore for parking on locks
13 //extern malloc
14 func libc_malloc(uintptr) unsafe.Pointer
16 //go:noescape
17 //extern sem_init
18 func sem_init(sem *semt, pshared int32, value uint32) int32
20 //go:noescape
21 //extern sem_wait
22 func sem_wait(sem *semt) int32
24 //go:noescape
25 //extern sem_post
26 func sem_post(sem *semt) int32
28 //go:noescape
29 //extern sem_reltimedwait_np
30 func sem_reltimedwait_np(sem *semt, timeout *timespec) int32
32 //go:nosplit
33 func semacreate(mp *m) {
34 if mp.mos.waitsema != 0 {
35 return
38 var sem *semt
40 // Call libc's malloc rather than malloc. This will
41 // allocate space on the C heap. We can't call malloc
42 // here because it could cause a deadlock.
43 sem = (*semt)(libc_malloc(unsafe.Sizeof(*sem)))
44 if sem_init(sem, 0, 0) != 0 {
45 throw("sem_init")
47 mp.mos.waitsema = uintptr(unsafe.Pointer(sem))
50 //go:nosplit
51 func semasleep(ns int64) int32 {
52 _m_ := getg().m
53 if ns >= 0 {
54 var ts timespec
55 ts.set_sec(ns / 1000000000)
56 ts.set_nsec(int32(ns % 1000000000))
58 if sem_reltimedwait_np((*semt)(unsafe.Pointer(_m_.mos.waitsema)), &ts) != 0 {
59 err := errno()
60 if err == _ETIMEDOUT || err == _EAGAIN || err == _EINTR {
61 return -1
63 throw("sem_reltimedwait_np")
65 return 0
67 for {
68 r1 := sem_wait((*semt)(unsafe.Pointer(_m_.mos.waitsema)))
69 if r1 == 0 {
70 break
72 if errno() == _EINTR {
73 continue
75 throw("sem_wait")
77 return 0
80 //go:nosplit
81 func semawakeup(mp *m) {
82 if sem_post((*semt)(unsafe.Pointer(mp.mos.waitsema))) != 0 {
83 throw("sem_post")