]> oss.titaniummirror.com Git - tinyos-2.x.git/commitdiff
Fixed three bugs:
authorscipio <scipio>
Mon, 28 Dec 2009 23:12:13 +0000 (23:12 +0000)
committerscipio <scipio>
Mon, 28 Dec 2009 23:12:13 +0000 (23:12 +0000)
  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.

tos/lib/net/TrickleTimerImplP.nc

index de0bbe86e8ca918c4c7c46f88c98e3b6e263bb9b..12e9d5bd2a5deefc667015dfd3c772ae8754b29b 100644 (file)
@@ -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 {