Source file
src/runtime/os_aix.go
1
2
3
4
5
6
7 package runtime
8
9 import (
10 "internal/abi"
11 "unsafe"
12 )
13
14 const (
15 threadStackSize = 0x100000
16 )
17
18
19
20 type funcDescriptor struct {
21 fn uintptr
22 toc uintptr
23 envPointer uintptr
24 }
25
26 type mOS struct {
27 waitsema uintptr
28 perrno uintptr
29 }
30
31
32 func semacreate(mp *m) {
33 if mp.waitsema != 0 {
34 return
35 }
36
37 var sem *semt
38
39
40
41
42 sem = (*semt)(malloc(unsafe.Sizeof(*sem)))
43 if sem_init(sem, 0, 0) != 0 {
44 throw("sem_init")
45 }
46 mp.waitsema = uintptr(unsafe.Pointer(sem))
47 }
48
49
50 func semasleep(ns int64) int32 {
51 mp := getg().m
52 if ns >= 0 {
53 var ts timespec
54
55 if clock_gettime(_CLOCK_REALTIME, &ts) != 0 {
56 throw("clock_gettime")
57 }
58 ts.tv_sec += ns / 1e9
59 ts.tv_nsec += ns % 1e9
60 if ts.tv_nsec >= 1e9 {
61 ts.tv_sec++
62 ts.tv_nsec -= 1e9
63 }
64
65 if r, err := sem_timedwait((*semt)(unsafe.Pointer(mp.waitsema)), &ts); r != 0 {
66 if err == _ETIMEDOUT || err == _EAGAIN || err == _EINTR {
67 return -1
68 }
69 println("sem_timedwait err ", err, " ts.tv_sec ", ts.tv_sec, " ts.tv_nsec ", ts.tv_nsec, " ns ", ns, " id ", mp.id)
70 throw("sem_timedwait")
71 }
72 return 0
73 }
74 for {
75 r1, err := sem_wait((*semt)(unsafe.Pointer(mp.waitsema)))
76 if r1 == 0 {
77 break
78 }
79 if err == _EINTR {
80 continue
81 }
82 throw("sem_wait")
83 }
84 return 0
85 }
86
87
88 func semawakeup(mp *m) {
89 if sem_post((*semt)(unsafe.Pointer(mp.waitsema))) != 0 {
90 throw("sem_post")
91 }
92 }
93
94 func osinit() {
95 ncpu = int32(sysconf(__SC_NPROCESSORS_ONLN))
96 physPageSize = sysconf(__SC_PAGE_SIZE)
97 }
98
99
100
101
102
103
104
105 func newosproc0(stacksize uintptr, fn *funcDescriptor) {
106 var (
107 attr pthread_attr
108 oset sigset
109 tid pthread
110 )
111
112 if pthread_attr_init(&attr) != 0 {
113 write(2, unsafe.Pointer(&failthreadcreate[0]), int32(len(failthreadcreate)))
114 exit(1)
115 }
116
117 if pthread_attr_setstacksize(&attr, threadStackSize) != 0 {
118 write(2, unsafe.Pointer(&failthreadcreate[0]), int32(len(failthreadcreate)))
119 exit(1)
120 }
121
122 if pthread_attr_setdetachstate(&attr, _PTHREAD_CREATE_DETACHED) != 0 {
123 write(2, unsafe.Pointer(&failthreadcreate[0]), int32(len(failthreadcreate)))
124 exit(1)
125 }
126
127
128
129 sigprocmask(_SIG_SETMASK, &sigset_all, &oset)
130 var ret int32
131 for tries := 0; tries < 20; tries++ {
132
133
134 ret = pthread_create(&tid, &attr, fn, nil)
135 if ret != _EAGAIN {
136 break
137 }
138 usleep(uint32(tries+1) * 1000)
139 }
140 sigprocmask(_SIG_SETMASK, &oset, nil)
141 if ret != 0 {
142 write(2, unsafe.Pointer(&failthreadcreate[0]), int32(len(failthreadcreate)))
143 exit(1)
144 }
145
146 }
147
148 var failthreadcreate = []byte("runtime: failed to create new OS thread\n")
149
150
151
152
153
154
155 func libpreinit() {
156 initsig(true)
157 }
158
159
160 func mpreinit(mp *m) {
161 mp.gsignal = malg(32 * 1024)
162 mp.gsignal.m = mp
163 }
164
165
166
167 func miniterrno() {
168 mp := getg().m
169 r, _ := syscall0(&libc__Errno)
170 mp.perrno = r
171
172 }
173
174 func minit() {
175 miniterrno()
176 minitSignals()
177 getg().m.procid = uint64(pthread_self())
178 }
179
180 func unminit() {
181 unminitSignals()
182 }
183
184
185
186 func mdestroy(mp *m) {
187 }
188
189
190 var tstart funcDescriptor
191
192 func newosproc(mp *m) {
193 var (
194 attr pthread_attr
195 oset sigset
196 tid pthread
197 )
198
199 if pthread_attr_init(&attr) != 0 {
200 throw("pthread_attr_init")
201 }
202
203 if pthread_attr_setstacksize(&attr, threadStackSize) != 0 {
204 throw("pthread_attr_getstacksize")
205 }
206
207 if pthread_attr_setdetachstate(&attr, _PTHREAD_CREATE_DETACHED) != 0 {
208 throw("pthread_attr_setdetachstate")
209 }
210
211
212
213 sigprocmask(_SIG_SETMASK, &sigset_all, &oset)
214 var ret int32
215 for tries := 0; tries < 20; tries++ {
216
217
218 ret = pthread_create(&tid, &attr, &tstart, unsafe.Pointer(mp))
219 if ret != _EAGAIN {
220 break
221 }
222 usleep(uint32(tries+1) * 1000)
223 }
224 sigprocmask(_SIG_SETMASK, &oset, nil)
225 if ret != 0 {
226 print("runtime: failed to create new OS thread (have ", mcount(), " already; errno=", ret, ")\n")
227 if ret == _EAGAIN {
228 println("runtime: may need to increase max user processes (ulimit -u)")
229 }
230 throw("newosproc")
231 }
232
233 }
234
235 func exitThread(wait *uint32) {
236
237
238 throw("exitThread")
239 }
240
241 var urandom_dev = []byte("/dev/urandom\x00")
242
243
244 func getRandomData(r []byte) {
245 fd := open(&urandom_dev[0], 0 , 0)
246 n := read(fd, unsafe.Pointer(&r[0]), int32(len(r)))
247 closefd(fd)
248 extendRandom(r, int(n))
249 }
250
251 func goenvs() {
252 goenvs_unix()
253 }
254
255
256
257 const (
258 _NSIG = 256
259 )
260
261
262 var sigtramp funcDescriptor
263
264
265
266 func setsig(i uint32, fn uintptr) {
267 var sa sigactiont
268 sa.sa_flags = _SA_SIGINFO | _SA_ONSTACK | _SA_RESTART
269 sa.sa_mask = sigset_all
270 if fn == abi.FuncPCABIInternal(sighandler) {
271 fn = uintptr(unsafe.Pointer(&sigtramp))
272 }
273 sa.sa_handler = fn
274 sigaction(uintptr(i), &sa, nil)
275
276 }
277
278
279
280 func setsigstack(i uint32) {
281 var sa sigactiont
282 sigaction(uintptr(i), nil, &sa)
283 if sa.sa_flags&_SA_ONSTACK != 0 {
284 return
285 }
286 sa.sa_flags |= _SA_ONSTACK
287 sigaction(uintptr(i), &sa, nil)
288 }
289
290
291
292 func getsig(i uint32) uintptr {
293 var sa sigactiont
294 sigaction(uintptr(i), nil, &sa)
295 return sa.sa_handler
296 }
297
298
299
300 func setSignalstackSP(s *stackt, sp uintptr) {
301 *(*uintptr)(unsafe.Pointer(&s.ss_sp)) = sp
302 }
303
304
305 func (c *sigctxt) fixsigcode(sig uint32) {
306 switch sig {
307 case _SIGPIPE:
308
309
310
311 c.set_sigcode(_SI_USER)
312 }
313 }
314
315
316
317 func sigaddset(mask *sigset, i int) {
318 (*mask)[(i-1)/64] |= 1 << ((uint32(i) - 1) & 63)
319 }
320
321 func sigdelset(mask *sigset, i int) {
322 (*mask)[(i-1)/64] &^= 1 << ((uint32(i) - 1) & 63)
323 }
324
325 func setProcessCPUProfiler(hz int32) {
326 setProcessCPUProfilerTimer(hz)
327 }
328
329 func setThreadCPUProfiler(hz int32) {
330 setThreadCPUProfilerHz(hz)
331 }
332
333
334 func validSIGPROF(mp *m, c *sigctxt) bool {
335 return true
336 }
337
338 const (
339 _CLOCK_REALTIME = 9
340 _CLOCK_MONOTONIC = 10
341 )
342
343
344 func nanotime1() int64 {
345 tp := ×pec{}
346 if clock_gettime(_CLOCK_REALTIME, tp) != 0 {
347 throw("syscall clock_gettime failed")
348 }
349 return tp.tv_sec*1000000000 + tp.tv_nsec
350 }
351
352 func walltime() (sec int64, nsec int32) {
353 ts := ×pec{}
354 if clock_gettime(_CLOCK_REALTIME, ts) != 0 {
355 throw("syscall clock_gettime failed")
356 }
357 return ts.tv_sec, int32(ts.tv_nsec)
358 }
359
360
361 func fcntl(fd, cmd, arg int32) int32 {
362 r, _ := syscall3(&libc_fcntl, uintptr(fd), uintptr(cmd), uintptr(arg))
363 return int32(r)
364 }
365
366
367 func closeonexec(fd int32) {
368 fcntl(fd, _F_SETFD, _FD_CLOEXEC)
369 }
370
371
372 func setNonblock(fd int32) {
373 flags := fcntl(fd, _F_GETFL, 0)
374 fcntl(fd, _F_SETFL, flags|_O_NONBLOCK)
375 }
376
377
378
379 const sigPerThreadSyscall = 1 << 31
380
381
382 func runPerThreadSyscall() {
383 throw("runPerThreadSyscall only valid on linux")
384 }
385
View as plain text