2 * \brief DOpE timer tick module
4 * \author Norman Feske <nf2@inf.tu-dresden.de>
8 * Copyright (C) 2002-2004 Norman Feske <nf2@os.inf.tu-dresden.de>
9 * Technische Universitaet Dresden, Operating Systems Research Group
11 * This file is part of the DOpE package, which is distributed under
12 * the terms of the GNU General Public Licence 2. Please see the
13 * COPYING file for details.
24 u32 deadline; /* next deadline */
25 u32 usec; /* duration between ticks */
26 int (*callback) (void *); /* tick callback */
27 void *arg; /* callback argument */
28 struct tick *next; /* next tick in ticklist */
31 static struct tick ticks[MAX_TICKS];
32 static struct tick *head = NULL; /* head of tick list */
34 static struct timer_services *timer;
36 int init_tick(struct dope_services *d);
39 /*************************
40 *** SERVICE FUNCTIONS ***
41 *************************/
43 /*** SCHEDULE NEW TICK EVENT ***/
44 static void queue_tick(struct tick *t) {
47 /* if ticklist is empty add first element */
54 /* if deadline is smaller than any other deadline, put it on the head */
55 if (t->deadline < head->deadline) {
61 /* find list element with a higher deadline */
63 while (curr->next && (curr->next->deadline < t->deadline)) curr = curr->next;
65 /* if end of list is reached, append new element */
71 /* insert element in middle of list */
77 /*** REGISTER NEW TIMER TICK CALLBACK ROUTINE ***
79 * \param msec duration between ticks
80 * \param callback routine that is called for every tick
81 * \param arg private argument for callback
82 * \return 1 on success
84 * The return code of this function should be evaluated!
86 static int tick_add(s32 msec, int (*callback)(void *), void *arg) {
89 /* find empty tick slot */
90 for (i=0; i<MAX_TICKS; i++)
91 if (ticks[i].callback == NULL) break;
93 /* no empty tick slot - return 0 */
94 if (i == MAX_TICKS) return 0;
96 /* put new tick at the beginning of the ticklist */
97 ticks[i].usec = msec * 1000;
98 ticks[i].deadline = timer->get_time() + ticks[i].usec;
99 ticks[i].callback = callback;
101 queue_tick(&ticks[i]);
107 /*** CHECK FOR DUE TICK EVENTS AND EXECUTE CALLBACKS ***/
108 static void tick_handle(void) {
109 u32 now = timer->get_time();
110 struct tick *curr = head;
112 while ((curr = head) && ((s32)now > (s32)head->deadline)) {
113 void *arg = head->arg;
115 /* remove tick from head of the list */
119 if (curr->callback(arg)) {
120 /* tick is still valid - schedule next event */
121 curr->deadline = now + curr->usec;
124 /* mark tick slot as free */
125 curr->callback = NULL;
131 /****************************************
132 *** SERVICE STRUCTURE OF THIS MODULE ***
133 ****************************************/
135 static struct tick_services services = {
141 /**************************
142 *** MODULE ENTRY POINT ***
143 **************************/
145 int init_tick(struct dope_services *dope) {
147 timer = dope->get_module("Timer 1.0");
149 dope->register_module("Tick 1.0",&services);