summaryrefslogtreecommitdiff
path: root/src/pkg/runtime/freebsd
diff options
context:
space:
mode:
authorOndřej Surý <ondrej@sury.org>2011-04-26 09:55:32 +0200
committerOndřej Surý <ondrej@sury.org>2011-04-26 09:55:32 +0200
commit7b15ed9ef455b6b66c6b376898a88aef5d6a9970 (patch)
tree3ef530baa80cdf29436ba981f5783be6b4d2202b /src/pkg/runtime/freebsd
parent50104cc32a498f7517a51c8dc93106c51c7a54b4 (diff)
downloadgolang-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.h21
-rw-r--r--src/pkg/runtime/freebsd/386/signal.c61
-rw-r--r--src/pkg/runtime/freebsd/386/sys.s5
-rw-r--r--src/pkg/runtime/freebsd/amd64/defs.h23
-rw-r--r--src/pkg/runtime/freebsd/amd64/signal.c61
-rw-r--r--src/pkg/runtime/freebsd/amd64/sys.s8
-rw-r--r--src/pkg/runtime/freebsd/defs.c7
-rw-r--r--src/pkg/runtime/freebsd/mem.c2
-rw-r--r--src/pkg/runtime/freebsd/os.h5
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*);