3 #include <ddekit/memory.h>
4 #include <ddekit/semaphore.h>
5 #include <ddekit/thread.h>
6 #include <ddekit/timer.h>
8 #ifdef DDEBUG_LEVEL_TIMER
10 #define DDEBUG DDEBUG_LEVEL_TIMER
16 #define DDEBUG_MSG_TIMER(t) \
17 DDEBUG_MSG_VERBOSE("id: %d, exp: %d, fn: %d, now %d", \
18 (t)->id, (t)->exp, (t)->fn, jiffies)
20 typedef clock_t myclock_t
;
22 struct ddekit_timer_s
{
27 struct ddekit_timer_s
* next
;
31 static ddekit_sem_t
*pending_timer_ints
;
33 /* are we currently expecting a alarm notify? */
34 int _ddekit_timer_pending
= 0;
36 unsigned long long jiffies
;
39 static struct ddekit_timer_s list
= {0,0,-1,1,0};
41 static ddekit_thread_t
*th
;
42 static ddekit_lock_t lock
;
44 static void lock_timer(void);
45 static void unlock_timer(void);
46 static clock_t get_current_clock(void);
47 static void remove_timer(int id
);
48 static int insert_timer(struct ddekit_timer_s
*t
);
49 static struct ddekit_timer_s
* get_next( myclock_t exp
);
50 static void ddekit_timer_thread(void *data
);
52 /****************************************************************************
54 ****************************************************************************/
56 /*****************************************************************************
58 ****************************************************************************/
59 static void lock_timer()
61 ddekit_lock_lock(&lock
);
64 /*****************************************************************************
66 ****************************************************************************/
67 static void unlock_timer()
69 ddekit_lock_unlock(&lock
);
72 /*****************************************************************************
74 ****************************************************************************/
75 static myclock_t
get_current_clock()
77 /* returns the current clock tick */
83 /*****************************************************************************
85 ****************************************************************************/
86 static void remove_timer(int id
)
88 /* removes a timer from the timer list */
89 struct ddekit_timer_s
*l
,*m
;
93 for (l
= &list
; l
&& l
->next
&& l
->next
->id
!=id
; l
= l
->next
)
100 "deleting timer at for tick: %d fn: %p, (now: %d)\n",
101 m
->exp
, m
->fn
, jiffies
);
106 ddekit_simple_free(m
);
112 /*****************************************************************************
114 ****************************************************************************/
115 static int insert_timer(struct ddekit_timer_s
*t
)
117 /* inserts a timer to the timer list */
122 struct ddekit_timer_s
*l
;
124 for (l
= &list
; l
->next
&& l
->next
->exp
<= t
->exp
; l
= l
->next
) {
136 DDEBUG_MSG_WARN("Timer ID overflow...");
146 /*****************************************************************************
148 ****************************************************************************/
149 static struct ddekit_timer_s
* get_next( myclock_t exp
)
152 * this one get the next timer, which's timeout expired,
153 * returns NULL if no timer is pending
155 struct ddekit_timer_s
* ret
= 0;
159 if (list
.next
->exp
<= exp
)
162 list
.next
= ret
->next
;
169 /*****************************************************************************
170 * ddekit_timer_thread *
171 ****************************************************************************/
172 static void ddekit_timer_thread(void * data
)
174 struct ddekit_timer_s
* l
;
176 /* rock around the clock! */
179 /* wait for timer interrupts */
180 ddekit_sem_down(pending_timer_ints
);
181 DDEBUG_MSG_VERBOSE("handling timer interrupt");
183 /* execute all expired timers */
184 while( (l
= get_next(jiffies
)) != 0 ) {
189 ddekit_simple_free(l
);
195 /****************************************************************************
196 * Public functions (ddekit/timer.h) *
197 ****************************************************************************/
199 /*****************************************************************************
201 ****************************************************************************/
203 (void (*fn
)(void *), void *args
, unsigned long timeout
)
205 struct ddekit_timer_s
*t
;
207 t
= (struct ddekit_timer_s
*)
208 ddekit_simple_malloc(sizeof(struct ddekit_timer_s
));
212 t
->exp
= (myclock_t
) timeout
;
214 return insert_timer(t
);
217 /*****************************************************************************
219 ****************************************************************************/
220 int ddekit_del_timer(int timer
)
226 /*****************************************************************************
227 * ddekit_timer_pending *
228 ****************************************************************************/
229 int ddekit_timer_pending(int timer
)
232 struct ddekit_timer_s
*t
;
234 for (t
=list
.next
; t
; t
= t
->next
) {
244 /*****************************************************************************
245 * ddekit_init_timers *
246 ****************************************************************************/
247 void ddekit_init_timers(void)
249 static int first_time
=0;
253 ddekit_lock_init(&lock
);
254 jiffies
= get_current_clock();
256 pending_timer_ints
= ddekit_sem_init(0);
257 th
= ddekit_thread_create(ddekit_timer_thread
, 0, "timer");
259 DDEBUG_MSG_INFO("DDEkit timer subsustem initialized");
263 /*****************************************************************************
264 * ddekit_get_timer_thread *
265 ****************************************************************************/
266 ddekit_thread_t
*ddekit_get_timer_thread(void)
271 /****************************************************************************
272 * ddekit_internal (src/timer.h) *
273 ****************************************************************************/
275 /*****************************************************************************
276 * _ddekit_timer_interrupt *
277 ****************************************************************************/
278 void _ddekit_timer_interrupt(void)
280 jiffies
= get_current_clock();
281 DDEBUG_MSG_VERBOSE("now: %d", jiffies
);
282 ddekit_sem_up(pending_timer_ints
);
285 /*****************************************************************************
286 * _ddekit_timer_update *
287 ****************************************************************************/
288 void _ddekit_timer_update()
292 static myclock_t next_timout
;
295 if(!_ddekit_timer_pending
|| list
.next
->exp
< next_timout
) {
297 unsigned to
= list
.next
->exp
- jiffies
;
299 _ddekit_timer_pending
= 1;
301 if (list
.next
->exp
<= jiffies
) {
302 DDEBUG_MSG_WARN("Timeout lies in past to %d, now: %d",
303 list
.next
->exp
, jiffies
);
307 sys_setalarm(to
, 0 /* REL */);
309 DDEBUG_MSG_VERBOSE("requesting alarm for clock tick %d , now %d",
310 list
.next
->exp
, jiffies
);
312 next_timout
= list
.next
->exp
;