/*
 * FIXME: allow amnt to be specified in time units rather than ticks.
 */
int timed_event_block(spdid_t spdinv, unsigned int amnt)
{
	spdid_t spdid = cos_spd_id();
	struct thread_event *te;
	int block_time;
	event_time_t t;

	if (amnt == 0) return 0;
	/* 
	 * Convert from usec to ticks
	 *
	 * +2 here as we don't know how far through the current clock
	 * tick we are _and_ we don't know how far into the clock tick
	 * the wakeup time is.  The sleep is supposed to be for _at
	 * least_ amnt clock ticks, thus here we are conservative.
	 */
	//amnt = (amnt/(unsigned int)usec_per_tick) + 2;
	/* update: seems like +1 should be enough */
	amnt++;
	
	TAKE(spdid);
	te = te_get(cos_get_thd_id());
	if (NULL == te) BUG();
	assert(EMPTY_LIST(te, next, prev));

	te->thread_id = cos_get_thd_id();
	te->flags &= ~TE_TIMED_OUT;
	te->flags |= TE_BLOCKED;

	ticks = sched_timestamp();
	te->event_expiration = ticks + amnt;
	block_time = ticks;
   	assert(te->event_expiration > ticks);
	t = next_event_time();
	insert_event(te);
	assert(te->next && te->prev && !EMPTY_LIST(te, next, prev));
	RELEASE(spdid);

	if (t != next_event_time()) sched_timeout(spdid, amnt);
	if (-1 == sched_block(spdid, 0)) {
		prints("fprr: sched block failed in timed_event_block.");
	}

	/* we better have been taking off the list! */
	assert(EMPTY_LIST(te, next, prev));
	if (te->flags & TE_TIMED_OUT) return TIMER_EXPIRED;

	/* 
	 * The event has already been removed from event list in
	 * event_expiration by the timeout thread.
	 * 
	 * Minus 1 here as we must report the amount of time we are
	 * sure we waited for.  As we don't know how far into the tick
	 * we were when we slept, and how far the wakeup is into a
	 * tick, we must account for this.
	 */
	return ((int)ticks - block_time - 1); //*usec_per_tick; /* expressed in ticks currently */
}
int periodic_wake_create(spdid_t spdinv, unsigned int period)
{
	struct thread_event *te;
	unsigned short int tid = cos_get_thd_id();
	spdid_t spdid = cos_spd_id();
	event_time_t n, t;
	
	if (period < 1) return -1;

	TAKE(spdid);
	te = te_pget(tid);
	if (NULL == te) BUG();
	if (te->flags & TE_PERIODIC) {
		assert(!EMPTY_LIST(te, next, prev));
		REM_LIST(te, next, prev);
	}
	assert(EMPTY_LIST(te, next, prev));
	te->flags |= TE_PERIODIC;
	te->period = period;
	ticks = sched_timestamp();
	te->event_expiration = n = ticks + period;
	assert(n > ticks);

	t = next_event_time();
	assert(t > ticks);
	insert_pevent(te);
	if (t > n) sched_timeout(spdid, n-ticks);

	RELEASE(spdid);

	return 0;
}
Exemple #3
0
/**
 * Calculate the time until a MUCK event will happen
 *
 * Could be an event, a dump, or a cleanup.  Whichever comes next
 * will determine which time is returned.
 *
 * @return the time until the next MUCK event
 */
time_t
next_muckevent_time(void)
{
    time_t nexttime = 1000L;

    nexttime = MIN(next_event_time(), nexttime);
    nexttime = MIN(next_dump_time(), nexttime);
    nexttime = MIN(next_clean_time(), nexttime);

    return (nexttime);
}
Exemple #4
0
long
next_muckevent_time(void)
{
	long nexttime = 1000L;

	nexttime = mintime(next_event_time(), nexttime);
	nexttime = mintime(next_dump_time(), nexttime);
	nexttime = mintime(next_clean_time(), nexttime);

	return (nexttime);
}
Exemple #5
0
time_t
next_muckevent_time(void)
{
    time_t nexttime = 1000L;

    nexttime = mintime(next_event_time(), nexttime);
    nexttime = mintime(next_dump_time(), nexttime);
    nexttime = mintime(next_clean_time(), nexttime);
#ifdef RWHO
    nexttime = mintime(next_rwho_time(), nexttime);
#endif
#ifdef MUD
    nexttime = mintime(next_mud_time(), nexttime);
    nexttime = mintime(next_mob_time(), nexttime);
#endif

    return (nexttime);
}
static void start_timer_thread(void)
{
	spdid_t spdid = cos_spd_id();
	unsigned int tick_freq;

	INIT_LIST(&events, next, prev);
	events.thread_id = 0;
	INIT_LIST(&periodic, next, prev);
	periodic.thread_id = 0;

	cos_vect_init_static(&thd_evts);
	cos_vect_init_static(&thd_periodic);

	sched_timeout_thd(spdid);
	tick_freq = sched_tick_freq();
	assert(tick_freq == 100);
	ticks = sched_timestamp();
	/* currently timeouts are expressed in ticks, so we don't need this */
//	usec_per_tick = USEC_PER_SEC/tick_freq;
	cyc_per_tick = sched_cyc_per_tick();
	//	printc("cyc_per_tick = %lld\n", cyc_per_tick);

	/* When the system boots, we have no pending waits */
	assert(EMPTY_LIST(&events, next, prev));
	sched_block(spdid, 0);
	/* Wait for events, then act on expired events.  Loop. */
	while (1) {
		event_time_t next_wakeup;

		cos_mpd_update(); /* update mpd config given this
				   * thread is now in this component
				   * (no dependency if we are in the
				   * same protection domain as the
				   * scheduler) */
		ticks = sched_timestamp();
		if (sched_component_take(spdid)) {
			prints("fprr: scheduler lock failed!!!");
			BUG();
		}
		event_expiration(ticks);
		next_wakeup = next_event_time();

		/* Are there no pending events??? */
		if (TIMER_NO_EVENTS == next_wakeup) {
			if (sched_component_release(spdid)) {
				prints("fprr: scheduler lock release failed!!!");
				BUG();
			}

			sched_block(spdid, 0);
		} else {
			unsigned int wakeup;

			assert(next_wakeup > ticks);
			wakeup = (unsigned int)(next_wakeup - ticks);
			if (sched_component_release(spdid)) {
				prints("fprr: scheduler lock release failed!!!");
				BUG();
			}
			sched_timeout(spdid, wakeup);
		}
	}
}