int spin_check(spin_t *s)
{
	/* Check whether a timeout has taken place. Return TRUE if the caller
	 * should continue spinning, and FALSE if a timeout has occurred. The
	 * implementation assumes that it is okay to spin a little bit too long
	 * (up to a full clock tick extra).
	 */
	u64_t cur_tsc, tsc_delta;
	clock_t now, micro_delta;

	switch (s->s_state) {
	case STATE_INIT:
		s->s_state = STATE_BASE_TS;
		break;

	case STATE_BASE_TS:
		s->s_state = STATE_TS;
		read_frclock_64(&s->s_base_tsc);
		break;

	case STATE_TS:
		read_frclock_64(&cur_tsc);
		tsc_delta = delta_frclock_64(s->s_base_tsc, cur_tsc);
		micro_delta = frclock_64_to_micros(tsc_delta);

		if (micro_delta >= s->s_usecs) {
			s->s_timeout = TRUE;
			return FALSE;
		}

		if (micro_delta >= TSC_SPIN) {
			s->s_usecs -= micro_delta;
			s->s_base_uptime = getticks();
			s->s_state = STATE_UPTIME;
		}

		break;

	case STATE_UPTIME:
		now = getticks();

		/* We assume that sys_hz() caches its return value. */
		micro_delta = ((now - s->s_base_uptime) * 1000 / sys_hz()) *
			1000;

		if (micro_delta >= s->s_usecs) {
			s->s_timeout = TRUE;
			return FALSE;
		}

		break;

	default:
		panic("spin_check: invalid state %d", s->s_state);
	}

	return TRUE;
}
Esempio n. 2
0
static int
keep_displaying_restarted()
{
	u64_t delta;
	u32_t micro_delta;

	read_frclock_64(&has_restarted_t2);
	delta = delta_frclock_64(has_restarted_t1, has_restarted_t2);
	micro_delta = frclock_64_to_micros(delta);

#define DISPLAY_1SEC 1000000	/* 1 second in microseconds */
	if (micro_delta < DISPLAY_1SEC) {
		return 1;
	}

	has_restarted = 0;
	return 0;
}