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.
event void Timer.fired() {
uint8_t i;
uint32_t dt = call Timer.getdt();
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) {
for (i = 0; i < count; i++) {
uint32_t remaining = trickles[i].time;
if (remaining != 0) {
if (remaining == 0) {
if (trickles[i].count < k) {
atomic {
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 Pending.set(i);
}
post timerTask();
}
generateTime(i);
/* Note that this logic is not the exact trickle algorithm.
generateTime(i);
/* Note that this logic is not the exact trickle algorithm.
*/
trickles[i].count = 0;
}
*/
trickles[i].count = 0;
}
- else {
- trickles[i].time = remaining;
- }
for (i = 0; i < count; i++) {
uint32_t timeRemaining = trickles[i].time;
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;
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;
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 {
call Timer.startOneShot(timerVal);
}
else {