예제 #1
0
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;
}
예제 #2
0
파일: sched.c 프로젝트: tdz/opsys
/**
 * This function is the high-level entry point for the thread-schedule
 * interrupt. It triggers switches to other runnable threads.
 */
static timeout_t
alarm_handler(struct alarm* alarm)
{
    sched_switch(cpuid());

    return sched_timeout();
}
예제 #3
0
/*
 * 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 */
}
예제 #4
0
파일: s_cstub.c 프로젝트: songjiguo/CMon
int __sg_sched_timeout(spdid_t spdid, unsigned long amnt)
{
	/* printc("ser: sched_wakeup (thd %d)\n", cos_get_thd_id()); */
	int ret;
#ifdef LOG_MONITOR
	evt_enqueue(cos_get_thd_id(), spdid, cos_spd_id(), FN_SCHED_TIMEOUT, amnt, EVT_SINV);
#endif
	ret = sched_timeout(spdid, amnt);
#ifdef LOG_MONITOR
	evt_enqueue(cos_get_thd_id(), cos_spd_id(), spdid, FN_SCHED_TIMEOUT, amnt, EVT_SRET);
#endif
	return ret;
}
예제 #5
0
파일: s_cstub.c 프로젝트: songjiguo/C3
int __sg_sched_timeout(spdid_t spdid, unsigned long amnt)
{
	/* printc("ser: sched_wakeup (thd %d)\n", cos_get_thd_id()); */
	int ret;
#ifdef LOG_MONITOR
	monevt_enqueue(cos_spd_id(), 15, 0);
#endif
	ret = sched_timeout(spdid, amnt);
#ifdef LOG_MONITOR
	monevt_enqueue(0, 15, 0);
#endif
	return ret;
}
예제 #6
0
파일: sched.c 프로젝트: tdz/opsys
/**
 * \brief init scheduler
 * \param[in] idle the initial idle thread
 * \return 0 on success, or a negative error code otherwise
 *
 * This initializes the scheduler. The passed thread is the idle
 * thread. It is added to the thread list automatically.
 */
int
sched_init(struct tcb* idle)
{
    assert(idle);

    for (size_t i = 0; i < ARRAY_NELEMS(g_current_thread); ++i) {
        g_current_thread[i] = idle;
    }

    for (size_t i = 0; i < ARRAY_NELEMS(g_thread); ++i) {
        list_init_head(g_thread + i);
    }

    alarm_init(&g_alarm, alarm_handler);

    int res = timer_add_alarm(&g_alarm, sched_timeout());
    if (res < 0) {
        goto err_timer_add_alarm;
    }

    res = sched_add_thread(idle, 0);
    if (res < 0) {
        goto err_sched_add_thread;
    }

    return 0;

err_sched_add_thread:
    timer_remove_alarm(&g_alarm);
err_timer_add_alarm:
    for (size_t i = ARRAY_NELEMS(g_current_thread); i;) {
        --i;
        g_current_thread[i] = NULL;
    }
    return res;
}
예제 #7
0
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);
		}
	}
}