diff options
Diffstat (limited to 'src/pkg/runtime/linux/arm')
-rw-r--r-- | src/pkg/runtime/linux/arm/defs.h | 42 | ||||
-rw-r--r-- | src/pkg/runtime/linux/arm/signal.c | 59 | ||||
-rw-r--r-- | src/pkg/runtime/linux/arm/sys.s | 9 |
3 files changed, 82 insertions, 28 deletions
diff --git a/src/pkg/runtime/linux/arm/defs.h b/src/pkg/runtime/linux/arm/defs.h index ff43d689a..6b2f22c66 100644 --- a/src/pkg/runtime/linux/arm/defs.h +++ b/src/pkg/runtime/linux/arm/defs.h @@ -1,4 +1,4 @@ -// godefs -carm-gcc -f -I/usr/local/google/src/linux-2.6.28/arch/arm/include -f -I/usr/local/google/src/linux-2.6.28/include -f-D__KERNEL__ -f-D__ARCH_SI_UID_T=int defs_arm.c +// godefs -f-I/usr/src/linux-headers-2.6.26-2-versatile/include defs_arm.c // MACHINE GENERATED - DO NOT EDIT. @@ -58,23 +58,15 @@ enum { BUS_OBJERR = 0x3, SEGV_MAPERR = 0x1, SEGV_ACCERR = 0x2, + ITIMER_REAL = 0, + ITIMER_PROF = 0x2, + ITIMER_VIRTUAL = 0x1, }; // Types #pragma pack on -typedef struct Sigset Sigset; -struct Sigset { - uint32 sig[2]; -}; - -typedef struct Sigaction Sigaction; -struct Sigaction { - void *sa_handler; - uint32 sa_flags; - void *sa_restorer; - Sigset sa_mask; -}; +typedef uint32 Sigset; typedef struct Timespec Timespec; struct Timespec { @@ -120,11 +112,23 @@ struct Ucontext { Ucontext *uc_link; Sigaltstack uc_stack; Sigcontext uc_mcontext; - Sigset uc_sigmask; - int32 __unused[30]; + uint32 uc_sigmask; + int32 __unused[31]; uint32 uc_regspace[128]; }; +typedef struct Timeval Timeval; +struct Timeval { + int32 tv_sec; + int32 tv_usec; +}; + +typedef struct Itimerval Itimerval; +struct Itimerval { + Timeval it_interval; + Timeval it_value; +}; + typedef struct Siginfo Siginfo; struct Siginfo { int32 si_signo; @@ -132,4 +136,12 @@ struct Siginfo { int32 si_code; uint8 _sifields[4]; }; + +typedef struct Sigaction Sigaction; +struct Sigaction { + void *sa_handler; + uint32 sa_flags; + void *sa_restorer; + uint32 sa_mask; +}; #pragma pack off diff --git a/src/pkg/runtime/linux/arm/signal.c b/src/pkg/runtime/linux/arm/signal.c index 843c40b68..05c6b0261 100644 --- a/src/pkg/runtime/linux/arm/signal.c +++ b/src/pkg/runtime/linux/arm/signal.c @@ -58,6 +58,11 @@ runtime·sighandler(int32 sig, Siginfo *info, void *context, G *gp) uc = context; r = &uc->uc_mcontext; + if(sig == SIGPROF) { + runtime·sigprof((uint8*)r->arm_pc, (uint8*)r->arm_sp, (uint8*)r->arm_lr, 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 @@ -119,31 +124,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.sig[0] = 0xFFFFFFFF; - sa.sa_mask.sig[1] = 0xFFFFFFFF; - 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/arm/sys.s b/src/pkg/runtime/linux/arm/sys.s index 9daf9c2e4..b9767a028 100644 --- a/src/pkg/runtime/linux/arm/sys.s +++ b/src/pkg/runtime/linux/arm/sys.s @@ -26,6 +26,7 @@ #define SYS_futex (SYS_BASE + 240) #define SYS_exit_group (SYS_BASE + 248) #define SYS_munmap (SYS_BASE + 91) +#define SYS_setitimer (SYS_BASE + 104) #define ARM_BASE (SYS_BASE + 0x0f0000) #define SYS_ARM_cacheflush (ARM_BASE + 2) @@ -72,6 +73,14 @@ TEXT runtime·munmap(SB),7,$0 SWI $0 RET +TEXT runtime·setitimer(SB),7,$0 + MOVW 0(FP), R0 + MOVW 4(FP), R1 + MOVW 8(FP), R2 + MOVW $SYS_setitimer, R7 + SWI $0 + RET + TEXT runtime·gettime(SB),7,$32 /* dummy version - return 0,0 */ MOVW $0, R1 |