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