OLD | NEW |
1 // Copyright 2009 The Go Authors. All rights reserved. | 1 // Copyright 2009 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 "stack.h" | 8 #include "stack.h" |
9 | 9 |
10 extern SigTab runtime·sigtab[]; | 10 extern SigTab runtime·sigtab[]; |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
59 int32 ret; | 59 int32 ret; |
60 uintptr nout; | 60 uintptr nout; |
61 | 61 |
62 mib[0] = 6; | 62 mib[0] = 6; |
63 mib[1] = 3; | 63 mib[1] = 3; |
64 nout = sizeof out; | 64 nout = sizeof out; |
65 out = 0; | 65 out = 0; |
66 ret = runtime·sysctl(mib, 2, (byte*)&out, &nout, nil, 0); | 66 ret = runtime·sysctl(mib, 2, (byte*)&out, &nout, nil, 0); |
67 if(ret >= 0) | 67 if(ret >= 0) |
68 runtime·ncpu = out; | 68 runtime·ncpu = out; |
| 69 runtime·gsignalstk = 32*1024; // OS X wants >=8K, Linux >=2K |
69 } | 70 } |
70 | 71 |
71 void | 72 void |
72 runtime·goenvs(void) | 73 runtime·goenvs(void) |
73 { | 74 { |
74 runtime·goenvs_unix(); | 75 runtime·goenvs_unix(); |
75 | 76 |
76 // Register our thread-creation callback (see sys_darwin_{amd64,386}.s) | 77 // Register our thread-creation callback (see sys_darwin_{amd64,386}.s) |
77 // but only if we're not using cgo. If we are using cgo we need | 78 // but only if we're not using cgo. If we are using cgo we need |
78 // to let the C pthread libary install its own thread-creation callback. | 79 // to let the C pthread libary install its own thread-creation callback. |
79 if(!runtime·iscgo) { | 80 if(!runtime·iscgo) { |
80 if(runtime·bsdthread_register() != 0) { | 81 if(runtime·bsdthread_register() != 0) { |
81 if(runtime·getenv("DYLD_INSERT_LIBRARIES")) | 82 if(runtime·getenv("DYLD_INSERT_LIBRARIES")) |
82 runtime·throw("runtime: bsdthread_register error
(unset DYLD_INSERT_LIBRARIES)"); | 83 runtime·throw("runtime: bsdthread_register error
(unset DYLD_INSERT_LIBRARIES)"); |
83 runtime·throw("runtime: bsdthread_register error"); | 84 runtime·throw("runtime: bsdthread_register error"); |
84 } | 85 } |
85 } | 86 } |
86 | |
87 } | 87 } |
88 | 88 |
89 void | 89 void |
90 runtime·newosproc(M *m, G *g, void *stk, void (*fn)(void)) | 90 runtime·newosproc(M *m, G *g, void *stk, void (*fn)(void)) |
91 { | 91 { |
92 int32 errno; | 92 int32 errno; |
93 Sigset oset; | 93 Sigset oset; |
94 | 94 |
95 m->tls[0] = m->id; // so 386 asm can find it | 95 m->tls[0] = m->id; // so 386 asm can find it |
96 if(0){ | 96 if(0){ |
97 runtime·printf("newosproc stk=%p m=%p g=%p fn=%p id=%d/%d ostk=%
p\n", | 97 runtime·printf("newosproc stk=%p m=%p g=%p fn=%p id=%d/%d ostk=%
p\n", |
98 stk, m, g, fn, m->id, m->tls[0], &m); | 98 stk, m, g, fn, m->id, m->tls[0], &m); |
99 } | 99 } |
100 | 100 |
101 runtime·sigprocmask(SIG_SETMASK, &sigset_all, &oset); | 101 runtime·sigprocmask(SIG_SETMASK, &sigset_all, &oset); |
102 errno = runtime·bsdthread_create(stk, m, g, fn); | 102 errno = runtime·bsdthread_create(stk, m, g, fn); |
103 runtime·sigprocmask(SIG_SETMASK, &oset, nil); | 103 runtime·sigprocmask(SIG_SETMASK, &oset, nil); |
104 | 104 |
105 if(errno < 0) { | 105 if(errno < 0) { |
106 runtime·printf("runtime: failed to create new OS thread (have %d
already; errno=%d)\n", runtime·mcount(), -errno); | 106 runtime·printf("runtime: failed to create new OS thread (have %d
already; errno=%d)\n", runtime·mcount(), -errno); |
107 runtime·throw("runtime.newosproc"); | 107 runtime·throw("runtime.newosproc"); |
108 } | 108 } |
109 } | 109 } |
110 | 110 |
111 // Called to initialize a new m (including the bootstrap m). | 111 // Called to initialize a new m (including the bootstrap m). |
112 void | 112 void |
113 runtime·minit(void) | 113 runtime·minit(void) |
114 { | 114 { |
115 // Initialize signal handling. | 115 // Initialize signal handling. |
116 m->gsignal = runtime·malg(32*1024); // OS X wants >=8K, Linux >=2K | |
117 runtime·signalstack((byte*)m->gsignal->stackguard - StackGuard, 32*1024)
; | 116 runtime·signalstack((byte*)m->gsignal->stackguard - StackGuard, 32*1024)
; |
118 | 117 |
119 if(m->profilehz > 0) | 118 if(m->profilehz > 0) |
120 runtime·sigprocmask(SIG_SETMASK, &sigset_none, nil); | 119 runtime·sigprocmask(SIG_SETMASK, &sigset_none, nil); |
121 else | 120 else |
122 runtime·sigprocmask(SIG_SETMASK, &sigset_prof, nil); | 121 runtime·sigprocmask(SIG_SETMASK, &sigset_prof, nil); |
123 } | 122 } |
124 | 123 |
125 // Mach IPC, to get at semaphores | 124 // Mach IPC, to get at semaphores |
126 // Definitions are in /usr/include/mach on a Mac. | 125 // Definitions are in /usr/include/mach on a Mac. |
(...skipping 277 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
404 while((r = runtime·mach_semaphore_signal(sem)) != 0) { | 403 while((r = runtime·mach_semaphore_signal(sem)) != 0) { |
405 if(r == KERN_ABORTED) // interrupted | 404 if(r == KERN_ABORTED) // interrupted |
406 continue; | 405 continue; |
407 macherror(r, "semaphore_signal"); | 406 macherror(r, "semaphore_signal"); |
408 } | 407 } |
409 } | 408 } |
410 | 409 |
411 void | 410 void |
412 runtime·sigpanic(void) | 411 runtime·sigpanic(void) |
413 { | 412 { |
| 413 //runtime·printf("%d: sigpanic\n", m->id); |
414 switch(g->sig) { | 414 switch(g->sig) { |
415 case SIGBUS: | 415 case SIGBUS: |
| 416 //if(0) |
416 if(g->sigcode0 == BUS_ADRERR && g->sigcode1 < 0x1000) { | 417 if(g->sigcode0 == BUS_ADRERR && g->sigcode1 < 0x1000) { |
417 if(g->sigpc == 0) | 418 if(g->sigpc == 0) |
418 runtime·panicstring("call of nil func value"); | 419 runtime·panicstring("call of nil func value"); |
419 runtime·panicstring("invalid memory address or nil point
er dereference"); | 420 runtime·panicstring("invalid memory address or nil point
er dereference"); |
420 } | 421 } |
421 runtime·printf("unexpected fault address %p\n", g->sigcode1); | 422 runtime·printf("unexpected fault address %p\n", g->sigcode1); |
422 runtime·throw("fault"); | 423 runtime·throw("fault"); |
423 case SIGSEGV: | 424 case SIGSEGV: |
| 425 //if(0) |
424 if((g->sigcode0 == 0 || g->sigcode0 == SEGV_MAPERR || g->sigcode
0 == SEGV_ACCERR) && g->sigcode1 < 0x1000) { | 426 if((g->sigcode0 == 0 || g->sigcode0 == SEGV_MAPERR || g->sigcode
0 == SEGV_ACCERR) && g->sigcode1 < 0x1000) { |
425 if(g->sigpc == 0) | 427 if(g->sigpc == 0) |
426 runtime·panicstring("call of nil func value"); | 428 runtime·panicstring("call of nil func value"); |
427 runtime·panicstring("invalid memory address or nil point
er dereference"); | 429 runtime·panicstring("invalid memory address or nil point
er dereference"); |
428 } | 430 } |
429 runtime·printf("unexpected fault address %p\n", g->sigcode1); | 431 runtime·printf("unexpected fault address %p\n", g->sigcode1); |
430 runtime·throw("fault"); | 432 runtime·throw("fault"); |
431 case SIGFPE: | 433 case SIGFPE: |
432 switch(g->sigcode0) { | 434 switch(g->sigcode0) { |
433 case FPE_INTDIV: | 435 case FPE_INTDIV: |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
503 #pragma textflag 7 | 505 #pragma textflag 7 |
504 void | 506 void |
505 runtime·badsignal(int32 sig) | 507 runtime·badsignal(int32 sig) |
506 { | 508 { |
507 if (sig == SIGPROF) { | 509 if (sig == SIGPROF) { |
508 return; // Ignore SIGPROFs intended for a non-Go thread. | 510 return; // Ignore SIGPROFs intended for a non-Go thread. |
509 } | 511 } |
510 runtime·write(2, badsignal, sizeof badsignal - 1); | 512 runtime·write(2, badsignal, sizeof badsignal - 1); |
511 runtime·exit(1); | 513 runtime·exit(1); |
512 } | 514 } |
OLD | NEW |