Пример #1
0
// Similar to cv_wait(), except that it returns -1 without the condition
// being signaled after the timeout time has been reached.
//
// timeout     A time, in absolute ticks since boot, when cv_timedwait()
//             should return.
clock_t cv_timedwait(kcondvar_t * cv, kmutex_t * m, clock_t timeout)
{
    struct timespec abstime;

    // All the callers of cv_timedwait calculate the timeout by adding
    // ticks to ddi_get_lbolt(), which is in usec.
    abstime.tv_sec = USEC_TO_SEC(timeout);
    abstime.tv_nsec = USEC_TO_NSEC(timeout - SEC_TO_USEC(abstime.tv_sec));

    int error = pthread_cond_timedwait(&cv->cond, &m->mutex, &abstime);
    switch (error) {
    case 0:
        // Update the mutex holder since we now own the lock.
        m->holder = pthread_to_kthread(pthread_self());

        // Return >0 on signalled wakeup.
        return 1;
    case ETIMEDOUT:
        // Update the mutex holder since we now own the lock.
        m->holder = pthread_to_kthread(pthread_self());

        // Return -1 on timeout.
        return -1;
    default:
        // And this only happens on a programmer error.
        panic("pthread_cond_timedwait() failed: %s (%d)",
                strerror(error), error);
    }
}
Пример #2
0
// Unlike cv_timedwait(), this timeout is relative to now.
clock_t cv_timedwait_hires(
        kcondvar_t * cv, kmutex_t * m, hrtime_t timeout, hrtime_t resolution, int flag)
{
    VERIFY0(flag); // We don't support flags.
    clock_t expiration = ddi_get_lbolt() + timeout;;

    if (resolution > 1) {
        expiration = (expiration / resolution) * resolution;
    }

    // clock_t is ticks (usec) and hrtime_t is nsec.
    return cv_timedwait(cv, m, USEC_TO_NSEC(expiration));
}
Пример #3
0
static ssize_t hrt_write(struct file *filp, const char __user *buff,
		size_t count, loff_t *f_pos)
{
	char str[16];
	ssize_t status;
	unsigned long usecs;

	if (count == 0)
		return 0;

	if (down_interruptible(&hrt.sem))
		return -ERESTARTSYS;

	if (count > 8)
		count = 8; 

	str[count] = 0;

	if (copy_from_user(str, buff, count)) {
		printk(KERN_ALERT "Error copy_from_user\n");
		status = -EFAULT;
		goto hrt_write_done;
	}

	usecs = simple_strtoul(str, NULL, 10);

	if (usecs < 1 || usecs > 500000) {
		printk(KERN_ALERT "invalid delay %lu\n", usecs);
		status = -EINVAL;
		goto hrt_write_done;
	}
	
	hrt.delay = ktime_set(0, USEC_TO_NSEC(usecs));

	do_toggle_test();	

	status = count;
	*f_pos += count;

hrt_write_done:

	up(&hrt.sem);

	return status;
}
Пример #4
0
/*
 * this routine serves two purposes:
 *   1. report progress
 *   2. check for deadlocks
 */
void *reporter(void *arg)
{
	int status;
	int end = 0;
	struct timespec ts;

	ts.tv_sec = 0;
	ts.tv_nsec = USEC_TO_NSEC(report_interval);

	tsnorm(&ts);

	if (duration >= 0)
		end = duration + time(NULL);

	/* sleep initially to let everything get up and running */
	status = clock_nanosleep(CLOCK_MONOTONIC, 0, &ts, NULL);
	if (status) {
		error("from clock_nanosleep: %s\n", strerror(status));
		return NULL;
	}

	debug("reporter: starting report loop\n");
	info("Press Control-C to stop test\nCurrent Inversions: \n");

	for (;;) {
		pthread_mutex_lock(&shutdown_mtx);
		if (shutdown) {
			pthread_mutex_unlock(&shutdown_mtx);
			break;
		}
		pthread_mutex_unlock(&shutdown_mtx);

		/* wait for our reporting interval */
		status = clock_nanosleep(CLOCK_MONOTONIC, 0, &ts, NULL);
		if (status) {
			error("from clock_nanosleep: %s\n", strerror(status));
			break;
		}

		/* check for signaled shutdown */
		if (!quiet) {
			pthread_mutex_lock(&shutdown_mtx);
			if (shutdown == 0) {
				fputs(UP_ONE, stdout);
				printf("Current Inversions: %lu\n",
						total_inversions());
			}
		}
		pthread_mutex_unlock(&shutdown_mtx);

		/* if we specified a duration, see if it has expired */
		if (end && time(NULL) > end) {
			info("duration reached (%d seconds)\n", duration);
			set_shutdown_flag();
			continue;
		}
		/* check for a pending SIGINT */
		if (pending_interrupt()) {
			info("Keyboard Interrupt!\n");
			break;
		}
		/* check watchdog stuff */
		if ((watchdog_check())) {
			error("reporter stopping due to watchdog event\n");
			set_shutdown_flag();
			break;
		}
		/* clear watchdog counters */
		watchdog_clear();

	}
	debug("reporter: finished\n");
	set_shutdown_flag();
	return NULL;
}