Source file src/runtime/os_aix.go
1
2
3
4
5
6
7 package runtime
8
9 import (
10 "internal/cpu"
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 _m_ := 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(_m_.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 ", _m_.id)
70 throw("sem_timedwait")
71 }
72 return 0
73 }
74 for {
75 r1, err := sem_wait((*semt)(unsafe.Pointer(_m_.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 setupSystemConf()
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 func libpreinit() {
157 initsig(true)
158 }
159
160
161 func mpreinit(mp *m) {
162 mp.gsignal = malg(32 * 1024)
163 mp.gsignal.m = mp
164 }
165
166
167
168 func miniterrno() {
169 mp := getg().m
170 r, _ := syscall0(&libc__Errno)
171 mp.perrno = r
172
173 }
174
175 func minit() {
176 miniterrno()
177 minitSignals()
178 }
179
180 func unminit() {
181 unminitSignals()
182 }
183
184
185 var tstart funcDescriptor
186
187 func newosproc(mp *m) {
188 var (
189 attr pthread_attr
190 oset sigset
191 tid pthread
192 )
193
194 if pthread_attr_init(&attr) != 0 {
195 throw("pthread_attr_init")
196 }
197
198 if pthread_attr_setstacksize(&attr, threadStackSize) != 0 {
199 throw("pthread_attr_getstacksize")
200 }
201
202 if pthread_attr_setdetachstate(&attr, _PTHREAD_CREATE_DETACHED) != 0 {
203 throw("pthread_attr_setdetachstate")
204 }
205
206
207
208 sigprocmask(_SIG_SETMASK, &sigset_all, &oset)
209 var ret int32
210 for tries := 0; tries < 20; tries++ {
211
212
213 ret = pthread_create(&tid, &attr, &tstart, unsafe.Pointer(mp))
214 if ret != _EAGAIN {
215 break
216 }
217 usleep(uint32(tries+1) * 1000)
218 }
219 sigprocmask(_SIG_SETMASK, &oset, nil)
220 if ret != 0 {
221 print("runtime: failed to create new OS thread (have ", mcount(), " already; errno=", ret, ")\n")
222 if ret == _EAGAIN {
223 println("runtime: may need to increase max user processes (ulimit -u)")
224 }
225 throw("newosproc")
226 }
227
228 }
229
230 func exitThread(wait *uint32) {
231
232
233 throw("exitThread")
234 }
235
236 var urandom_dev = []byte("/dev/urandom\x00")
237
238
239 func getRandomData(r []byte) {
240 fd := open(&urandom_dev[0], 0 , 0)
241 n := read(fd, unsafe.Pointer(&r[0]), int32(len(r)))
242 closefd(fd)
243 extendRandom(r, int(n))
244 }
245
246 func goenvs() {
247 goenvs_unix()
248 }
249
250
251
252 const (
253 _NSIG = 256
254 )
255
256
257 var sigtramp funcDescriptor
258
259
260
261 func setsig(i uint32, fn uintptr) {
262 var sa sigactiont
263 sa.sa_flags = _SA_SIGINFO | _SA_ONSTACK | _SA_RESTART
264 sa.sa_mask = sigset_all
265 if fn == funcPC(sighandler) {
266 fn = uintptr(unsafe.Pointer(&sigtramp))
267 }
268 sa.sa_handler = fn
269 sigaction(uintptr(i), &sa, nil)
270
271 }
272
273
274
275 func setsigstack(i uint32) {
276 var sa sigactiont
277 sigaction(uintptr(i), nil, &sa)
278 if sa.sa_flags&_SA_ONSTACK != 0 {
279 return
280 }
281 sa.sa_flags |= _SA_ONSTACK
282 sigaction(uintptr(i), &sa, nil)
283 }
284
285
286
287 func getsig(i uint32) uintptr {
288 var sa sigactiont
289 sigaction(uintptr(i), nil, &sa)
290 return sa.sa_handler
291 }
292
293
294
295 func setSignalstackSP(s *stackt, sp uintptr) {
296 *(*uintptr)(unsafe.Pointer(&s.ss_sp)) = sp
297 }
298
299
300 func (c *sigctxt) fixsigcode(sig uint32) {
301 switch sig {
302 case _SIGPIPE:
303
304
305
306 c.set_sigcode(_SI_USER)
307 }
308 }
309
310
311
312 func sigaddset(mask *sigset, i int) {
313 (*mask)[(i-1)/64] |= 1 << ((uint32(i) - 1) & 63)
314 }
315
316 func sigdelset(mask *sigset, i int) {
317 (*mask)[(i-1)/64] &^= 1 << ((uint32(i) - 1) & 63)
318 }
319
320 const (
321 _CLOCK_REALTIME = 9
322 _CLOCK_MONOTONIC = 10
323 )
324
325
326 func nanotime() int64 {
327 tp := ×pec{}
328 if clock_gettime(_CLOCK_REALTIME, tp) != 0 {
329 throw("syscall clock_gettime failed")
330 }
331 return tp.tv_sec*1000000000 + tp.tv_nsec
332 }
333
334 func walltime() (sec int64, nsec int32) {
335 ts := ×pec{}
336 if clock_gettime(_CLOCK_REALTIME, ts) != 0 {
337 throw("syscall clock_gettime failed")
338 }
339 return ts.tv_sec, int32(ts.tv_nsec)
340 }
341
342 const (
343
344 _SC_IMPL = 2
345 _IMPL_POWER8 = 0x10000
346 _IMPL_POWER9 = 0x20000
347 )
348
349
350
351 func setupSystemConf() {
352 impl := getsystemcfg(_SC_IMPL)
353 if impl&_IMPL_POWER8 != 0 {
354 cpu.HWCap2 |= cpu.PPC_FEATURE2_ARCH_2_07
355 }
356 if impl&_IMPL_POWER9 != 0 {
357 cpu.HWCap2 |= cpu.PPC_FEATURE2_ARCH_3_00
358 }
359 }
360
View as plain text