From: idgay Date: Fri, 11 Aug 2006 21:03:52 +0000 (+0000) Subject: simplify logic X-Git-Tag: tinyos/2.0.1~286 X-Git-Url: https://oss.titaniummirror.com/gitweb/?a=commitdiff_plain;h=2001a3bff5d6dcf0611e3cc155e8297770057d7f;p=tinyos-2.x.git simplify logic --- diff --git a/tos/lib/timer/TransformAlarmCounterC.nc b/tos/lib/timer/TransformAlarmCounterC.nc index 69da7150..d6341b8a 100644 --- a/tos/lib/timer/TransformAlarmCounterC.nc +++ b/tos/lib/timer/TransformAlarmCounterC.nc @@ -146,7 +146,6 @@ implementation { atomic { - m_upper++; if ((m_upper & OVERFLOW_MASK) == 0) signal Counter.overflow(); @@ -178,31 +177,23 @@ implementation void set_alarm() { - to_size_type now = call Counter.get(), expires, remaining; - - /* m_t0 is assumed to be in the past. If it's > now, we assume - that time has wrapped around */ - - expires = m_t0 + m_dt; - - /* The cast is necessary to get correct wrap-around arithmetic */ - remaining = (to_size_type)(expires - now); + to_size_type now = call Counter.get(), elapsed = now - m_t0, remaining; - /* if (expires <= now) remaining = 0; in wrap-around arithmetic */ - if (m_t0 <= now) - { - if (expires >= m_t0 && // if it wraps, it's > now - expires <= now) - remaining = 0; - } + m_skip_overflows = 0; + if (elapsed >= m_dt) + { + remaining = 0; + m_t0 += m_dt; + m_dt = 0; + } else - { - if (expires >= m_t0 || // didn't wrap so < now - expires <= now) - remaining = 0; - } + { + remaining = m_dt - elapsed; - if (remaining > MAX_DELAY * 2) + /* MAX_DELAY is 1/2 an underlying counter overflow time. Just count + overflows if the timer is far in the future, and we'll set an + alarm once we're close to the deadline. */ + if (remaining > MAX_DELAY * 2) { if (remaining >= MAX_DELAY * 2 * (to_size_type)256) m_skip_overflows = 255; @@ -210,20 +201,19 @@ implementation m_skip_overflows = remaining / (MAX_DELAY * 2); return; } - else - m_skip_overflows = 0; - if (remaining > MAX_DELAY) + if (remaining > MAX_DELAY) { m_t0 = now + MAX_DELAY; m_dt = remaining - MAX_DELAY; remaining = MAX_DELAY; } - else + else { m_t0 += m_dt; m_dt = 0; } + } call AlarmFrom.startAt((from_size_type)now << bit_shift_right, (from_size_type)remaining << bit_shift_right); } diff --git a/tos/lib/timer/VirtualizeTimerC.nc b/tos/lib/timer/VirtualizeTimerC.nc index 8b6bea25..b36e75a8 100644 --- a/tos/lib/timer/VirtualizeTimerC.nc +++ b/tos/lib/timer/VirtualizeTimerC.nc @@ -55,41 +55,33 @@ implementation } Timer_t; Timer_t m_timers[NUM_TIMERS]; - - enum { - /* bitmask */ - S_TIMER_RUNNING = 1, - S_TIMER_CHANGED = 2 - }; - bool state; + bool m_timers_changed; task void executeTimersNow(); - void executeTimers(uint32_t then) + void executeTimers() { - int32_t min_remaining = (1UL<<31)-1; //max signed int32_t + /* This code supports a maximum dt of MAXINT. If min_remaining and + remaining were switched to uint32_t, and the logic changed a + little, dt's up to 2^32-1 should work (but at a slightly higher + runtime cost). */ + uint32_t now = call TimerFrom.getNow(); + int32_t min_remaining = (1UL << 31) - 1; /* max int32_t */ bool min_remaining_isset = FALSE; - int num; + uint8_t num; - /* We always come here with the timer stopped */ - state = 0; + call TimerFrom.stop(); + m_timers_changed = FALSE; - for(num=0; numisrunning) { - // Calculate "remaining" before the timer is fired. If a timer - // restarts itself in a fired event, then we 1) need a consistent - // "remaining" value to work with, and no worries because 2) all - // start commands post executeTimersNow, so the timer will be - // recomputed later, anyway. + uint32_t elapsed = now - timer->t0; - uint32_t elapsed = then - timer->t0; - int32_t remaining = timer->dt - elapsed; - - if (remaining <= 0) + if (elapsed >= timer->dt) { if (timer->isoneshot) { @@ -97,70 +89,52 @@ implementation } else { - // The remaining time is non-positive (the timer had fired). - // So add dt to convert it to remaining for the next event. + // Update timer for next event timer->t0 += timer->dt; - remaining += timer->dt; + // Update elapsed so we compute the time of the next event + elapsed -= timer->dt; } signal Timer.fired[num](); } - // check isrunning in case the timer was stopped in the fired + // Check isrunning in case the timer was stopped in the fired // event or this was a one shot timer; note that a one shot // timer that was restarted in its fired event will push us - // through here with remaining <= 0, but we're already scheduled - // an executeTimersTask in that case (and suppressed setting - // TimerFrom) + // through here with a value of remaining <= 0. But we're + // already scheduled an executeTimersNow in that case (and + // suppressed setting TimerFrom) if (timer->isrunning) { + int32_t remaining = timer->dt - elapsed; + if (remaining < min_remaining) - min_remaining = remaining; - min_remaining_isset = TRUE; + { + min_remaining = remaining; + min_remaining_isset = TRUE; + } } } } - if (!(state & S_TIMER_CHANGED) && min_remaining_isset) + if (!m_timers_changed && min_remaining_isset) { if (min_remaining <= 0) post executeTimersNow(); else - { - call TimerFrom.startOneShotAt(then, min_remaining); - state |= S_TIMER_RUNNING; - } + call TimerFrom.startOneShotAt(now, min_remaining); } } event void TimerFrom.fired() { - executeTimers(call TimerFrom.gett0() + call TimerFrom.getdt()); + executeTimers(); } task void executeTimersNow() { - /* If we set a timer, try and stop it. But if it believes it's - not running, that means that the execution of its fired event - is pending, so we: - - don't need to call executeTimers (it will happen soon) - - we must not call executeTimers, because that would change the - timer's setting, confusing the pending call to TimerFrom.fired - (it would call executeTimers with an incorrect "then" - parameter) - We need to use an atomic section even though it's a "timer", - because it's based on an underlying alarm, whose transitions - are asynchronous (yuck?) - */ - if (state & S_TIMER_RUNNING) - atomic - { - if (!call TimerFrom.isRunning()) - return; - call TimerFrom.stop(); - } - executeTimers(call TimerFrom.getNow()); + executeTimers(); } void startTimer(uint8_t num, uint32_t t0, uint32_t dt, bool isoneshot) @@ -170,7 +144,7 @@ implementation timer->dt = dt; timer->isoneshot = isoneshot; timer->isrunning = TRUE; - state |= S_TIMER_CHANGED; + m_timers_changed = TRUE; post executeTimersNow(); }