[Tinyos-2-commits] CVS: tinyos-2.x/tos/lib/timer VirtualizeAlarmC.nc, 1.2, 1.3 VirtualizeTimerC.nc, 1.2, 1.3

David Gay idgay at users.sourceforge.net
Mon Aug 7 15:18:23 PDT 2006


Update of /cvsroot/tinyos/tinyos-2.x/tos/lib/timer
In directory sc8-pr-cvs10.sourceforge.net:/tmp/cvs-serv15238

Modified Files:
	VirtualizeAlarmC.nc VirtualizeTimerC.nc 
Log Message:
move Cory's fixes from the old devel branch


Index: VirtualizeAlarmC.nc
===================================================================
RCS file: /cvsroot/tinyos/tinyos-2.x/tos/lib/timer/VirtualizeAlarmC.nc,v
retrieving revision 1.2
retrieving revision 1.3
diff -C2 -d -r1.2 -r1.3
*** VirtualizeAlarmC.nc	12 Jul 2006 17:02:31 -0000	1.2
--- VirtualizeAlarmC.nc	7 Aug 2006 22:18:21 -0000	1.3
***************
*** 45,156 ****
    };
  
!   size_type m_t0[NUM_ALARMS];
!   size_type m_dt[NUM_ALARMS];
!   bool m_isset[NUM_ALARMS];
  
!   command error_t Init.init()
!   {
      return SUCCESS;
    }
  
!   void setAlarm(size_type now)
!   {
!     size_type t0 = 0;
!     size_type dt = 0;
!     bool isNotSet = TRUE;
!     uint8_t id;
  
!     for(id=0; id<NUM_ALARMS; id++)
!     {
!       if (m_isset[id])
!       {
!         size_type elapse = now - m_t0[id];
!         if (m_dt[id] <= elapse)
!         {
!           m_t0[id] += m_dt[id];
!           m_dt[id] = 0;
!         }
!         else
!         {
!           m_t0[id] = now;
!           m_dt[id] -= elapse;
          }
  
!         if (isNotSet || (m_dt[id] < dt))
!         {
!           t0 = m_t0[id];
!           dt = m_dt[id];
!           isNotSet = FALSE;
          }
        }
      }
  
!     if (isNotSet)
!       call AlarmFrom.stop();
!     else
!       call AlarmFrom.startAt(t0, dt);
    }
!   
    // basic interface
!   async command void Alarm.start[uint8_t id](size_type dt)
!   {
!     call Alarm.startAt[id](call AlarmFrom.getNow(), dt);
    }
  
!   async command void Alarm.stop[uint8_t id]()
!   {
!     atomic
!     {
!       m_isset[id] = FALSE;
!       setAlarm(call AlarmFrom.getNow());
!     }
    }
  
!   async event void AlarmFrom.fired()
!   {
!     atomic
!     {
!       uint8_t id;
!       for(id=0; id<NUM_ALARMS; id++)
!       {
!         if (m_isset[id] && (m_dt[id] == 0))
!         {
!           m_isset[id] = FALSE;
!           signal Alarm.fired[id]();
!         }
!       }
!       setAlarm(call AlarmFrom.getNow());
      }
    }
  
    // extended interface
!   async command bool Alarm.isRunning[uint8_t id]()
!   {
!     return m_isset[id];
    }
  
!   async command void Alarm.startAt[uint8_t id](size_type t0, size_type dt)
!   {
!     atomic
!     {
!       m_t0[id] = t0;
!       m_dt[id] = dt;
!       m_isset[id] = TRUE;
!       setAlarm(t0);
      }
    }
  
!   async command size_type Alarm.getNow[uint8_t id]()
!   {
      return call AlarmFrom.getNow();
    }
  
!   async command size_type Alarm.getAlarm[uint8_t id]()
!   {
!     atomic return m_t0[id]+m_dt[id];
    }
  
!   default async event void Alarm.fired[uint8_t id]() { }
! 
  }
  
--- 45,189 ----
    };
  
!   typedef struct {
!     size_type t0;
!     size_type dt;
!   } alarm_t;
  
!   // css 26 jul 2006: All computations with respect to the current time ("now")
!   // require that "now" is (non-strictly) monotonically increasing.  Calling
!   // setNextAlarm within Alarm.start within Alarm.fired within signalAlarms
!   // breaks this monotonicity requirements when "now" is cached at the start of
!   // the function.  Two ways around this: 1) refresh "now" each time it is
!   // used, or 2) use the is_signaling flag to prevent setNextAlarm from being
!   // called inside signalAlarms.  The latter is generally more efficient by
!   // preventing redundant calls to setNextAlarm at the expense of an extra byte
!   // of RAM, so that's what the code does now.  Update: option 2 is
!   // unacceptable because an Alarm.start could be called within some other
!   // Alarm.fired, which can break monotonicity in now.
! 
!   // A struct of member variables so only one memset is called for init.
!   struct {
!     alarm_t alarm[NUM_ALARMS];
!     bool isset[NUM_ALARMS];
!     bool is_signaling;
!   } m;
! 
!   command error_t Init.init() {
!     memset( &m, 0, sizeof(m) );
      return SUCCESS;
    }
  
