diff --git a/lib/utils/tick_delay.c b/lib/utils/tick_delay.c index 985234c05..ce97f5f4f 100644 --- a/lib/utils/tick_delay.c +++ b/lib/utils/tick_delay.c @@ -6,7 +6,14 @@ PUBLIC int tick_delay(ticks) long ticks; /* number of ticks to wait */ { - message m; +/* This function uses the synchronous alarm to delay for a while. This works + * even if a previous synchronous alarm was scheduled, because the remaining + * tick of the previous alarm are returned so that it can be rescheduled. + * Note however that a long tick_delay (longer than the remaining time of the + * previous) alarm will also delay the previous alarm. + */ + message m, m_alarm; + clock_t time_left; int s; if (ticks <= 0) return; /* check for robustness */ @@ -16,10 +23,20 @@ long ticks; /* number of ticks to wait */ m.ALRM_EXP_TIME = ticks; /* request message after ticks */ m.ALRM_ABS_TIME = 0; /* ticks are relative to now */ s = _taskcall(SYSTASK, SYS_SYNCALRM, &m); + if (s != OK) return(s); + + receive(HARDWARE,&m_alarm); /* await synchronous alarm */ + + /* Check if we must reschedule the current alarm. */ + if (m.ALRM_TIME_LEFT > 0) { + printf("tick_delay: reschedule alarm\n"); + m.ALRM_EXP_TIME = m.ALRM_TIME_LEFT - ticks; + if (m.ALRM_EXP_TIME <= 0) + m.ALRM_EXP_TIME = 1; + s = _taskcall(SYSTASK, SYS_SYNCALRM, &m); + } - if (OK == s) receive(HARDWARE,&m); /* await synchronous alarm */ return(s); - } diff --git a/tools/Makefile b/tools/Makefile index 31d3873bd..b6eb6c10c 100755 --- a/tools/Makefile +++ b/tools/Makefile @@ -52,6 +52,7 @@ image: programs # rebuild the program or system libraries programs: + cd ../include && $(MAKE) install cd ../kernel && $(MAKE) cd ../servers && $(MAKE) install cd ../drivers && $(MAKE) install