Пример #1
0
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);
}
Пример #2
0
/*
 * 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);
}
Пример #3
0
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);
    }
Пример #4
0
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);
    }