Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*****************************************************************************
- * @File timer.c
- * @Date 10/15/2012
- * @Brief We use unsorted double linked list to manage timers, Simple and small
- * for most embedded purposes as we won't have a lot of timers at any
- * given time. Add:O(1)/Remove:O(1)/Handle:O(N),
- * 1) Optimizing for Timeout timers that don't get called often but
- * are added/removed often. We optimise for most used path.
- * This is based on assumption that timers (registered for waking
- * or notifying timeouts) don't fire that often compared to the
- * frequency at which timers are added/removed.
- * 2) Periodic timers can be implemented by re-adding timer in callback.
- * Add:O(N)/Remove:O(1)/Handle:O(1) (sorted list) is bad for this
- * purpose as periodic timer needs to be resorted giving it Handle:O(N+1)
- * overhead for each periodic timer in handle instead of Handle:O(2)
- * using an unsorted list.
- *****************************************************************************/
- #include <timer.h>
- volatile time_t timer_tick = 0UL; /* DIRTY! */
- static list_t timer_list = LIST_INIT(timer_list);
- static inline void timer_insert_internal(timer_t *timer)
- {
- if(likely(!list_in_list(&timer->node)))
- list_add(&timer_list, &timer->node);
- }
- static inline void timer_remove_internal(timer_t *timer)
- {
- if(likely(list_in_list(&timer->node)))
- list_delete(&timer->node);
- }
- void sys_tick(void)
- {
- timer_t *tmp;
- timer_t *timer;
- ++timer_ticks;
- list_for_every_entry_safe(&timer_list, timer, tmp, timer_t, node)
- {
- if(timer->tick <= timer_ticks)
- {
- if(timer->handle(timer, timer->args) != TIMER_RESCHEDULE)
- list_delete(&timer->node);
- }
- }
- if(unlikely(--curr_thread->quantum <= 0))
- thread_preempt();
- }
- void timer_cancel(timer_t *timer)
- {
- irq_disable();
- timer_remove_internal(timer);
- irq_enable();
- }
- void timer_reset(timer_t *timer, time_t delay)
- {
- timer->tick = cpu_msecs_to_ticks(delay) + timer_ticks;
- irq_disable();
- timer_insert_internal(timer);
- irq_enable();
- }
- void timer_set(timer_t *timer, time_t delay, timer_handle_t handle, void *args)
- {
- timer->args = args;
- timer->handle = handle;
- timer->tick = cpu_msecs_to_ticks(delay) + timer_ticks;
- irq_disable();
- timer_insert_internal(timer);
- irq_enable();
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement