/* * 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; }
/** * 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); }
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); }
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); } } }