static void scheduler_prepare_events(scheduler_t *s) { struct timeval diff; struct timeval now; event_t *event; FD_ZERO(&s->read_fds); FD_ZERO(&s->write_fds); FD_ZERO(&s->except_fds); s->max_fd = -1; s->timeout = TV_SECS(SCHEDULER_MAX_TIMEOUT); gettimeofday(&now, NULL); scheduler_for_each_event(s, event) { if (event->masked || event->dead) continue; if (event->mode & SCHEDULER_POLL_FD && (fcntl(event->fd, F_GETFL) < 0) && errno == EBADF) { EPRINTF("EBADF: Marking event dead, id: %d", event->id); event->dead = 1; continue; } if (event->mode & SCHEDULER_POLL_READ_FD) { FD_SET(event->fd, &s->read_fds); s->max_fd = MAX(event->fd, s->max_fd); } if (event->mode & SCHEDULER_POLL_WRITE_FD) { FD_SET(event->fd, &s->write_fds); s->max_fd = MAX(event->fd, s->max_fd); } if (event->mode & SCHEDULER_POLL_EXCEPT_FD) { FD_SET(event->fd, &s->except_fds); s->max_fd = MAX(event->fd, s->max_fd); } if (event->mode & SCHEDULER_POLL_TIMEOUT && !TV_IS_INF(event->timeout)) { TV_SUB(event->deadline, now, diff); if (TV_AFTER(diff, TV_ZERO)) s->timeout = TV_MIN(s->timeout, diff); else s->timeout = TV_ZERO; } } s->timeout = TV_MIN(s->timeout, s->max_timeout); }
/* * Do a `read wait': select for reading from stdin, with timeout *tvp. * On return, modify *tvp to reflect the amount of time spent waiting. * It will be positive only if input appeared before the time ran out; * otherwise it will be zero or perhaps negative. * * If tvp is nil, wait forever, but return if select is interrupted. * * Return 0 => no input, 1 => can read() from stdin */ int rwait(struct timeval *tvp) { int i, ninq, timeout; struct timeval starttv, endtv; #define NILTZ ((struct timezone *)0) if (tvp) { (void) gettimeofday(&starttv, NILTZ); endtv = *tvp; timeout = tvp->tv_usec / 1000; } else timeout = 1000; /* * We don't have select() or poll() as for now. * This is replaced by polling TTY input queue via ioctl(). */ for (i = 0; i < timeout; i++) { ioctl(1, TIOCINQ, &ninq); if (ninq > 0) break; timer_sleep(1, 0); /* wait 1ms */ } if (i >= timeout) { /* timed out */ if (tvp == NULL) return (-1); else { tvp->tv_sec = 0; tvp->tv_usec = 0; return (0); } } if (tvp) { /* since there is input, we may not have timed out */ (void) gettimeofday(&endtv, NILTZ); TV_SUB(&endtv, &starttv); TV_SUB(tvp, &endtv); /* adjust *tvp by elapsed time */ } return (1); }
int nanosleep ( const struct timespec *rqtp, /* time to delay */ struct timespec *rmtp /* premature wakeup (NULL=no result) */ ) { int status; /* int oldErrno; */ ULONG delayTicks; struct timespec then; struct timespec now; int returnStatus; int savtype; if (rqtp == NULL || !TV_VALID(*rqtp)) { errno = EINVAL; return (ERROR); } if (TV_ISZERO(*rqtp)) return (OK); if (_func_pthread_setcanceltype != NULL) { _func_pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &savtype); } (void)clockLibInit (); /* make sure clock "running" */ (void)clock_gettime (CLOCK_REALTIME, &then); TV_CONVERT_TO_TICK (delayTicks, *rqtp); /* return's 1 (RESTART) if interrupted sleep */ status = taskDelay (delayTicks); if (status == 0) returnStatus = 0; else returnStatus = -1; if (rmtp != NULL) { (void)clock_gettime (CLOCK_REALTIME, &now); TV_SUB (now, then); /* make time relative to start */ if (TV_LT(now, *rqtp)) { TV_SET(*rmtp, *rqtp); TV_SUB(*rmtp, now); } else TV_ZERO((*rmtp)); } if (_func_pthread_setcanceltype != NULL) { _func_pthread_setcanceltype(savtype, NULL); } return (returnStatus); }
int timer_settime ( timer_t timerid, /* timer ID */ int flags, /* absolute or relative */ const struct itimerspec *value, /* time to be set */ struct itimerspec *ovalue /* previous time set (NULL=no result) */ ) { struct timespec now; struct timespec timerExpire; /* absolute time that timer will go off */ ULONG delayTicks; if (timerid == NULL) { errno = EINVAL; return (ERROR); } if (timerid->clock_id != CLOCK_REALTIME || !TV_VALID(value->it_value)) { errno = EINVAL; return (ERROR); } if (ovalue != NULL) { /* if timer is disarmed, simply set value to 0 */ if (timerid->active == FALSE) { ovalue->it_value.tv_sec = 0; ovalue->it_value.tv_nsec = 0; } else { /* get current time */ if (clock_gettime (CLOCK_REALTIME, &now) == ERROR) return (ERROR);; /* use time stamp and get absolute time that timer will go off */ timerExpire.tv_sec = timerid->timeStamp.tv_sec + timerid->exp.it_value.tv_sec; timerExpire.tv_nsec = timerid->timeStamp.tv_nsec + timerid->exp.it_value.tv_nsec; TV_NORMALIZE (timerExpire); /* compute difference using current time */ ovalue->it_value.tv_sec = timerExpire.tv_sec - now.tv_sec; ovalue->it_value.tv_nsec = timerExpire.tv_nsec - now.tv_nsec; TV_NORMALIZE (ovalue->it_value); } /* get reload value */ ovalue->it_interval.tv_sec = timerid->exp.it_interval.tv_sec; ovalue->it_interval.tv_nsec = timerid->exp.it_interval.tv_nsec; TV_NORMALIZE (ovalue->it_interval); } if (TV_ISZERO(value->it_value)) { if (timerid->active) { timerid->active = FALSE; wdCancel (timerid->wdog); } return (OK); } TV_SET(timerid->exp.it_interval, value->it_interval); TV_SET(timerid->exp.it_value, value->it_value); if (flags == TIMER_ABSTIME) { /* convert current to relative time */ (void) clock_gettime (CLOCK_REALTIME, &now); /* could be in the past */ if (TV_GT(now, timerid->exp.it_value)) { TV_ZERO(timerid->exp.it_value); } else { TV_SUB(timerid->exp.it_value, now); } /* time stamp when timer is armed */ TV_SET (timerid->timeStamp, now); } else /* time stamp when timer is armed */ (void) clock_gettime (CLOCK_REALTIME, &(timerid->timeStamp)); TV_CONVERT_TO_TICK (delayTicks, timerid->exp.it_value); if (timerid->active) wdCancel (timerid->wdog); else timerid->active = TRUE; wdStart (timerid->wdog, delayTicks, (FUNCPTR)timerWdHandler, (int)timerid); return (OK); }