Advertisement
Guest User

Untitled

a guest
Oct 16th, 2012
20
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.44 KB | None | 0 0
  1. /*****************************************************************************
  2. * @File timer.c
  3. * @Date 10/15/2012
  4. * @Brief We use unsorted double linked list to manage timers, Simple and small
  5. * for most embedded purposes as we won't have a lot of timers at any
  6. * given time. Add:O(1)/Remove:O(1)/Handle:O(N),
  7. * 1) Optimizing for Timeout timers that don't get called often but
  8. * are added/removed often. We optimise for most used path.
  9. * This is based on assumption that timers (registered for waking
  10. * or notifying timeouts) don't fire that often compared to the
  11. * frequency at which timers are added/removed.
  12. * 2) Periodic timers can be implemented by re-adding timer in callback.
  13. * Add:O(N)/Remove:O(1)/Handle:O(1) (sorted list) is bad for this
  14. * purpose as periodic timer needs to be resorted giving it Handle:O(N+1)
  15. * overhead for each periodic timer in handle instead of Handle:O(2)
  16. * using an unsorted list.
  17. *****************************************************************************/
  18.  
  19. #include <timer.h>
  20.  
  21. volatile time_t timer_tick = 0UL; /* DIRTY! */
  22. static list_t timer_list = LIST_INIT(timer_list);
  23.  
  24. static inline void timer_insert_internal(timer_t *timer)
  25. {
  26. if(likely(!list_in_list(&timer->node)))
  27. list_add(&timer_list, &timer->node);
  28. }
  29.  
  30. static inline void timer_remove_internal(timer_t *timer)
  31. {
  32. if(likely(list_in_list(&timer->node)))
  33. list_delete(&timer->node);
  34. }
  35.  
  36. void sys_tick(void)
  37. {
  38. timer_t *tmp;
  39. timer_t *timer;
  40.  
  41. ++timer_ticks;
  42.  
  43. list_for_every_entry_safe(&timer_list, timer, tmp, timer_t, node)
  44. {
  45. if(timer->tick <= timer_ticks)
  46. {
  47. if(timer->handle(timer, timer->args) != TIMER_RESCHEDULE)
  48. list_delete(&timer->node);
  49. }
  50. }
  51.  
  52. if(unlikely(--curr_thread->quantum <= 0))
  53. thread_preempt();
  54. }
  55.  
  56. void timer_cancel(timer_t *timer)
  57. {
  58. irq_disable();
  59. timer_remove_internal(timer);
  60. irq_enable();
  61. }
  62.  
  63. void timer_reset(timer_t *timer, time_t delay)
  64. {
  65. timer->tick = cpu_msecs_to_ticks(delay) + timer_ticks;
  66.  
  67. irq_disable();
  68. timer_insert_internal(timer);
  69. irq_enable();
  70. }
  71.  
  72. void timer_set(timer_t *timer, time_t delay, timer_handle_t handle, void *args)
  73. {
  74. timer->args = args;
  75. timer->handle = handle;
  76. timer->tick = cpu_msecs_to_ticks(delay) + timer_ticks;
  77.  
  78. irq_disable();
  79. timer_insert_internal(timer);
  80. irq_enable();
  81. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement