181 lines
4.1 KiB
C
181 lines
4.1 KiB
C
#include <vhex/timer/interface.h>
|
|
#include <vhex/driver.h>
|
|
#include <vhex/module.h>
|
|
#include <vhex/timer.h>
|
|
|
|
#include <string.h>
|
|
|
|
|
|
/* 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);
|