00001 #ifndef KAL_TIMER_HRTIMER_H_
00002 #define KAL_TIMER_HRTIMER_H_
00003
00013 #ifndef CONFIG_HIGH_RES_TIMERS
00014 # error "CONFIG_HIGH_RES_TIMERS not set in kernel config"
00015 #endif
00016
00017 #include <linux/aquosa/qos_debug.h>
00018 #include <linux/aquosa/qos_types.h>
00019 #include <linux/aquosa/qos_memory.h>
00020 #include <linux/hrtimer.h>
00021
00022 #include "kal_time.h"
00023 #include "kal_arg.h"
00024
00025 typedef void (*kal_timer_cb)(kal_arg_t cb_data);
00026
00043 typedef struct kal_timer {
00044 struct hrtimer hrtimer;
00045 kal_timer_cb timer_cb;
00046 kal_arg_t timer_cb_data;
00047 char handler_running;
00048 } kal_timer_t;
00049
00050 typedef enum hrtimer_restart (*hrtimer_cb)(struct hrtimer *);
00051
00057 static enum hrtimer_restart hrt_callback(struct hrtimer *hrt) {
00058 kal_timer_t * timer = (kal_timer_t *) hrt;
00059 qos_chk_do(qos_mem_valid(timer), goto out);
00060 timer->handler_running = 1;
00061 timer->timer_cb(timer->timer_cb_data);
00062 timer->handler_running = 0;
00063 out:
00064 return HRTIMER_NORESTART;
00065 }
00066
00067 static inline void kal_timer_init(kal_timer_t * p_timer, kal_timer_cb cb, kal_arg_t cb_data) {
00068
00069 hrtimer_init(&p_timer->hrtimer, CLOCK_MONOTONIC, HRTIMER_MODE_ABS);
00070 p_timer->timer_cb = cb;
00071 p_timer->timer_cb_data = cb_data;
00072 p_timer->hrtimer.function = &hrt_callback;
00073 p_timer->handler_running = 0;
00074 }
00075
00077 #if LINUX_VERSION_CODE>=KERNEL_VERSION(2,6,28)
00078 static inline void kal_timer_set_expires(kal_timer_t * p_timer, kal_time_t t) {
00079 hrtimer_set_expires((struct hrtimer*) p_timer, kal_time2ktime(t));
00080 }
00081 #else
00082 static inline void kal_timer_set_expires(kal_timer_t * p_timer, kal_time_t t) {
00083 p_timer->hrtimer.expires = kal_time2ktime(t);
00084 }
00085 #endif
00086
00088 #if LINUX_VERSION_CODE>=KERNEL_VERSION(2,6,28)
00089 static inline kal_time_t kal_timer_get_expires(kal_timer_t * p_timer) {
00090 return kal_ktime2time(hrtimer_get_expires((struct hrtimer*) p_timer));
00091 }
00092 #else
00093 static inline kal_time_t kal_timer_get_expires(kal_timer_t * p_timer) {
00094 return kal_ktime2time(p_timer->hrtimer.expires);
00095 }
00096 #endif
00097
00099 static inline void kal_timer_init_now(kal_timer_t * p_timer, kal_timer_cb cb, kal_arg_t cb_data) {
00100 kal_time_t now = kal_time_now();
00101 kal_timer_init(p_timer, cb, cb_data);
00102 kal_timer_set_expires(p_timer, now);
00103 }
00104
00105 static inline void kal_timer_del(kal_timer_t * p_timer) {
00106 if (hrtimer_active(&p_timer->hrtimer) && (! p_timer->handler_running)) {
00107
00108 hrtimer_cancel(&p_timer->hrtimer);
00109
00110 }
00111 }
00112
00114 static inline void kal_timer_set(kal_timer_t * p_timer, kal_time_t t) {
00115 kal_timer_del(p_timer);
00116 hrtimer_start(&p_timer->hrtimer, kal_time2ktime(t), HRTIMER_MODE_ABS);
00117 }
00118
00120 static inline kal_time_t kal_timer_get_remaining(kal_timer_t * p_timer) {
00121 return kal_ktime2time(hrtimer_get_remaining(&p_timer->hrtimer));
00122 }
00123
00124 static inline void kal_timer_forward(kal_timer_t * p_timer, kal_time_t t) {
00125 kal_time_t expires = kal_time_add(kal_timer_get_expires(p_timer), t);
00126 kal_timer_del(p_timer);
00127 hrtimer_start(&p_timer->hrtimer, kal_time2ktime(expires), HRTIMER_MODE_ABS);
00128 }
00129
00130 static inline int kal_timer_pending(kal_timer_t *p_timer) {
00131 return hrtimer_active(&p_timer->hrtimer);
00132 }
00133
00134 #endif