kern
diff src/timer.c @ 55:88a6c4e192f9
Fixed most important task switching bugs.
Now it seems that I can switch in and out of user space reliably.
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Mon, 15 Aug 2011 04:03:39 +0300 |
parents | b1e8c8251884 |
children | 0be4615594df |
line diff
1.1 --- a/src/timer.c Sun Aug 14 16:57:23 2011 +0300 1.2 +++ b/src/timer.c Mon Aug 15 04:03:39 2011 +0300 1.3 @@ -45,10 +45,6 @@ 1.4 1.5 struct timer_event { 1.6 int dt; /* remaining ticks delta from the previous event */ 1.7 - 1.8 - void (*callback)(void*); 1.9 - void *cbarg; 1.10 - 1.11 struct timer_event *next; 1.12 }; 1.13 1.14 @@ -79,24 +75,21 @@ 1.15 interrupt(IRQ_TO_INTR(0), intr_handler); 1.16 } 1.17 1.18 -int start_timer(unsigned long msec, timer_func_t cbfunc, void *cbarg) 1.19 +void sleep(unsigned long msec) 1.20 { 1.21 int ticks, tsum, istate; 1.22 struct timer_event *ev, *node; 1.23 1.24 - printf("start_timer(%lu)\n", msec); 1.25 + printf("sleep(%lu)\n", msec); 1.26 1.27 if((ticks = MSEC_TO_TICKS(msec)) <= 0) { 1.28 - cbfunc(cbarg); 1.29 - return 0; 1.30 + return; 1.31 } 1.32 1.33 if(!(ev = malloc(sizeof *ev))) { 1.34 - printf("start_timer: failed to allocate timer_event structure\n"); 1.35 - return -1; 1.36 + printf("sleep: failed to allocate timer_event structure\n"); 1.37 + return; 1.38 } 1.39 - ev->callback = cbfunc; 1.40 - ev->cbarg = cbarg; 1.41 1.42 istate = get_intr_state(); 1.43 disable_intr(); 1.44 @@ -110,29 +103,30 @@ 1.45 if(ev->next) { 1.46 ev->next->dt -= ticks; 1.47 } 1.48 - set_intr_state(istate); 1.49 - return 0; 1.50 - } 1.51 + } else { 1.52 1.53 - tsum = evlist->dt; 1.54 - node = evlist; 1.55 + tsum = evlist->dt; 1.56 + node = evlist; 1.57 1.58 - while(node->next && ticks > tsum + node->next->dt) { 1.59 - tsum += node->next->dt; 1.60 - node = node->next; 1.61 - } 1.62 + while(node->next && ticks > tsum + node->next->dt) { 1.63 + tsum += node->next->dt; 1.64 + node = node->next; 1.65 + } 1.66 1.67 - ev->next = node->next; 1.68 - node->next = ev; 1.69 + ev->next = node->next; 1.70 + node->next = ev; 1.71 1.72 - /* fix the relative times */ 1.73 - ev->dt = ticks - tsum; 1.74 - if(ev->next) { 1.75 - ev->next->dt -= ev->dt; 1.76 + /* fix the relative times */ 1.77 + ev->dt = ticks - tsum; 1.78 + if(ev->next) { 1.79 + ev->next->dt -= ev->dt; 1.80 + } 1.81 } 1.82 1.83 set_intr_state(istate); 1.84 - return 0; 1.85 + 1.86 + /* wait on the address of this timer event */ 1.87 + wait(ev); 1.88 } 1.89 1.90 /* This will be called by the interrupt dispatcher approximately 1.91 @@ -160,17 +154,15 @@ 1.92 evlist = evlist->next; 1.93 1.94 printf("timer going off!!!\n"); 1.95 - ev->callback(ev->cbarg); 1.96 + /* wake up all processes waiting on this address */ 1.97 + wakeup(ev); 1.98 free(ev); 1.99 } 1.100 } 1.101 1.102 if((cur_proc = get_current_proc())) { 1.103 + /* if the timeslice of this process has expire, call the scheduler */ 1.104 if(--cur_proc->ticks_left <= 0) { 1.105 - /* since schedule will not return, we have to notify 1.106 - * the PIC that we're done with the IRQ handling 1.107 - */ 1.108 - end_of_irq(INTR_TO_IRQ(inum)); 1.109 schedule(); 1.110 } 1.111 }