diff options
author | Ondřej Surý <ondrej@sury.org> | 2011-04-26 09:55:32 +0200 |
---|---|---|
committer | Ondřej Surý <ondrej@sury.org> | 2011-04-26 09:55:32 +0200 |
commit | 7b15ed9ef455b6b66c6b376898a88aef5d6a9970 (patch) | |
tree | 3ef530baa80cdf29436ba981f5783be6b4d2202b /src/pkg/runtime/linux/amd64 | |
parent | 50104cc32a498f7517a51c8dc93106c51c7a54b4 (diff) | |
download | golang-7b15ed9ef455b6b66c6b376898a88aef5d6a9970.tar.gz |
Imported Upstream version 2011.04.13upstream/2011.04.13
Diffstat (limited to 'src/pkg/runtime/linux/amd64')
-rw-r--r-- | src/pkg/runtime/linux/amd64/defs.h | 13 | ||||
-rw-r--r-- | src/pkg/runtime/linux/amd64/signal.c | 58 | ||||
-rw-r--r-- | src/pkg/runtime/linux/amd64/sys.s | 8 |
3 files changed, 65 insertions, 14 deletions
diff --git a/src/pkg/runtime/linux/amd64/defs.h b/src/pkg/runtime/linux/amd64/defs.h index 3e3d32f0d..70d63145c 100644 --- a/src/pkg/runtime/linux/amd64/defs.h +++ b/src/pkg/runtime/linux/amd64/defs.h @@ -58,6 +58,9 @@ enum { BUS_OBJERR = 0x3, SEGV_MAPERR = 0x1, SEGV_ACCERR = 0x2, + ITIMER_REAL = 0, + ITIMER_VIRTUAL = 0x1, + ITIMER_PROF = 0x2, }; // Types @@ -88,9 +91,15 @@ struct Siginfo { int32 si_signo; int32 si_errno; int32 si_code; - byte pad0[4]; + byte pad_godefs_0[4]; byte _sifields[112]; }; + +typedef struct Itimerval Itimerval; +struct Itimerval { + Timeval it_interval; + Timeval it_value; +}; #pragma pack off // godefs -f -m64 defs1.c @@ -170,7 +179,7 @@ typedef struct Sigaltstack Sigaltstack; struct Sigaltstack { void *ss_sp; int32 ss_flags; - byte pad0[4]; + byte pad_godefs_0[4]; uint64 ss_size; }; diff --git a/src/pkg/runtime/linux/amd64/signal.c b/src/pkg/runtime/linux/amd64/signal.c index ea0932523..1db9c95e5 100644 --- a/src/pkg/runtime/linux/amd64/signal.c +++ b/src/pkg/runtime/linux/amd64/signal.c @@ -61,6 +61,11 @@ runtime·sighandler(int32 sig, Siginfo *info, void *context, G *gp) mc = &uc->uc_mcontext; r = (Sigcontext*)mc; // same layout, more conveient names + if(sig == SIGPROF) { + runtime·sigprof((uint8*)r->rip, (uint8*)r->rsp, nil, gp); + return; + } + if(gp != nil && (runtime·sigtab[sig].flags & SigPanic)) { // Make it look like a call to the signal func. // Have to pass arguments out of band since @@ -124,30 +129,59 @@ runtime·signalstack(byte *p, int32 n) runtime·sigaltstack(&st, nil); } +static void +sigaction(int32 i, void (*fn)(int32, Siginfo*, void*, G*), bool restart) +{ + Sigaction sa; + + runtime·memclr((byte*)&sa, sizeof sa); + sa.sa_flags = SA_ONSTACK | SA_SIGINFO | SA_RESTORER; + if(restart) + sa.sa_flags |= SA_RESTART; + sa.sa_mask = ~0ULL; + sa.sa_restorer = (void*)runtime·sigreturn; + if(fn == runtime·sighandler) + fn = (void*)runtime·sigtramp; + sa.sa_handler = fn; + runtime·rt_sigaction(i, &sa, nil, 8); +} + void runtime·initsig(int32 queue) { - static Sigaction sa; + int32 i; + void *fn; runtime·siginit(); - int32 i; - sa.sa_flags = SA_ONSTACK | SA_SIGINFO | SA_RESTORER; - sa.sa_mask = 0xFFFFFFFFFFFFFFFFULL; - sa.sa_restorer = (void*)runtime·sigreturn; for(i = 0; i<NSIG; i++) { if(runtime·sigtab[i].flags) { if((runtime·sigtab[i].flags & SigQueue) != queue) continue; if(runtime·sigtab[i].flags & (SigCatch | SigQueue)) - sa.sa_handler = (void*)runtime·sigtramp; + fn = runtime·sighandler; else - sa.sa_handler = (void*)runtime·sigignore; - if(runtime·sigtab[i].flags & SigRestart) - sa.sa_flags |= SA_RESTART; - else - sa.sa_flags &= ~SA_RESTART; - runtime·rt_sigaction(i, &sa, nil, 8); + fn = runtime·sigignore; + sigaction(i, fn, (runtime·sigtab[i].flags & SigRestart) != 0); } } } + +void +runtime·resetcpuprofiler(int32 hz) +{ + Itimerval it; + + runtime·memclr((byte*)&it, sizeof it); + if(hz == 0) { + runtime·setitimer(ITIMER_PROF, &it, nil); + sigaction(SIGPROF, SIG_IGN, true); + } else { + sigaction(SIGPROF, runtime·sighandler, true); + it.it_interval.tv_sec = 0; + it.it_interval.tv_usec = 1000000 / hz; + it.it_value = it.it_interval; + runtime·setitimer(ITIMER_PROF, &it, nil); + } + m->profilehz = hz; +} diff --git a/src/pkg/runtime/linux/amd64/sys.s b/src/pkg/runtime/linux/amd64/sys.s index 1bf734dc0..11df1f894 100644 --- a/src/pkg/runtime/linux/amd64/sys.s +++ b/src/pkg/runtime/linux/amd64/sys.s @@ -36,6 +36,14 @@ TEXT runtime·write(SB),7,$0-24 SYSCALL RET +TEXT runtime·setitimer(SB),7,$0-24 + MOVL 8(SP), DI + MOVQ 16(SP), SI + MOVQ 24(SP), DX + MOVL $38, AX // syscall entry + SYSCALL + RET + TEXT runtime·gettime(SB), 7, $32 LEAQ 8(SP), DI MOVQ $0, SI |