- /*interrupt(IRQ_TO_INTR(0), timer_handler);*/
- /* set low level fast timer interrupt routine directly in the IDT */
- set_intr_entry(IRQ_TO_INTR(0), intr_entry_fast_timer);
+ interrupt(IRQ_TO_INTR(0), timer_handler);
+}
+
+void set_alarm(unsigned long msec, void (*func)(void))
+{
+ int ticks, tsum, iflag;
+ struct timer_event *ev, *node;
+
+ if((ticks = MSEC_TO_TICKS(msec)) <= 0) {
+ return;
+ }
+
+ if(!(ev = malloc(sizeof *ev))) {
+ panic("failed to allocate timer event");
+ return;
+ }
+ ev->func = func;
+
+ iflag = get_intr_flag();
+ disable_intr();
+
+ if(!evlist || ticks < evlist->dt) {
+ /* insert at the begining */
+ ev->next = evlist;
+ evlist = ev;
+
+ ev->dt = ticks;
+ if(ev->next) {
+ ev->next->dt -= ticks;
+ }
+ } else {
+ tsum = evlist->dt;
+ node = evlist;
+
+ while(node->next && ticks > tsum + node->next->dt) {
+ tsum += node->next->dt;
+ node = node->next;
+ }
+
+ ev->next = node->next;
+ node->next = ev;
+
+ /* fix the relative times */
+ ev->dt = ticks - tsum;
+ if(ev->next) {
+ ev->next->dt -= ev->dt;
+ }
+ }
+
+ set_intr_flag(iflag);
+}
+
+void cancel_alarm(void (*func)(void))
+{
+ int iflag;
+ struct timer_event *ev, *node;
+ struct timer_event dummy;
+
+ iflag = get_intr_flag();
+ disable_intr();
+
+ dummy.next = evlist;
+ node = &dummy;
+ while(node->next) {
+ ev = node->next;
+ if(ev->func == func) {
+ /* found it */
+ if(ev->next) {
+ ev->next->dt += ev->dt;
+ }
+ node->next = ev->next;
+ free(ev);
+ break;
+ }
+ node = node->next;
+ }
+
+ set_intr_flag(iflag);