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