Kprof uses an IRQ alarm
[akaros.git] / kern / drivers / dev / kprof.c
index 1377b15..a6b002b 100644 (file)
@@ -134,19 +134,20 @@ kproftimer(uintptr_t pc)
 
 static void setup_timers(void)
 {
 
 static void setup_timers(void)
 {
-       void handler(struct alarm_waiter *waiter)
+       void kprof_alarm(struct alarm_waiter *waiter, struct hw_trapframe *hw_tf)
        {
                struct timer_chain *tchain = &per_cpu_info[core_id()].tchain;
        {
                struct timer_chain *tchain = &per_cpu_info[core_id()].tchain;
-               kproftimer(per_cpu_info[core_id()].rip);
+               kproftimer(get_hwtf_pc(hw_tf));
                set_awaiter_rel(waiter, 1000);
                __set_alarm(tchain, waiter);
        }
        struct timer_chain *tchain = &per_cpu_info[core_id()].tchain;
        struct alarm_waiter *waiter = kmalloc(sizeof(struct alarm_waiter), 0);
                set_awaiter_rel(waiter, 1000);
                __set_alarm(tchain, waiter);
        }
        struct timer_chain *tchain = &per_cpu_info[core_id()].tchain;
        struct alarm_waiter *waiter = kmalloc(sizeof(struct alarm_waiter), 0);
-       init_awaiter(waiter, handler);
+       init_awaiter_irq(waiter, kprof_alarm);
        set_awaiter_rel(waiter, 1000);
        set_alarm(tchain, waiter);
 }
        set_awaiter_rel(waiter, 1000);
        set_alarm(tchain, waiter);
 }
+
 static void
 kprofinit(void)
 {
 static void
 kprofinit(void)
 {
@@ -163,6 +164,9 @@ kprofwalk(struct chan *c, struct chan *nc, char **name, int nname)
 static int
 kprofstat(struct chan *c, uint8_t *db, int n)
 {
 static int
 kprofstat(struct chan *c, uint8_t *db, int n)
 {
+       /* barf. */
+       kproftab[3].length = oproflen();
+
        return devstat(c, db, n, kproftab, ARRAY_SIZE(kproftab), devgen);
 }
 
        return devstat(c, db, n, kproftab, ARRAY_SIZE(kproftab), devgen);
 }
 
@@ -192,8 +196,6 @@ kprofread(struct chan *c, void *va, long n, int64_t off)
        uintptr_t offset = off;
        uint64_t pc;
        int snp_ret, ret = 0;
        uintptr_t offset = off;
        uint64_t pc;
        int snp_ret, ret = 0;
-       /* the oprofile queue */
-       extern struct queue *opq;
 
        switch((int)c->qid.path){
        case Kprofdirqid:
 
        switch((int)c->qid.path){
        case Kprofdirqid:
@@ -259,7 +261,7 @@ kprofread(struct chan *c, void *va, long n, int64_t off)
                n = ret;
                break;
        case Kprofoprofileqid:
                n = ret;
                break;
        case Kprofoprofileqid:
-               n = qread(opq, va, n);
+               n = oprofread(va,n);
                break;
        default:
                n = 0;
                break;
        default:
                n = 0;
@@ -286,15 +288,19 @@ kprofwrite(struct chan *c, void *a, long n, int64_t unused)
                        kprof.time = 1;
                }else if(strncmp(a, "start", 5) == 0) {
                        kprof.time = 1;
                        kprof.time = 1;
                }else if(strncmp(a, "start", 5) == 0) {
                        kprof.time = 1;
+                       /* this sets up the timer on the *calling* core! */
                        setup_timers();
                } else if(strncmp(a, "stop", 4) == 0) {
                        setup_timers();
                } else if(strncmp(a, "stop", 4) == 0) {
+                       /* TODO: stop the timers! */
                        kprof.time = 0;
                } else if(strncmp(a, "clear", 5) == 0) {
                        kprof_clear(&kprof);
                        kprof.time = 0;
                } else if(strncmp(a, "clear", 5) == 0) {
                        kprof_clear(&kprof);
-               }else if(strncmp(a, "opstart", 8) == 0) {
-                       /* maybe have enable/disable for it. */
+               }else if(strncmp(a, "opstart", 7) == 0) {
+                       oprofile_control_trace(1);
                }else if(strncmp(a, "opstop", 6) == 0) {
                }else if(strncmp(a, "opstop", 6) == 0) {
+                       oprofile_control_trace(0);
                } else  {
                } else  {
+                       printk("startclr|start|stop|clear|opstart|opstop");
                        error("startclr|start|stop|clear|opstart|opstop");
                }
                break;
                        error("startclr|start|stop|clear|opstart|opstop");
                }
                break;