1 #include "sysutil.h" 2 #include <minix/timers.h> 3 4 /*===========================================================================* 5 * tickdelay * 6 *===========================================================================*/ 7 int tickdelay(clock_t ticks) 8 { 9 /* This function uses the synchronous alarm to delay for a while. This works 10 * even if a previous synchronous alarm was scheduled, because the remaining 11 * ticks of the previous alarm are returned so that it can be rescheduled. 12 * Note however that a long tick delay (longer than the remaining time of the 13 * previous) alarm will also delay the previous alarm. 14 */ 15 clock_t time_left, uptime; 16 message m; 17 int r, status; 18 19 if (ticks <= 0) return OK; /* check for robustness */ 20 21 /* Set the new alarm while getting the time left on the previous alarm. */ 22 if ((r = sys_setalarm2(ticks, FALSE, &time_left, &uptime)) != OK) 23 return r; 24 25 /* Await synchronous alarm. Since an alarm notification may already have 26 * been dispatched by the time that we set the new alarm, we keep going 27 * until we actually receive an alarm with a timestamp no earlier than the 28 * alarm time we expect. 29 */ 30 while ((r = ipc_receive(CLOCK, &m, &status)) == OK) { 31 if (m.m_type == NOTIFY_MESSAGE && 32 m.m_notify.timestamp >= uptime + ticks) 33 break; 34 } 35 36 /* Check if we must reschedule the previous alarm. */ 37 if (time_left != TMR_NEVER) { 38 if (time_left > ticks) 39 time_left -= ticks; 40 else 41 time_left = 1; /* force an alarm */ 42 43 /* There's no point in returning an error from here.. */ 44 (void)sys_setalarm(time_left, FALSE); 45 } 46 47 return r; 48 } 49