LEFT | RIGHT |
1 // Copyright 2011 The Go Authors. All rights reserved. | 1 // Copyright 2011 The Go Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style | 2 // Use of this source code is governed by a BSD-style |
3 // license that can be found in the LICENSE file. | 3 // license that can be found in the LICENSE file. |
4 | 4 |
5 #include "runtime.h" | 5 #include "runtime.h" |
6 #include "defs_GOOS_GOARCH.h" | 6 #include "defs_GOOS_GOARCH.h" |
7 #include "os_GOOS.h" | 7 #include "os_GOOS.h" |
8 #include "signal_unix.h" | 8 #include "signal_unix.h" |
9 #include "stack.h" | 9 #include "stack.h" |
10 #include "../../cmd/ld/textflag.h" | 10 #include "../../cmd/ld/textflag.h" |
11 | 11 |
12 #pragma dynexport end _end | 12 #pragma dynexport end _end |
13 #pragma dynexport etext _etext | 13 #pragma dynexport etext _etext |
14 #pragma dynexport edata _edata | 14 #pragma dynexport edata _edata |
15 | 15 |
16 #pragma dynimport libc·___errno ___errno "libc.so" | 16 #pragma dynimport libc·___errno ___errno "libc.so" |
17 #pragma dynimport libc·clock_gettime clock_gettime "libc.so" | 17 #pragma dynimport libc·clock_gettime clock_gettime "libc.so" |
18 #pragma dynimport libc·close close "libc.so" | 18 #pragma dynimport libc·close close "libc.so" |
19 #pragma dynimport libc·exit exit "libc.so" | 19 #pragma dynimport libc·exit exit "libc.so" |
20 #pragma dynimport libc·fcntl fcntl "libc.so" | |
21 #pragma dynimport libc·fstat fstat "libc.so" | 20 #pragma dynimport libc·fstat fstat "libc.so" |
22 #pragma dynimport libc·getcontext getcontext "libc.so" | 21 #pragma dynimport libc·getcontext getcontext "libc.so" |
23 #pragma dynimport libc·getrlimit getrlimit "libc.so" | 22 #pragma dynimport libc·getrlimit getrlimit "libc.so" |
24 #pragma dynimport libc·malloc malloc "libc.so" | 23 #pragma dynimport libc·malloc malloc "libc.so" |
25 #pragma dynimport libc·mmap mmap "libc.so" | 24 #pragma dynimport libc·mmap mmap "libc.so" |
26 #pragma dynimport libc·munmap munmap "libc.so" | 25 #pragma dynimport libc·munmap munmap "libc.so" |
27 #pragma dynimport libc·open open "libc.so" | 26 #pragma dynimport libc·open open "libc.so" |
28 #pragma dynimport libc·pthread_attr_destroy pthread_attr_destroy "libc.so" | 27 #pragma dynimport libc·pthread_attr_destroy pthread_attr_destroy "libc.so" |
29 #pragma dynimport libc·pthread_attr_getstack pthread_attr_getstack "libc.so" | 28 #pragma dynimport libc·pthread_attr_getstack pthread_attr_getstack "libc.so" |
30 #pragma dynimport libc·pthread_attr_init pthread_attr_init "libc.so" | 29 #pragma dynimport libc·pthread_attr_init pthread_attr_init "libc.so" |
(...skipping 13 matching lines...) Expand all Loading... |
44 #pragma dynimport libc·sigaltstack sigaltstack "libc.so" | 43 #pragma dynimport libc·sigaltstack sigaltstack "libc.so" |
45 #pragma dynimport libc·sigprocmask sigprocmask "libc.so" | 44 #pragma dynimport libc·sigprocmask sigprocmask "libc.so" |
46 #pragma dynimport libc·sysconf sysconf "libc.so" | 45 #pragma dynimport libc·sysconf sysconf "libc.so" |
47 #pragma dynimport libc·usleep usleep "libc.so" | 46 #pragma dynimport libc·usleep usleep "libc.so" |
48 #pragma dynimport libc·write write "libc.so" | 47 #pragma dynimport libc·write write "libc.so" |
49 | 48 |
50 extern uintptr libc·___errno; | 49 extern uintptr libc·___errno; |
51 extern uintptr libc·clock_gettime; | 50 extern uintptr libc·clock_gettime; |
52 extern uintptr libc·close; | 51 extern uintptr libc·close; |
53 extern uintptr libc·exit; | 52 extern uintptr libc·exit; |
54 extern uintptr libc·fcntl; | |
55 extern uintptr libc·fstat; | 53 extern uintptr libc·fstat; |
56 extern uintptr libc·getcontext; | 54 extern uintptr libc·getcontext; |
57 extern uintptr libc·getrlimit; | 55 extern uintptr libc·getrlimit; |
58 extern uintptr libc·malloc; | 56 extern uintptr libc·malloc; |
59 extern uintptr libc·mmap; | 57 extern uintptr libc·mmap; |
60 extern uintptr libc·munmap; | 58 extern uintptr libc·munmap; |
61 extern uintptr libc·open; | 59 extern uintptr libc·open; |
62 extern uintptr libc·pthread_attr_destroy; | 60 extern uintptr libc·pthread_attr_destroy; |
63 extern uintptr libc·pthread_attr_getstack; | 61 extern uintptr libc·pthread_attr_getstack; |
64 extern uintptr libc·pthread_attr_init; | 62 extern uintptr libc·pthread_attr_init; |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
110 for(;count; count--) | 108 for(;count; count--) |
111 m->scratch.v[count - 1] = *((uintptr*)&count + count); | 109 m->scratch.v[count - 1] = *((uintptr*)&count + count); |
112 m->libcall.args = (uintptr*)&m->scratch.v[0]; | 110 m->libcall.args = (uintptr*)&m->scratch.v[0]; |
113 runtime·asmcgocall(runtime·asmsysvicall6, &m->libcall); | 111 runtime·asmcgocall(runtime·asmsysvicall6, &m->libcall); |
114 return m->libcall.r1; | 112 return m->libcall.r1; |
115 } | 113 } |
116 | 114 |
117 static int32 | 115 static int32 |
118 getncpu(void)· | 116 getncpu(void)· |
119 { | 117 { |
120 » int32 n = (int32)runtime·sysconf(_SC_NPROCESSORS_ONLN); | 118 » int32 n; |
121 » return n > 1 ? n : 1; | 119 »······· |
| 120 » n = (int32)runtime·sysconf(_SC_NPROCESSORS_ONLN); |
| 121 » if(n < 1) |
| 122 » » return 1; |
| 123 » return n; |
122 } | 124 } |
123 | 125 |
124 void | 126 void |
125 runtime·osinit(void) | 127 runtime·osinit(void) |
126 { | 128 { |
127 runtime·ncpu = getncpu();· | 129 runtime·ncpu = getncpu();· |
128 } | 130 } |
129 | 131 |
130 void | 132 void |
131 runtime·newosproc(M *mp, void *stk) | 133 runtime·newosproc(M *mp, void *stk) |
(...skipping 11 matching lines...) Expand all Loading... |
143 if(runtime·pthread_attr_getstack(&attr, (void**)&mp->g0->stackbase, &mp-
>g0->stacksize) != 0) | 145 if(runtime·pthread_attr_getstack(&attr, (void**)&mp->g0->stackbase, &mp-
>g0->stacksize) != 0) |
144 runtime·throw("pthread_attr_getstack");· | 146 runtime·throw("pthread_attr_getstack");· |
145 if(runtime·pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED) !
= 0) | 147 if(runtime·pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED) !
= 0) |
146 runtime·throw("pthread_attr_setdetachstate"); | 148 runtime·throw("pthread_attr_setdetachstate"); |
147 | 149 |
148 // Disable signals during create, so that the new thread starts | 150 // Disable signals during create, so that the new thread starts |
149 // with signals disabled. It will enable them in minit. | 151 // with signals disabled. It will enable them in minit. |
150 runtime·sigprocmask(SIG_SETMASK, &sigset_all, &oset); | 152 runtime·sigprocmask(SIG_SETMASK, &sigset_all, &oset); |
151 ret = runtime·pthread_create(&tid, &attr, (void (*)(void))runtime·tstart
_sysvicall, mp); | 153 ret = runtime·pthread_create(&tid, &attr, (void (*)(void))runtime·tstart
_sysvicall, mp); |
152 runtime·sigprocmask(SIG_SETMASK, &oset, nil); | 154 runtime·sigprocmask(SIG_SETMASK, &oset, nil); |
153 » if (ret != 0) { | 155 » if(ret != 0) { |
154 runtime·printf("runtime: failed to create new OS thread (have %d
already; errno=%d)\n", runtime·mcount(), ret); | 156 runtime·printf("runtime: failed to create new OS thread (have %d
already; errno=%d)\n", runtime·mcount(), ret); |
155 runtime·throw("runtime.newosproc"); | 157 runtime·throw("runtime.newosproc"); |
156 } | 158 } |
157 } | 159 } |
158 | 160 |
159 void | 161 void |
160 runtime·get_random_data(byte **rnd, int32 *rnd_len) | 162 runtime·get_random_data(byte **rnd, int32 *rnd_len) |
161 { | 163 { |
162 static byte urandom_data[HashRandomBytes]; | 164 static byte urandom_data[HashRandomBytes]; |
163 int32 fd; | 165 int32 fd; |
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
309 StackT st; | 311 StackT st; |
310 | 312 |
311 st.ss_sp = (void*)p; | 313 st.ss_sp = (void*)p; |
312 st.ss_size = n; | 314 st.ss_size = n; |
313 st.ss_flags = 0; | 315 st.ss_flags = 0; |
314 if(p == nil) | 316 if(p == nil) |
315 st.ss_flags = SS_DISABLE; | 317 st.ss_flags = SS_DISABLE; |
316 runtime·sigaltstack(&st, nil); | 318 runtime·sigaltstack(&st, nil); |
317 } | 319 } |
318 | 320 |
| 321 void |
| 322 runtime·unblocksignals(void) |
| 323 { |
| 324 runtime·sigprocmask(SIG_SETMASK, &sigset_none, nil); |
| 325 } |
| 326 |
319 #pragma textflag NOSPLIT | 327 #pragma textflag NOSPLIT |
320 uintptr | 328 uintptr |
321 runtime·semacreate(void) | 329 runtime·semacreate(void) |
322 { | 330 { |
323 SemT* sem; | 331 SemT* sem; |
324 | 332 |
325 // Call libc's malloc rather than runtime·malloc. This will | 333 // Call libc's malloc rather than runtime·malloc. This will |
326 // allocate space on the C heap. We can't call runtime·malloc | 334 // allocate space on the C heap. We can't call runtime·malloc |
327 // here because it could cause a deadlock. | 335 // here because it could cause a deadlock. |
328 m->libcall.fn = (void*)libc·malloc; | 336 m->libcall.fn = (void*)libc·malloc; |
329 m->libcall.n = 1; | 337 m->libcall.n = 1; |
330 runtime·memclr((byte*)&m->scratch, sizeof(m->scratch)); | 338 runtime·memclr((byte*)&m->scratch, sizeof(m->scratch)); |
331 m->scratch.v[0] = (uintptr)sizeof(*sem); | 339 m->scratch.v[0] = (uintptr)sizeof(*sem); |
332 m->libcall.args = (uintptr*)&m->scratch; | 340 m->libcall.args = (uintptr*)&m->scratch; |
333 runtime·asmcgocall(runtime·asmsysvicall6, &m->libcall); | 341 runtime·asmcgocall(runtime·asmsysvicall6, &m->libcall); |
334 sem = (void*)m->libcall.r1; | 342 sem = (void*)m->libcall.r1; |
335 » if (runtime·sem_init(sem, 0, 0) != 0) | 343 » if(runtime·sem_init(sem, 0, 0) != 0) |
336 runtime·throw("sem_init"); | 344 runtime·throw("sem_init"); |
337 return (uintptr)sem; | 345 return (uintptr)sem; |
338 } | 346 } |
339 | 347 |
340 #pragma textflag NOSPLIT | 348 #pragma textflag NOSPLIT |
341 int32 | 349 int32 |
342 runtime·semasleep(int64 ns) | 350 runtime·semasleep(int64 ns) |
343 { | 351 { |
344 if(ns >= 0) { | 352 if(ns >= 0) { |
345 m->ts.tv_sec = ns / 1000000000LL; | 353 m->ts.tv_sec = ns / 1000000000LL; |
346 m->ts.tv_nsec = ns % 1000000000LL; | 354 m->ts.tv_nsec = ns % 1000000000LL; |
347 | 355 |
348 m->libcall.fn = (void*)libc·sem_reltimedwait_np; | 356 m->libcall.fn = (void*)libc·sem_reltimedwait_np; |
349 m->libcall.n = 2; | 357 m->libcall.n = 2; |
350 runtime·memclr((byte*)&m->scratch, sizeof(m->scratch)); | 358 runtime·memclr((byte*)&m->scratch, sizeof(m->scratch)); |
351 m->scratch.v[0] = m->waitsema; | 359 m->scratch.v[0] = m->waitsema; |
352 m->scratch.v[1] = (uintptr)&m->ts; | 360 m->scratch.v[1] = (uintptr)&m->ts; |
353 m->libcall.args = (uintptr*)&m->scratch; | 361 m->libcall.args = (uintptr*)&m->scratch; |
354 runtime·asmcgocall(runtime·asmsysvicall6, &m->libcall); | 362 runtime·asmcgocall(runtime·asmsysvicall6, &m->libcall); |
355 » » if(*((int32*)(m->perrno)) != 0) { | 363 » » if(*m->perrno != 0) { |
356 » » » if(*((int32*)(m->perrno)) == ETIMEDOUT || *((int32*)(m->
perrno)) == EAGAIN || *((int32*)(m->perrno)) == EINTR) | 364 » » » if(*m->perrno == ETIMEDOUT || *m->perrno == EAGAIN || *m
->perrno == EINTR) |
357 return -1; | 365 return -1; |
358 runtime·throw("sem_reltimedwait_np"); | 366 runtime·throw("sem_reltimedwait_np"); |
359 } | 367 } |
360 return 0; | 368 return 0; |
361 } | 369 } |
362 for(;;) { | 370 for(;;) { |
363 m->libcall.fn = (void*)libc·sem_wait; | 371 m->libcall.fn = (void*)libc·sem_wait; |
364 m->libcall.n = 1; | 372 m->libcall.n = 1; |
365 runtime·memclr((byte*)&m->scratch, sizeof(m->scratch)); | 373 runtime·memclr((byte*)&m->scratch, sizeof(m->scratch)); |
366 m->scratch.v[0] = m->waitsema; | 374 m->scratch.v[0] = m->waitsema; |
367 m->libcall.args = (uintptr*)&m->scratch; | 375 m->libcall.args = (uintptr*)&m->scratch; |
368 runtime·asmcgocall(runtime·asmsysvicall6, &m->libcall); | 376 runtime·asmcgocall(runtime·asmsysvicall6, &m->libcall); |
369 if(m->libcall.r1 == 0) | 377 if(m->libcall.r1 == 0) |
370 break; | 378 break; |
371 » » if(*((int32*)(m->perrno)) == EINTR)· | 379 » » if(*m->perrno == EINTR)· |
372 continue; | 380 continue; |
373 runtime·throw("sem_wait"); | 381 runtime·throw("sem_wait"); |
374 } | 382 } |
375 return 0; | 383 return 0; |
376 } | 384 } |
377 | 385 |
378 #pragma textflag NOSPLIT | 386 #pragma textflag NOSPLIT |
379 void | 387 void |
380 runtime·semawakeup(M *mp) | 388 runtime·semawakeup(M *mp) |
381 { | 389 { |
382 SemT* sem = (SemT*)mp->waitsema; | 390 SemT* sem = (SemT*)mp->waitsema; |
383 » if (runtime·sem_post(sem) != 0) | 391 » if(runtime·sem_post(sem) != 0) |
384 runtime·throw("sem_post"); | 392 runtime·throw("sem_post"); |
385 } | 393 } |
386 | 394 |
387 int32 | 395 int32 |
388 runtime·close(int32 fd) | 396 runtime·close(int32 fd) |
389 { | 397 { |
390 return runtime·sysvicall6(libc·close, 1, (uintptr)fd); | 398 return runtime·sysvicall6(libc·close, 1, (uintptr)fd); |
391 } | 399 } |
392 | 400 |
393 void | 401 void |
(...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
562 runtime·write(int32 fd, void* buf, int32 nbyte) | 570 runtime·write(int32 fd, void* buf, int32 nbyte) |
563 { | 571 { |
564 return runtime·sysvicall6(libc·write, 3, (uintptr)fd, (uintptr)buf, (uin
tptr)nbyte); | 572 return runtime·sysvicall6(libc·write, 3, (uintptr)fd, (uintptr)buf, (uin
tptr)nbyte); |
565 } | 573 } |
566 | 574 |
567 void | 575 void |
568 runtime·osyield(void) | 576 runtime·osyield(void) |
569 { | 577 { |
570 runtime·sysvicall6(libc·sched_yield, 0); | 578 runtime·sysvicall6(libc·sched_yield, 0); |
571 } | 579 } |
LEFT | RIGHT |