From: scipio Date: Mon, 28 Dec 2009 23:12:13 +0000 (+0000) Subject: Fixed three bugs: X-Git-Tag: rc_6_tinyos_2_1_1~82 X-Git-Url: https://oss.titaniummirror.com/gitweb/?p=tinyos-2.x.git;a=commitdiff_plain;h=4d7a0136de287198f6bc9640625216377f700f0d Fixed three bugs: 1) Peter Bigot @ Rincon noted that the changed flag was incorrectly cleared and set, such that elapsed time would not be considered in trickle timers. This caused trickle timers to fire late. 2) The possibility of a subtraction wraparound could cause timers to have very large values and fire very late. 3) A repetition of subtracting the elapsed time (in both the fired event and in adjustTime) would cause timers to fire early. --- diff --git a/tos/lib/net/TrickleTimerImplP.nc b/tos/lib/net/TrickleTimerImplP.nc index de0bbe86..12e9d5bd 100644 --- a/tos/lib/net/TrickleTimerImplP.nc +++ b/tos/lib/net/TrickleTimerImplP.nc @@ -168,7 +168,7 @@ implementation { event void Timer.fired() { uint8_t i; uint32_t dt = call Timer.getdt(); - + dbg("Trickle", "Trickle Sub-timer fired\n"); for (i = 0; i < count; i++) { uint32_t remaining = trickles[i].time; if (remaining != 0) { @@ -176,11 +176,12 @@ implementation { if (remaining == 0) { if (trickles[i].count < k) { atomic { + dbg("Trickle", "Trickle: mark timer %hhi as pending\n", i); call Pending.set(i); } post timerTask(); } - + call Changed.set(i); generateTime(i); /* Note that this logic is not the exact trickle algorithm. @@ -191,9 +192,6 @@ implementation { */ trickles[i].count = 0; } - else { - trickles[i].time = remaining; - } } } adjustTimer(); @@ -213,26 +211,42 @@ implementation { for (i = 0; i < count; i++) { uint32_t timeRemaining = trickles[i].time; - if (timeRemaining != 0) { - atomic { - if (!call Changed.get(i)) { - call Changed.clear(i); + dbg("Trickle", "Adjusting: timer %hhi (%u)\n", i, timeRemaining); + + if (timeRemaining == 0) { // Not running, go to next timer + continue; + } + + atomic { + if (!call Changed.get(i)) { + if (timeRemaining > elapsed) { + dbg("Trickle", " not changed, elapse time remaining to %u.\n", trickles[i].time - elapsed); timeRemaining -= elapsed; + trickles[i].time -= elapsed; + } + else { // Time has already passed, so fire immediately + dbg("Trickle", " not changed, ready to elapse, fire immediately\n"); + timeRemaining = 1; + trickles[i].time = 1; } } - if (!set) { - lowest = timeRemaining; - set = TRUE; - } - else if (timeRemaining < lowest) { - lowest = timeRemaining; + else { + dbg("Trickle", " changed, fall through.\n"); + call Changed.clear(i); } } + if (!set) { + lowest = timeRemaining; + set = TRUE; + } + else if (timeRemaining < lowest) { + lowest = timeRemaining; + } } + if (set) { uint32_t timerVal = lowest; - timerVal = timerVal; - dbg("Trickle", "Starting time with time %u.\n", timerVal); + dbg("Trickle", "Starting sub-timer with interval %u.\n", timerVal); call Timer.startOneShot(timerVal); } else {