Daily bump.
[official-gcc.git] / libgo / go / runtime / os_darwin.go
blob10904fd87eae1e290d98d3081427c34df0661bb3
1 // Copyright 2009 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 (
8 "unsafe"
11 type mOS struct {
12 initialized bool
13 mutex pthreadmutex
14 cond pthreadcond
15 count int
18 func unimplemented(name string) {
19 println(name, "not implemented")
20 *(*int)(unsafe.Pointer(uintptr(1231))) = 1231
23 //go:nosplit
24 func semacreate(mp *m) {
25 if mp.initialized {
26 return
28 mp.initialized = true
29 if err := pthread_mutex_init(&mp.mutex, nil); err != 0 {
30 throw("pthread_mutex_init")
32 if err := pthread_cond_init(&mp.cond, nil); err != 0 {
33 throw("pthread_cond_init")
37 //go:nosplit
38 func semasleep(ns int64) int32 {
39 var start int64
40 if ns >= 0 {
41 start = nanotime()
43 mp := getg().m
44 pthread_mutex_lock(&mp.mutex)
45 for {
46 if mp.count > 0 {
47 mp.count--
48 pthread_mutex_unlock(&mp.mutex)
49 return 0
51 if ns >= 0 {
52 spent := nanotime() - start
53 if spent >= ns {
54 pthread_mutex_unlock(&mp.mutex)
55 return -1
57 var t timespec
58 t.setNsec(ns - spent)
59 err := pthread_cond_timedwait_relative_np(&mp.cond, &mp.mutex, &t)
60 if err == _ETIMEDOUT {
61 pthread_mutex_unlock(&mp.mutex)
62 return -1
64 } else {
65 pthread_cond_wait(&mp.cond, &mp.mutex)
70 //go:nosplit
71 func semawakeup(mp *m) {
72 pthread_mutex_lock(&mp.mutex)
73 mp.count++
74 if mp.count > 0 {
75 pthread_cond_signal(&mp.cond)
77 pthread_mutex_unlock(&mp.mutex)
80 // The read and write file descriptors used by the sigNote functions.
81 var sigNoteRead, sigNoteWrite int32
83 // sigNoteSetup initializes an async-signal-safe note.
85 // The current implementation of notes on Darwin is not async-signal-safe,
86 // because the functions pthread_mutex_lock, pthread_cond_signal, and
87 // pthread_mutex_unlock, called by semawakeup, are not async-signal-safe.
88 // There is only one case where we need to wake up a note from a signal
89 // handler: the sigsend function. The signal handler code does not require
90 // all the features of notes: it does not need to do a timed wait.
91 // This is a separate implementation of notes, based on a pipe, that does
92 // not support timed waits but is async-signal-safe.
93 func sigNoteSetup(*note) {
94 if sigNoteRead != 0 || sigNoteWrite != 0 {
95 throw("duplicate sigNoteSetup")
97 var errno int32
98 sigNoteRead, sigNoteWrite, errno = pipe()
99 if errno != 0 {
100 throw("pipe failed")
102 closeonexec(sigNoteRead)
103 closeonexec(sigNoteWrite)
105 // Make the write end of the pipe non-blocking, so that if the pipe
106 // buffer is somehow full we will not block in the signal handler.
107 // Leave the read end of the pipe blocking so that we will block
108 // in sigNoteSleep.
109 setNonblock(sigNoteWrite)
112 // sigNoteWakeup wakes up a thread sleeping on a note created by sigNoteSetup.
113 func sigNoteWakeup(*note) {
114 var b byte
115 write(uintptr(sigNoteWrite), unsafe.Pointer(&b), 1)
118 // sigNoteSleep waits for a note created by sigNoteSetup to be woken.
119 func sigNoteSleep(*note) {
120 for {
121 var b byte
122 entersyscallblock()
123 n := read(sigNoteRead, unsafe.Pointer(&b), 1)
124 exitsyscall()
125 if n != -_EINTR {
126 return
131 // BSD interface for threading.
132 func osinit() {
133 // pthread_create delayed until end of goenvs so that we
134 // can look at the environment first.
136 ncpu = getncpu()
137 physPageSize = getPageSize()
140 //go:nosplit
141 func validSIGPROF(mp *m, c *sigctxt) bool {
142 return true