!   void setNextAlarm() {
!     if( !m.is_signaling ) {
!       // css 25 jul 2006: To help prevent various problems with overflow, the
!       // elapsed time from t0 for a particular alarm is calculated as
!       // elapsed=now-t0 then dt-=elapsed and t0=now.  However, this means that
!       // now must be a monotonically increasing value with each call to
!       // setNextAlarm -- overflow in now is okay, but passing in older values of
!       // now=t0 for some arbitrary t0 is not okay, which is what the previous
!       // version of setAlarm did.
  
!       const size_type now = call AlarmFrom.getNow();
!       const alarm_t* pEnd = m.alarm+NUM_ALARMS;
!       bool isset = FALSE;
!       alarm_t* p = m.alarm;
!       bool* pset = m.isset;
!       size_type dt = ((size_type)0)-((size_type)1);
! 
!       for( ; p!=pEnd; p++,pset++ ) {
!         if( *pset ) {
!           size_type elapsed = now - p->t0;
!           if( p->dt <= elapsed ) {
!             p->t0 += p->dt;
!             p->dt = 0;
!           }
!           else {
!             p->t0 = now;
!             p->dt -= elapsed;
!           }
! 
!           if( p->dt <= dt ) {
!             dt = p->dt;
!             isset = TRUE;
!           }
          }
+       }
  
!       if( isset ) {
!         // css 25 jul 2006: If dt is big, then wait half of dt.  This helps
!         // significantly reduce the chance of overflow in the elapsed calculation
!         // for the alarm.  "big" is if the most signficant bit in dt is set.
! 
!         if( dt & (((size_type)1) << (8*sizeof(size_type)-1)) )
!           dt >>= 1;
! 
!         call AlarmFrom.startAt( now, dt );
!       }
!       else {
!         call AlarmFrom.stop();
!       }
!     }
!   }
!   
!   void signalAlarms() {
!     uint8_t id;
! 
!     m.is_signaling = TRUE;
! 
!     for( id=0; id<NUM_ALARMS; id++ ) {
!       if( m.isset[id] ) {
!         size_type elapsed = call AlarmFrom.getNow() - m.alarm[id].t0;
!         if( m.alarm[id].dt <= elapsed ) {
!           m.isset[id] = FALSE;
!           signal Alarm.fired[id]();
          }
        }
      }
  
!     m.is_signaling = FALSE;
    }
! 
! 
    // basic interface
!   async command void Alarm.start[uint8_t id]( size_type dt ) {
!     call Alarm.startAt[id]( call AlarmFrom.getNow(), dt );
    }
  
!   async command void Alarm.stop[uint8_t id]() {
!     atomic m.isset[id] = FALSE;
    }
  
!   async event void AlarmFrom.fired() {
!     atomic {
!       signalAlarms();
!       setNextAlarm();
      }
    }
  
+ 
    // extended interface
!   async command bool Alarm.isRunning[uint8_t id]() {
!     return m.isset[id];
    }
  
!   async command void Alarm.startAt[uint8_t id]( size_type t0, size_type dt ) {
!     atomic {
!       m.alarm[id].t0 = t0;
!       m.alarm[id].dt = dt;
!       m.isset[id] = TRUE;
!       setNextAlarm();
      }
    }
  
!   async command size_type Alarm.getNow[uint8_t id]() {
      return call AlarmFrom.getNow();
    }
  
!   async command size_type Alarm.getAlarm[uint8_t id]() {
!     atomic return m.alarm[id].t0 + m.alarm[id].dt;
    }
  
!   default async event void Alarm.fired[uint8_t id]() {
!   }
  }
  

Index: VirtualizeTimerC.nc
===================================================================
RCS file: /cvsroot/tinyos/tinyos-2.x/tos/lib/timer/VirtualizeTimerC.nc,v
retrieving revision 1.2
retrieving revision 1.3
diff -C2 -d -r1.2 -r1.3
*** VirtualizeTimerC.nc	12 Jul 2006 17:02:31 -0000	1.2
--- VirtualizeTimerC.nc	7 Aug 2006 22:18:21 -0000	1.3
***************
*** 61,65 ****
    void executeTimers(uint32_t then)
    {
!     uint32_t min_remaining = ~(uint32_t)0;
      bool min_remaining_isset = FALSE;
      int num;
--- 61,65 ----
    void executeTimers(uint32_t then)
    {
!     int32_t min_remaining = (1UL<<31)-1; //max signed int32_t
      bool min_remaining_isset = FALSE;
      int num;
***************
*** 78,82 ****
  
  	int32_t elapsed = then - timer->t0;
! 	uint32_t remaining = timer->dt - elapsed;
  	bool compute_min_remaining = TRUE;
  
--- 78,82 ----
  
  	int32_t elapsed = then - timer->t0;
! 	int32_t remaining = timer->dt - elapsed;
  	bool compute_min_remaining = TRUE;
  
***************
*** 108,112 ****
  	if (compute_min_remaining && timer->isrunning)
  	{
! 	  if (remaining < min_remaining)
  	    min_remaining = remaining;
  	  min_remaining_isset = TRUE;
--- 108,114 ----
  	if (compute_min_remaining && timer->isrunning)
  	{
!           if (remaining < 0)
!             min_remaining = 0;
! 	  else if (remaining < min_remaining)
  	    min_remaining = remaining;
  	  min_remaining_isset = TRUE;



More information about the Tinyos-2-commits mailing list