Remove building with NOCRYPTO option
[minix.git] / minix / lib / libddekit / src / timer.c
blob631b920fd264f48953bc86d004c9773eb31c41da
1 #include "common.h"
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
9 #undef DDEBUG
10 #define DDEBUG DDEBUG_LEVEL_TIMER
11 #endif
13 #include "debug.h"
14 #include "thread.h"
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 {
23 void (*fn)(void *);
24 void *args;
25 int id;
26 myclock_t exp;
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;
37 unsigned long HZ;
39 static struct ddekit_timer_s list = {0,0,-1,1,0};
40 static int _id = 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 void remove_timer(int id);
47 static int insert_timer(struct ddekit_timer_s *t);
48 static struct ddekit_timer_s * get_next( myclock_t exp );
49 static void ddekit_timer_thread(void *data);
51 /****************************************************************************
52 * Private funtions *
53 ****************************************************************************/
55 /*****************************************************************************
56 * lock_timer *
57 ****************************************************************************/
58 static void lock_timer()
60 ddekit_lock_lock(&lock);
63 /*****************************************************************************
64 * unlock_timer *
65 ****************************************************************************/
66 static void unlock_timer()
68 ddekit_lock_unlock(&lock);
71 /*****************************************************************************
72 * remove_timer *
73 ****************************************************************************/
74 static void remove_timer(int id)
76 /* removes a timer from the timer list */
77 struct ddekit_timer_s *l,*m;
79 lock_timer();
81 for (l = &list; l && l->next && l->next->id!=id; l = l->next )
84 if (l && l->next) {
85 m = l->next;
87 DDEBUG_MSG_VERBOSE(
88 "deleting timer at for tick: %d fn: %p, (now: %d)\n",
89 m->exp, m->fn, jiffies);
91 l->next = m->next;
92 DDEBUG_MSG_TIMER(m);
94 ddekit_simple_free(m);
97 unlock_timer();
100 /*****************************************************************************
101 * insert_timer *
102 ****************************************************************************/
103 static int insert_timer(struct ddekit_timer_s *t)
105 /* inserts a timer to the timer list */
106 int ret;
108 lock_timer();
110 struct ddekit_timer_s *l;
112 for (l = &list; l->next && l->next->exp <= t->exp; l = l->next) {
116 t->next = l->next;
117 l->next = t;
119 t->id = ret = _id;
121 _id++;
123 if (_id==0) {
124 DDEBUG_MSG_WARN("Timer ID overflow...");
127 DDEBUG_MSG_TIMER(t);
129 unlock_timer();
131 return ret;
134 /*****************************************************************************
135 * get_next *
136 ****************************************************************************/
137 static struct ddekit_timer_s * get_next( myclock_t exp )
140 * this one get the next timer, which's timeout expired,
141 * returns NULL if no timer is pending
143 struct ddekit_timer_s * ret = 0;
144 lock_timer();
145 if (list.next)
147 if (list.next->exp <= exp)
149 ret = list.next;
150 list.next = ret->next;
153 unlock_timer();
154 return ret;
157 /*****************************************************************************
158 * ddekit_timer_thread *
159 ****************************************************************************/
160 static void ddekit_timer_thread(void * data)
162 struct ddekit_timer_s * l;
164 /* rock around the clock! */
165 for ( ; ; )
167 /* wait for timer interrupts */
168 ddekit_sem_down(pending_timer_ints);
169 DDEBUG_MSG_VERBOSE("handling timer interrupt");
171 /* execute all expired timers */
172 while( (l = get_next(jiffies)) != 0 ) {
173 DDEBUG_MSG_TIMER(l);
174 if (l->fn) {
175 l->fn(l->args);
177 ddekit_simple_free(l);
183 /****************************************************************************
184 * Public functions (ddekit/timer.h) *
185 ****************************************************************************/
187 /*****************************************************************************
188 * ddekit_add_timer *
189 ****************************************************************************/
190 int ddekit_add_timer
191 (void (*fn)(void *), void *args, unsigned long timeout)
193 struct ddekit_timer_s *t;
195 t = (struct ddekit_timer_s *)
196 ddekit_simple_malloc(sizeof(struct ddekit_timer_s ));
198 t->fn = fn;
199 t->args = args;
200 t->exp = (myclock_t) timeout;
202 return insert_timer(t);
205 /*****************************************************************************
206 * ddekit_del_timer *
207 ****************************************************************************/
208 int ddekit_del_timer(int timer)
210 remove_timer(timer);
211 return 0;
214 /*****************************************************************************
215 * ddekit_timer_pending *
216 ****************************************************************************/
217 int ddekit_timer_pending(int timer)
219 int ret=0;
220 struct ddekit_timer_s *t;
221 lock_timer();
222 for (t=list.next; t; t = t->next) {
223 if (t->id==timer) {
224 ret = 1;
228 unlock_timer();
229 return ret;
232 /*****************************************************************************
233 * ddekit_init_timers *
234 ****************************************************************************/
235 void ddekit_init_timers(void)
237 static int first_time=0;
239 if (!first_time)
241 ddekit_lock_init(&lock);
242 jiffies = getticks();
243 HZ = sys_hz();
244 pending_timer_ints = ddekit_sem_init(0);
245 th = ddekit_thread_create(ddekit_timer_thread, 0, "timer");
246 first_time=1;
247 DDEBUG_MSG_INFO("DDEkit timer subsustem initialized");
251 /*****************************************************************************
252 * ddekit_get_timer_thread *
253 ****************************************************************************/
254 ddekit_thread_t *ddekit_get_timer_thread(void)
256 return th;
259 /****************************************************************************
260 * ddekit_internal (src/timer.h) *
261 ****************************************************************************/
263 /*****************************************************************************
264 * _ddekit_timer_interrupt *
265 ****************************************************************************/
266 void _ddekit_timer_interrupt(void)
268 jiffies = getticks();
269 DDEBUG_MSG_VERBOSE("now: %d", jiffies);
270 ddekit_sem_up(pending_timer_ints);
273 /*****************************************************************************
274 * _ddekit_timer_update *
275 ****************************************************************************/
276 void _ddekit_timer_update()
278 lock_timer();
280 static myclock_t next_timout;
281 if(list.next)
283 if(!_ddekit_timer_pending || list.next->exp < next_timout) {
285 unsigned to = list.next->exp - jiffies;
287 _ddekit_timer_pending = 1;
289 if (list.next->exp <= jiffies) {
290 DDEBUG_MSG_WARN("Timeout lies in past to %d, now: %d",
291 list.next->exp, jiffies);
292 to = 1;
295 sys_setalarm(to, 0 /* REL */);
297 DDEBUG_MSG_VERBOSE("requesting alarm for clock tick %d , now %d",
298 list.next->exp, jiffies);
300 next_timout = list.next->exp;
302 unlock_timer();