+ 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() {