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/freebsd | |
parent | 50104cc32a498f7517a51c8dc93106c51c7a54b4 (diff) | |
download | golang-7b15ed9ef455b6b66c6b376898a88aef5d6a9970.tar.gz |
Imported Upstream version 2011.04.13upstream/2011.04.13
Diffstat (limited to 'src/pkg/runtime/freebsd')
-rw-r--r-- | src/pkg/runtime/freebsd/386/defs.h | 21 | ||||
-rw-r--r-- | src/pkg/runtime/freebsd/386/signal.c | 61 | ||||
-rw-r--r-- | src/pkg/runtime/freebsd/386/sys.s | 5 | ||||
-rw-r--r-- | src/pkg/runtime/freebsd/amd64/defs.h | 23 | ||||
-rw-r--r-- | src/pkg/runtime/freebsd/amd64/signal.c | 61 | ||||
-rw-r--r-- | src/pkg/runtime/freebsd/amd64/sys.s | 8 | ||||
-rw-r--r-- | src/pkg/runtime/freebsd/defs.c | 7 | ||||
-rw-r--r-- | src/pkg/runtime/freebsd/mem.c | 2 | ||||
-rw-r--r-- | src/pkg/runtime/freebsd/os.h | 5 |
9 files changed, 156 insertions, 37 deletions
diff --git a/src/pkg/runtime/freebsd/386/defs.h b/src/pkg/runtime/freebsd/386/defs.h index 128be9cc9..ae12b2019 100644 --- a/src/pkg/runtime/freebsd/386/defs.h +++ b/src/pkg/runtime/freebsd/386/defs.h @@ -61,6 +61,9 @@ enum { BUS_OBJERR = 0x3, SEGV_MAPERR = 0x1, SEGV_ACCERR = 0x2, + ITIMER_REAL = 0, + ITIMER_VIRTUAL = 0x1, + ITIMER_PROF = 0x2, }; // Types @@ -154,7 +157,9 @@ struct Mcontext { int32 mc_ownedfp; int32 mc_spare1[1]; int32 mc_fpstate[128]; - int32 mc_spare2[8]; + int32 mc_fsbase; + int32 mc_gsbase; + int32 mc_spare2[6]; }; typedef struct Ucontext Ucontext; @@ -165,6 +170,18 @@ struct Ucontext { StackT uc_stack; int32 uc_flags; int32 __spare__[4]; - byte pad0[12]; + byte pad_godefs_0[12]; +}; + +typedef struct Timeval Timeval; +struct Timeval { + int32 tv_sec; + int32 tv_usec; +}; + +typedef struct Itimerval Itimerval; +struct Itimerval { + Timeval it_interval; + Timeval it_value; }; #pragma pack off diff --git a/src/pkg/runtime/freebsd/386/signal.c b/src/pkg/runtime/freebsd/386/signal.c index 8e9d74256..1ae2554eb 100644 --- a/src/pkg/runtime/freebsd/386/signal.c +++ b/src/pkg/runtime/freebsd/386/signal.c @@ -54,6 +54,11 @@ runtime·sighandler(int32 sig, Siginfo *info, void *context, G *gp) uc = context; r = &uc->uc_mcontext; + if(sig == SIGPROF) { + runtime·sigprof((uint8*)r->mc_eip, (uint8*)r->mc_esp, 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 @@ -122,32 +127,58 @@ 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_SIGINFO|SA_ONSTACK; + if(restart) + sa.sa_flags |= SA_RESTART; + sa.sa_mask = ~0ULL; + if (fn == runtime·sighandler) + fn = (void*)runtime·sigtramp; + sa.__sigaction_u.__sa_sigaction = (void*)fn; + runtime·sigaction(i, &sa, nil); +} + void runtime·initsig(int32 queue) { - static Sigaction sa; + int32 i; + void *fn; runtime·siginit(); - int32 i; - sa.sa_flags |= SA_ONSTACK | SA_SIGINFO; - sa.sa_mask = ~0x0ull; - - for(i = 0; i < NSIG; i++) { + 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.__sigaction_u.__sa_sigaction = (void*) runtime·sigtramp; + fn = runtime·sighandler; else - sa.__sigaction_u.__sa_sigaction = (void*) runtime·sigignore; - - if(runtime·sigtab[i].flags & SigRestart) - sa.sa_flags |= SA_RESTART; - else - sa.sa_flags &= ~SA_RESTART; - - runtime·sigaction(i, &sa, nil); + 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/freebsd/386/sys.s b/src/pkg/runtime/freebsd/386/sys.s index 60c189bf8..c4715b668 100644 --- a/src/pkg/runtime/freebsd/386/sys.s +++ b/src/pkg/runtime/freebsd/386/sys.s @@ -87,6 +87,11 @@ TEXT runtime·munmap(SB),7,$-4 CALL runtime·notok(SB) RET +TEXT runtime·setitimer(SB), 7, $-4 + MOVL $83, AX + INT $0x80 + RET + TEXT runtime·gettime(SB), 7, $32 MOVL $116, AX LEAL 12(SP), BX diff --git a/src/pkg/runtime/freebsd/amd64/defs.h b/src/pkg/runtime/freebsd/amd64/defs.h index 2a295a479..b101b1932 100644 --- a/src/pkg/runtime/freebsd/amd64/defs.h +++ b/src/pkg/runtime/freebsd/amd64/defs.h @@ -61,6 +61,9 @@ enum { BUS_OBJERR = 0x3, SEGV_MAPERR = 0x1, SEGV_ACCERR = 0x2, + ITIMER_REAL = 0, + ITIMER_VIRTUAL = 0x1, + ITIMER_PROF = 0x2, }; // Types @@ -83,7 +86,7 @@ struct ThrParam { int64 *child_tid; int64 *parent_tid; int32 flags; - byte pad0[4]; + byte pad_godefs_0[4]; Rtprio *rtp; void* spare[3]; }; @@ -93,7 +96,7 @@ struct Sigaltstack { int8 *ss_sp; uint64 ss_size; int32 ss_flags; - byte pad0[4]; + byte pad_godefs_0[4]; }; typedef struct Sigset Sigset; @@ -114,7 +117,7 @@ struct StackT { int8 *ss_sp; uint64 ss_size; int32 ss_flags; - byte pad0[4]; + byte pad_godefs_0[4]; }; typedef struct Siginfo Siginfo; @@ -178,6 +181,18 @@ struct Ucontext { StackT uc_stack; int32 uc_flags; int32 __spare__[4]; - byte pad0[12]; + byte pad_godefs_0[12]; +}; + +typedef struct Timeval Timeval; +struct Timeval { + int64 tv_sec; + int64 tv_usec; +}; + +typedef struct Itimerval Itimerval; +struct Itimerval { + Timeval it_interval; + Timeval it_value; }; #pragma pack off diff --git a/src/pkg/runtime/freebsd/amd64/signal.c b/src/pkg/runtime/freebsd/amd64/signal.c index f145371b4..9d8e5e692 100644 --- a/src/pkg/runtime/freebsd/amd64/signal.c +++ b/src/pkg/runtime/freebsd/amd64/signal.c @@ -62,6 +62,11 @@ runtime·sighandler(int32 sig, Siginfo *info, void *context, G *gp) uc = context; r = &uc->uc_mcontext; + if(sig == SIGPROF) { + runtime·sigprof((uint8*)r->mc_rip, (uint8*)r->mc_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 @@ -130,32 +135,58 @@ 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_SIGINFO|SA_ONSTACK; + if(restart) + sa.sa_flags |= SA_RESTART; + sa.sa_mask = ~0ULL; + if (fn == runtime·sighandler) + fn = (void*)runtime·sigtramp; + sa.__sigaction_u.__sa_sigaction = (void*)fn; + runtime·sigaction(i, &sa, nil); +} + void runtime·initsig(int32 queue) { - static Sigaction sa; + int32 i; + void *fn; runtime·siginit(); - int32 i; - sa.sa_flags |= SA_ONSTACK | SA_SIGINFO; - sa.sa_mask = ~0x0ull; - - for(i = 0; i < NSIG; i++) { + 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.__sigaction_u.__sa_sigaction = (void*) runtime·sigtramp; + fn = runtime·sighandler; else - sa.__sigaction_u.__sa_sigaction = (void*) runtime·sigignore; - - if(runtime·sigtab[i].flags & SigRestart) - sa.sa_flags |= SA_RESTART; - else - sa.sa_flags &= ~SA_RESTART; - - runtime·sigaction(i, &sa, nil); + 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/freebsd/amd64/sys.s b/src/pkg/runtime/freebsd/amd64/sys.s index d986e9ac0..9a6fdf1ac 100644 --- a/src/pkg/runtime/freebsd/amd64/sys.s +++ b/src/pkg/runtime/freebsd/amd64/sys.s @@ -65,6 +65,14 @@ TEXT runtime·write(SB),7,$-8 SYSCALL RET +TEXT runtime·setitimer(SB), 7, $-8 + MOVL 8(SP), DI + MOVQ 16(SP), SI + MOVQ 24(SP), DX + MOVL $83, AX + SYSCALL + RET + TEXT runtime·gettime(SB), 7, $32 MOVL $116, AX LEAQ 8(SP), DI diff --git a/src/pkg/runtime/freebsd/defs.c b/src/pkg/runtime/freebsd/defs.c index 32a80f475..2ce4fdc51 100644 --- a/src/pkg/runtime/freebsd/defs.c +++ b/src/pkg/runtime/freebsd/defs.c @@ -19,6 +19,7 @@ #include <sys/rtprio.h> #include <sys/thr.h> #include <sys/_sigset.h> +#include <sys/unistd.h> enum { $PROT_NONE = PROT_NONE, @@ -86,6 +87,10 @@ enum { $SEGV_MAPERR = SEGV_MAPERR, $SEGV_ACCERR = SEGV_ACCERR, + + $ITIMER_REAL = ITIMER_REAL, + $ITIMER_VIRTUAL = ITIMER_VIRTUAL, + $ITIMER_PROF = ITIMER_PROF, }; typedef struct rtprio $Rtprio; @@ -99,3 +104,5 @@ typedef siginfo_t $Siginfo; typedef mcontext_t $Mcontext; typedef ucontext_t $Ucontext; +typedef struct timeval $Timeval; +typedef struct itimerval $Itimerval; diff --git a/src/pkg/runtime/freebsd/mem.c b/src/pkg/runtime/freebsd/mem.c index f5bbfa6fa..f80439e38 100644 --- a/src/pkg/runtime/freebsd/mem.c +++ b/src/pkg/runtime/freebsd/mem.c @@ -53,7 +53,7 @@ runtime·SysMap(void *v, uintptr n) if(sizeof(void*) == 8) { p = runtime·mmap(v, n, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_ANON|MAP_PRIVATE, -1, 0); if(p != v) { - runtime·printf("runtime: address space conflict: map(%v) = %v\n", v, p); + runtime·printf("runtime: address space conflict: map(%p) = %p\n", v, p); runtime·throw("runtime: address space conflict"); } return; diff --git a/src/pkg/runtime/freebsd/os.h b/src/pkg/runtime/freebsd/os.h index 455355bc7..13754688b 100644 --- a/src/pkg/runtime/freebsd/os.h +++ b/src/pkg/runtime/freebsd/os.h @@ -1,5 +1,10 @@ +#define SIG_DFL ((void*)0) +#define SIG_IGN ((void*)1) + int32 runtime·thr_new(ThrParam*, int32); void runtime·sigpanic(void); void runtime·sigaltstack(Sigaltstack*, Sigaltstack*); struct sigaction; void runtime·sigaction(int32, struct sigaction*, struct sigaction*); +void runtiem·setitimerval(int32, Itimerval*, Itimerval*); +void runtime·setitimer(int32, Itimerval*, Itimerval*); |