Stuck in a 'for' loop in _Watchdog_Insert.

Nick Thomas nick.thomas at pixsan.com
Thu May 20 15:13:31 UTC 2010


> Nick,
> 
> unfortunately you do not provide real information about the system you
> are using. So it is really difficult to help you :-(
> 

Hi Thomas,

The system I am using is RTEMS 4.7.1. It's code in watchdoginsert.c,
watchdogadjust.c and watchdogtickle.c, these are all in cpukit/score/src.
So, they are not specific to any hardware.

There is already a comment in _Watchdog_Tickle in watchdogtickle.c which
says this:

  /*
   * For some reason, on rare occasions the_watchdog->delta_interval
   * of the head of the watchdog chain is 0.  Before this test was
   * added, on these occasions an event (which usually was supposed
   * to have a timeout of 1 tick would have a delta_interval of 0, which
   * would be decremented to 0xFFFFFFFF by the unprotected 
   * "the_watchdog->delta_interval--;" operation.
   * This would mean the event would not timeout, and also the chain would
   * be blocked, because a timeout with a very high number would be at the
   * head, rather than at the end.
   * The test "if (the_watchdog->delta_interval != 0)"
   * here prevents this from occuring. 
   * 
   * We were not able to categorically identify the situation that causes 
   * this, but proved it to be true empirically.  So this check causes 
   * correct behaviour in this circumstance.
   * 
   * The belief is that a race condition exists whereby an event at the head
   * of the chain is removed (by a pending ISR or higher priority task)
   * during the _ISR_Flash( level ); in _Watchdog_Insert, but the watchdog 
   * to be inserted has already had its delta_interval adjusted to 0, and 
   * so is added to the head of the chain with a delta_interval of 0.  
   * 
   * Steven Johnson - 12/2005 (gcc-3.2.3 -O3 on powerpc)
   */

This describes pretty much the behavior I am seeing, i.e.
the_watchdog->delta_interval == 0.

However, contrary to the above comments - removing the _ISR_Flash( level )
call from _Watchdog_Insert doesn't fix the issue.

I understand why I am stuck in this 'for' loop when this happens, but I
don't understand why this code doesn't break out of it when we get to the
end of the linked list:

if ( delta_interval == 0 || !_Watchdog_Next( after ) )
       break;

i.e. why doesn't !_Watchdog_Next( after ) return NULL at the end of the
list?

For some reason it points back to itself!!!!! So the for loop is still
engaged.


Regards

Nick






More information about the users mailing list