1 #include "common.h" 2 3 #include <ddekit/memory.h> 4 #include <ddekit/semaphore.h> 5 #include <ddekit/thread.h> 6 #include <ddekit/timer.h> 7 8 #ifdef DDEBUG_LEVEL_TIMER 9 #undef DDEBUG 10 #define DDEBUG DDEBUG_LEVEL_TIMER 11 #endif 12 13 #include "debug.h" 14 #include "thread.h" 15 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) 19 20 typedef clock_t myclock_t; 21 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; 28 }; 29 30 31 static ddekit_sem_t *pending_timer_ints; 32 33 /* are we currently expecting a alarm notify? */ 34 int _ddekit_timer_pending = 0; 35 36 unsigned long long jiffies; 37 unsigned long HZ; 38 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; 43 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); 50 51 /**************************************************************************** 52 * Private funtions * 53 ****************************************************************************/ 54 55 /***************************************************************************** 56 * lock_timer * 57 ****************************************************************************/ 58 static void lock_timer() 59 { 60 ddekit_lock_lock(&lock); 61 } 62 63 /***************************************************************************** 64 * unlock_timer * 65 ****************************************************************************/ 66 static void unlock_timer() 67 { 68 ddekit_lock_unlock(&lock); 69 } 70 71 /***************************************************************************** 72 * remove_timer * 73 ****************************************************************************/ 74 static void remove_timer(int id) 75 { 76 /* removes a timer from the timer list */ 77 struct ddekit_timer_s *l,*m; 78 79 lock_timer(); 80 81 for (l = &list; l && l->next && l->next->id!=id; l = l->next ) 82 ; 83 84 if (l && l->next) { 85 m = l->next; 86 87 DDEBUG_MSG_VERBOSE( 88 "deleting timer at for tick: %d fn: %p, (now: %d)\n", 89 m->exp, m->fn, jiffies); 90 91 l->next = m->next; 92 DDEBUG_MSG_TIMER(m); 93 94 ddekit_simple_free(m); 95 } 96 97 unlock_timer(); 98 } 99 100 /***************************************************************************** 101 * insert_timer * 102 ****************************************************************************/ 103 static int insert_timer(struct ddekit_timer_s *t) 104 { 105 /* inserts a timer to the timer list */ 106 int ret; 107 108 lock_timer(); 109 110 struct ddekit_timer_s *l; 111 112 for (l = &list; l->next && l->next->exp <= t->exp; l = l->next) { 113 114 } 115 116 t->next = l->next; 117 l->next = t; 118 119 t->id = ret = _id; 120 121 _id++; 122 123 if (_id==0) { 124 DDEBUG_MSG_WARN("Timer ID overflow..."); 125 } 126 127 DDEBUG_MSG_TIMER(t); 128 129 unlock_timer(); 130 131 return ret; 132 } 133 134 /***************************************************************************** 135 * get_next * 136 ****************************************************************************/ 137 static struct ddekit_timer_s * get_next( myclock_t exp ) 138 { 139 /* 140 * this one get the next timer, which's timeout expired, 141 * returns NULL if no timer is pending 142 */ 143 struct ddekit_timer_s * ret = 0; 144 lock_timer(); 145 if (list.next) 146 { 147 if (list.next->exp <= exp) 148 { 149 ret = list.next; 150 list.next = ret->next; 151 } 152 } 153 unlock_timer(); 154 return ret; 155 } 156 157 /***************************************************************************** 158 * ddekit_timer_thread * 159 ****************************************************************************/ 160 static void ddekit_timer_thread(void * data) 161 { 162 struct ddekit_timer_s * l; 163 164 /* rock around the clock! */ 165 for ( ; ; ) 166 { 167 /* wait for timer interrupts */ 168 ddekit_sem_down(pending_timer_ints); 169 DDEBUG_MSG_VERBOSE("handling timer interrupt"); 170 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); 176 } 177 ddekit_simple_free(l); 178 } 179 } 180 } 181 182 183 /**************************************************************************** 184 * Public functions (ddekit/timer.h) * 185 ****************************************************************************/ 186 187 /***************************************************************************** 188 * ddekit_add_timer * 189 ****************************************************************************/ 190 int ddekit_add_timer 191 (void (*fn)(void *), void *args, unsigned long timeout) 192 { 193 struct ddekit_timer_s *t; 194 195 t = (struct ddekit_timer_s *) 196 ddekit_simple_malloc(sizeof(struct ddekit_timer_s )); 197 198 t->fn = fn; 199 t->args = args; 200 t->exp = (myclock_t) timeout; 201 202 return insert_timer(t); 203 } 204 205 /***************************************************************************** 206 * ddekit_del_timer * 207 ****************************************************************************/ 208 int ddekit_del_timer(int timer) 209 { 210 remove_timer(timer); 211 return 0; 212 } 213 214 /***************************************************************************** 215 * ddekit_timer_pending * 216 ****************************************************************************/ 217 int ddekit_timer_pending(int timer) 218 { 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; 225 } 226 227 } 228 unlock_timer(); 229 return ret; 230 } 231 232 /***************************************************************************** 233 * ddekit_init_timers * 234 ****************************************************************************/ 235 void ddekit_init_timers(void) 236 { 237 static int first_time=0; 238 239 if (!first_time) 240 { 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"); 248 } 249 } 250 251 /***************************************************************************** 252 * ddekit_get_timer_thread * 253 ****************************************************************************/ 254 ddekit_thread_t *ddekit_get_timer_thread(void) 255 { 256 return th; 257 } 258 259 /**************************************************************************** 260 * ddekit_internal (src/timer.h) * 261 ****************************************************************************/ 262 263 /***************************************************************************** 264 * _ddekit_timer_interrupt * 265 ****************************************************************************/ 266 void _ddekit_timer_interrupt(void) 267 { 268 jiffies = getticks(); 269 DDEBUG_MSG_VERBOSE("now: %d", jiffies); 270 ddekit_sem_up(pending_timer_ints); 271 } 272 273 /***************************************************************************** 274 * _ddekit_timer_update * 275 ****************************************************************************/ 276 void _ddekit_timer_update() 277 { 278 lock_timer(); 279 280 static myclock_t next_timout; 281 if(list.next) 282 { 283 if(!_ddekit_timer_pending || list.next->exp < next_timout) { 284 285 unsigned to = list.next->exp - jiffies; 286 287 _ddekit_timer_pending = 1; 288 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; 293 } 294 295 sys_setalarm(to, 0 /* REL */); 296 297 DDEBUG_MSG_VERBOSE("requesting alarm for clock tick %d , now %d", 298 list.next->exp, jiffies); 299 } 300 next_timout = list.next->exp; 301 } 302 unlock_timer(); 303 } 304