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