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