CPU state tracking
[akaros.git] / kern / src / time.c
index 9364ca0..39955f3 100644 (file)
@@ -41,13 +41,27 @@ void train_timing()
        printk("TSC overhead (Min: %llu, Max: %llu)\n", min_overhead, max_overhead);
 }
 
+void udelay_sched(uint64_t usec)
+{
+       struct timer_chain *tchain = &per_cpu_info[core_id()].tchain;
+       struct alarm_waiter a_waiter;
+       init_awaiter(&a_waiter, 0);
+       set_awaiter_rel(&a_waiter, usec);
+       set_alarm(tchain, &a_waiter);
+       sleep_on_awaiter(&a_waiter);
+}
+
 /* Convenience wrapper called when a core's timer interrupt goes off.  Not to be
  * confused with global timers (like the PIC).  Do not put your code here.  If
  * you want something to happen in the future, set an alarm. */
-void timer_interrupt(struct trapframe *tf, void *data)
+void timer_interrupt(struct hw_trapframe *hw_tf, void *data)
 {
-       struct timer_chain *pcpui_tchain = &per_cpu_info[core_id()].tchain;
-       trigger_tchain(pcpui_tchain);
+       if (in_kernel(hw_tf))
+               oprofile_add_backtrace(get_hwtf_pc(hw_tf), get_hwtf_fp(hw_tf));
+       else
+               oprofile_add_userpc(get_hwtf_pc(hw_tf));
+
+       __trigger_tchain(&per_cpu_info[core_id()].tchain, hw_tf);
 }
 
 /* We can overflow/wraparound when we multiply up, but we have to divide last,
@@ -118,3 +132,18 @@ uint64_t nsec2tsc(uint64_t nsec)
        else
                return (nsec * system_timing.tsc_freq) / 1000000000;
 }
+
+uint64_t epoch_seconds(void)
+{
+       /* TODO: figure out what epoch time TSC == 0 is */
+       uint64_t boot_sec = 1242129600; /* nanwan's birthday */
+       return tsc2sec(read_tsc()) + boot_sec;
+}
+
+void tsc2timespec(uint64_t tsc_time, struct timespec *ts)
+{
+       ts->tv_sec = tsc2sec(tsc_time);
+       /* subtract off everything but the remainder */
+       tsc_time -= sec2tsc(ts->tv_sec);
+       ts->tv_nsec = tsc2nsec(tsc_time);
+}