#include #include #include #include #include /* internal timer information */ struct { struct timer_drv_interface driver; } timer_info; //--- // user-level timer API //--- /* timer_reserve(): Reserve and configure a timer */ tid_t timer_reserve(uint64_t delay_us) { if (timer_info.driver.timer_reserve != NULL) return (timer_info.driver.timer_reserve(delay_us)); return (-1); } /* timer_configure(): Reserve and configure a timer */ tid_t timer_configure(uint64_t delay_us, timer_call_t callback) { if (timer_info.driver.timer_configure != NULL) return (timer_info.driver.timer_configure(delay_us, callback)); return (-1); } /* timer_start(): Start a configured timer */ int timer_start(tid_t timer) { if (timer_info.driver.timer_start != NULL) return (timer_info.driver.timer_start(timer)); return (-1); } /* timer_pause(): Pause a timer without freeing it */ int timer_pause(tid_t timer) { if (timer_info.driver.timer_pause != NULL) return (timer_info.driver.timer_pause(timer)); return (-1); } /* timer_stop(): Stop and free a timer */ int timer_stop(tid_t timer) { if (timer_info.driver.timer_stop != NULL) return (timer_info.driver.timer_stop(timer)); return (-1); } /* timer_wait(): Wait for a timer to stop */ int timer_wait(tid_t timer) { if (timer_info.driver.timer_wait != NULL) return (timer_info.driver.timer_wait(timer)); return (-1); } /* timer_spinwait(): Start a timer and actively wait */ int timer_spinwait(tid_t timer) { if (timer_info.driver.timer_spinwait != NULL) return (timer_info.driver.timer_spinwait(timer)); return (-1); } /* timer_reload(): Change a timer's delay constant for next interrupts */ int timer_reload(tid_t timer, uint64_t delay_us) { if (timer_info.driver.timer_reload != NULL) return (timer_info.driver.timer_reload(timer, delay_us)); return (-1); } //--- // user-level profiling API //--- /* timer_prof_init(): Create a new context object */ int timer_prof_init(timer_prof_t *prof) { if (timer_info.driver.timer_prof_init != NULL) return (timer_info.driver.timer_prof_init(prof)); return (-1); } /* timer_prof_enter(): Start counting time for a function */ void timer_prof_enter(timer_prof_t *prof) { if (timer_info.driver.timer_prof_enter != NULL) timer_info.driver.timer_prof_enter(prof); } /* timer_prof_leave(): Stop counting time for a function */ void timer_prof_leave(timer_prof_t *prof) { if (timer_info.driver.timer_prof_leave != NULL) timer_info.driver.timer_prof_leave(prof); } /* timer_prof_enter_rec(): Start counting time for a recursive function */ void timer_prof_enter_rec(timer_prof_t *prof) { if (timer_info.driver.timer_prof_enter_rec != NULL) timer_info.driver.timer_prof_enter_rec(prof); } /* timer_prof_leave_rec(): Stop counting time for a recursive function */ void timer_prof_leave_rec(timer_prof_t *prof) { if (timer_info.driver.timer_prof_leave_rec != NULL) timer_info.driver.timer_prof_leave_rec(prof); } /* timer_prof_quit() : uninit timer_prof object */ int timer_prof_quit(timer_prof_t *prof) { if (timer_info.driver.timer_prof_quit != NULL) return (timer_info.driver.timer_prof_quit(prof)); return (-1); } /* timer_prof_time(): Time spent in a given context, in microseconds */ uint32_t timer_prof_time(timer_prof_t *prof) { if (timer_info.driver.timer_prof_time != NULL) return (timer_info.driver.timer_prof_time(prof)); return (-1); } //--- // Kernel module information //--- /* __timer_init() : initialize the timer module */ static void __timer_init(void) { memset(&timer_info, 0x00, sizeof(timer_info)); struct vhex_driver *driver = vhex_driver_table(); for (int i = 0; i < vhex_driver_count(); ++i) { if (driver[i].flags.TIMER) { memcpy( &timer_info.driver, driver[i].module_data, sizeof(struct timer_drv_interface) ); break; } } } /* __timer_quit() : uninitialize the timer module */ static void __timer_quit(void) { ; } /* declare the timer module */ struct vhex_module mod_timer = { .name = "timer", .init = &__timer_init, .quit = &__timer_quit, }; VHEX_DECLARE_MODULE(02, mod_timer);