Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(4)

Side by Side Diff: src/pkg/runtime/thread_darwin.c

Issue 5697066: code review 5697066: runtime/pprof: support OS X CPU profiling (Closed)
Patch Set: diff -r aa03e1f59b18 https://go.googlecode.com/hg/ Created 13 years ago
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/pkg/runtime/sys_darwin_amd64.s ('k') | src/pkg/runtime/thread_freebsd.c » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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[];
11 11
12 static Sigset sigset_all = ~(Sigset)0; 12 static Sigset sigset_all = ~(Sigset)0;
13 static Sigset sigset_none; 13 static Sigset sigset_none;
14 static Sigset sigset_prof = 1<<(SIGPROF-1);
14 15
15 static void 16 static void
16 unimplemented(int8 *name) 17 unimplemented(int8 *name)
17 { 18 {
18 runtime·prints(name); 19 runtime·prints(name);
19 runtime·prints(" not implemented\n"); 20 runtime·prints(" not implemented\n");
20 *(int32*)1231 = 1231; 21 *(int32*)1231 = 1231;
21 } 22 }
22 23
23 int32 24 int32
24 runtime·semasleep(int64 ns) 25 runtime·semasleep(int64 ns)
25 { 26 {
26 » return runtime·mach_semacquire(m->waitsema, ns); 27 » int32 v;
28
29 » if(m->profilehz > 0)
30 » » runtime·setprof(false);
31 » v = runtime·mach_semacquire(m->waitsema, ns);
32 » if(m->profilehz > 0)
33 » » runtime·setprof(true);
34 » return v;
27 } 35 }
28 36
29 void 37 void
30 runtime·semawakeup(M *mp) 38 runtime·semawakeup(M *mp)
31 { 39 {
32 runtime·mach_semrelease(mp->waitsema); 40 runtime·mach_semrelease(mp->waitsema);
33 } 41 }
34 42
35 uintptr 43 uintptr
36 runtime·semacreate(void) 44 runtime·semacreate(void)
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
77 85
78 m->tls[0] = m->id; // so 386 asm can find it 86 m->tls[0] = m->id; // so 386 asm can find it
79 if(0){ 87 if(0){
80 runtime·printf("newosproc stk=%p m=%p g=%p fn=%p id=%d/%d ostk=% p\n", 88 runtime·printf("newosproc stk=%p m=%p g=%p fn=%p id=%d/%d ostk=% p\n",
81 stk, m, g, fn, m->id, m->tls[0], &m); 89 stk, m, g, fn, m->id, m->tls[0], &m);
82 } 90 }
83 91
84 runtime·sigprocmask(SIG_SETMASK, &sigset_all, &oset); 92 runtime·sigprocmask(SIG_SETMASK, &sigset_all, &oset);
85 errno = runtime·bsdthread_create(stk, m, g, fn); 93 errno = runtime·bsdthread_create(stk, m, g, fn);
86 runtime·sigprocmask(SIG_SETMASK, &oset, nil); 94 runtime·sigprocmask(SIG_SETMASK, &oset, nil);
87 » 95
88 if(errno < 0) { 96 if(errno < 0) {
89 runtime·printf("runtime: failed to create new OS thread (have %d already; errno=%d)\n", runtime·mcount(), -errno); 97 runtime·printf("runtime: failed to create new OS thread (have %d already; errno=%d)\n", runtime·mcount(), -errno);
90 runtime·throw("runtime.newosproc"); 98 runtime·throw("runtime.newosproc");
91 } 99 }
92 } 100 }
93 101
94 // Called to initialize a new m (including the bootstrap m). 102 // Called to initialize a new m (including the bootstrap m).
95 void 103 void
96 runtime·minit(void) 104 runtime·minit(void)
97 { 105 {
98 // Initialize signal handling. 106 // Initialize signal handling.
99 m->gsignal = runtime·malg(32*1024); // OS X wants >=8K, Linux >=2K 107 m->gsignal = runtime·malg(32*1024); // OS X wants >=8K, Linux >=2K
100 runtime·signalstack(m->gsignal->stackguard - StackGuard, 32*1024); 108 runtime·signalstack(m->gsignal->stackguard - StackGuard, 32*1024);
101 » runtime·sigprocmask(SIG_SETMASK, &sigset_none, nil); 109
110 » if(m->profilehz > 0)
111 » » runtime·sigprocmask(SIG_SETMASK, &sigset_none, nil);
112 » else
113 » » runtime·sigprocmask(SIG_SETMASK, &sigset_prof, nil);
102 } 114 }
103 115
104 // Mach IPC, to get at semaphores 116 // Mach IPC, to get at semaphores
105 // Definitions are in /usr/include/mach on a Mac. 117 // Definitions are in /usr/include/mach on a Mac.
106 118
107 static void 119 static void
108 macherror(int32 r, int8 *fn) 120 macherror(int32 r, int8 *fn)
109 { 121 {
110 runtime·printf("mach error %s: %d\n", fn, r); 122 runtime·printf("mach error %s: %d\n", fn, r);
111 runtime·throw("mach error"); 123 runtime·throw("mach error");
(...skipping 315 matching lines...) Expand 10 before | Expand all | Expand 10 after
427 439
428 uintptr 440 uintptr
429 runtime·memlimit(void) 441 runtime·memlimit(void)
430 { 442 {
431 // NOTE(rsc): Could use getrlimit here, 443 // NOTE(rsc): Could use getrlimit here,
432 // like on FreeBSD or Linux, but Darwin doesn't enforce 444 // like on FreeBSD or Linux, but Darwin doesn't enforce
433 // ulimit -v, so it's unclear why we'd try to stay within 445 // ulimit -v, so it's unclear why we'd try to stay within
434 // the limit. 446 // the limit.
435 return 0; 447 return 0;
436 } 448 }
449
450 // NOTE(rsc): On OS X, when the CPU profiling timer expires, the SIGPROF
451 // signal is not guaranteed to be sent to the thread that was executing to
452 // cause it to expire. It can and often does go to a sleeping thread, which is
453 // not interesting for our profile. This is filed Apple Bug Report #9177434,
454 // copied to http://code.google.com/p/go/source/detail?r=35b716c94225.
455 // To work around this bug, we disable receipt of the profiling signal on
456 // a thread while in blocking system calls. This forces the kernel to deliver
457 // the profiling signal to an executing thread.
458 //
459 // The workaround fails on OS X machines using a 64-bit Snow Leopard kernel.
460 // In that configuration, the kernel appears to want to deliver SIGPROF to the
461 // sleeping threads regardless of signal mask and, worse, does not deliver
462 // the signal until the thread wakes up on its own.
463 //
464 // If necessary, we can switch to using ITIMER_REAL for OS X and handle
465 // the kernel-generated SIGALRM by generating our own SIGALRMs to deliver
466 // to all the running threads. SIGALRM does not appear to be affected by
467 // the 64-bit Snow Leopard bug. However, as of this writing Mountain Lion
468 // is in preview, making Snow Leopard two versions old, so it is unclear how
469 // much effort we need to spend on one buggy kernel.
470
471 // Control whether profiling signal can be delivered to this thread.
472 void
473 runtime·setprof(bool on)
474 {
475 if(on)
476 runtime·sigprocmask(SIG_UNBLOCK, &sigset_prof, nil);
477 else
478 runtime·sigprocmask(SIG_BLOCK, &sigset_prof, nil);
479 }
OLDNEW
« no previous file with comments | « src/pkg/runtime/sys_darwin_amd64.s ('k') | src/pkg/runtime/thread_freebsd.c » ('j') | no next file with comments »

Powered by Google App Engine
RSS Feeds Recent Issues | This issue
This is Rietveld f62528b