aboutsummaryrefslogtreecommitdiff
path: root/libgo/runtime/proc.c
diff options
context:
space:
mode:
Diffstat (limited to 'libgo/runtime/proc.c')
-rw-r--r--libgo/runtime/proc.c57
1 files changed, 57 insertions, 0 deletions
diff --git a/libgo/runtime/proc.c b/libgo/runtime/proc.c
index 191fac6..bbdf894 100644
--- a/libgo/runtime/proc.c
+++ b/libgo/runtime/proc.c
@@ -14,3 +14,60 @@ M m0;
#endif
__thread M *m = &m0;
+
+static struct {
+ Lock;
+ void (*fn)(uintptr*, int32);
+ int32 hz;
+ uintptr pcbuf[100];
+} prof;
+
+void
+runtime_sigprof(uint8 *pc __attribute__ ((unused)),
+ uint8 *sp __attribute__ ((unused)),
+ uint8 *lr __attribute__ ((unused)))
+{
+ int32 n;
+
+ if(prof.fn == nil || prof.hz == 0)
+ return;
+
+ runtime_lock(&prof);
+ if(prof.fn == nil) {
+ runtime_unlock(&prof);
+ return;
+ }
+ n = 0;
+ // n = runtime·gentraceback(pc, sp, lr, gp, 0, prof.pcbuf, nelem(prof.pcbuf));
+ if(n > 0)
+ prof.fn(prof.pcbuf, n);
+ runtime_unlock(&prof);
+}
+
+void
+runtime_setcpuprofilerate(void (*fn)(uintptr*, int32), int32 hz)
+{
+ // Force sane arguments.
+ if(hz < 0)
+ hz = 0;
+ if(hz == 0)
+ fn = nil;
+ if(fn == nil)
+ hz = 0;
+
+ // Stop profiler on this cpu so that it is safe to lock prof.
+ // if a profiling signal came in while we had prof locked,
+ // it would deadlock.
+ runtime_resetcpuprofiler(0);
+
+ runtime_lock(&prof);
+ prof.fn = fn;
+ prof.hz = hz;
+ runtime_unlock(&prof);
+ // runtime_lock(&runtime_sched);
+ // runtime_sched.profilehz = hz;
+ // runtime_unlock(&runtime_sched);
+
+ if(hz != 0)
+ runtime_resetcpuprofiler(hz);
+}