Notice: We have migrated to GitLab launching 2024-05-01 see here: https://gitlab.rtems.org/

Ticket #1347: pr1347-cvs.diff

File pr1347-cvs.diff, 38.8 KB (added by Joel Sherrill, on 12/03/08 at 19:50:18)

Patch to rework timer server (CVS)

  • cpukit/rtems/include/rtems/rtems/timer.h

    ? cpukit/changes-XXX
    ? cpukit/m.diff
    ? cpukit/rtmonperiod.diff
    ? cpukit/ssize_t.diff
    RCS file: /usr1/CVS/rtems/cpukit/rtems/include/rtems/rtems/timer.h,v
    retrieving revision 1.27
    diff -u -r1.27 timer.h
     
    5858/**
    5959 *  @defgroup ClassicTimer Classic API Timer
    6060 *
    61  *  This encapsulates functionality which XXX
     61 *  This encapsulates functionality related to the Classic API Timer
     62 *  Manager.  This manager provides functionality which allows the
     63 *  application to schedule the execution of methods at a specified
     64 *  time in the future.  These methods may be scheduled based upon
     65 *  interval or wall time and may be executed in either the clock tick
     66 *  ISR or in a special dedicated timer server task.
    6267 */
    6368/**@{*/
    6469
     
    126131RTEMS_TIMER_EXTERN Thread_Control *_Timer_Server;
    127132
    128133/**
    129  *  This chain contains the list of interval timers that are
    130  *  executed in the context of the Timer Server.
    131  *
    132  *  @note This is extern'ed because they do not have to be in the
    133  *        minimum footprint.  It is only really required when
    134  *        task-based timers are used.  Since task-based timers can
    135  *        not be started until the server is initiated, this structure
    136  *        does not have to be initialized until then.  This is declared
    137  *        in the same file as _Timer_Server_body.
    138  */
    139 extern Chain_Control _Timer_Ticks_chain;
    140 
    141 /**
    142  *  This chain contains the list of time of day timers that are
    143  *  executed in the context of the Timer Server.
    144  *
    145  *  @note This is extern'ed because they do not have to be in the
    146  *        minimum footprint.  It is only really required when
    147  *        task-based timers are used.  Since task-based timers can
    148  *        not be started until the server is initiated, this structure
    149  *        does not have to be initialized until then.  This is declared
    150  *        in the same file as _Timer_Server_body.
    151  */
    152 extern Chain_Control _Timer_Seconds_chain;
    153 
    154 /**
    155134 *  The following records define the control block used to manage
    156135 *  each timer.
    157136 */
     
    174153);
    175154
    176155/**
    177  *  @brief _Timer_Server_body
    178  *
    179  *  This is the server for task based timers.  This task executes whenever
    180  *  a task-based timer should fire.  It services both "after" and "when"
    181  *  timers.  It is not created automatically but must be created explicitly
    182  *  by the application before task-based timers may be initiated.
    183  */
    184 Thread _Timer_Server_body(
    185   uint32_t   ignored
    186 );
    187 
    188 /**
    189156 *  @brief rtems_timer_create
    190157 *
    191158 *  This routine implements the rtems_timer_create directive.  The
     
    353320);
    354321
    355322/**
    356  *  Macros and routines that expose the mechanisms required to service
    357  *  the Timer Server timer.  These stop the timer, synchronize it with
    358  *  the current time, and restart it.
    359  */
    360 extern Watchdog_Control _Timer_Seconds_timer;
    361 
    362 /**
    363  *  This method is used to temporarily disable updates to the
    364  *  Ticks Timer Chain managed by the Timer Server.
     323 *  This type defines the method used to schedule the insertion of task
     324 *  based timers.
    365325 */
    366 #define _Timer_Server_stop_ticks_timer() \
    367       _Watchdog_Remove( &_Timer_Server->Timer )
    368 
    369 /**
    370  *  This method is used to temporarily disable updates to the
    371  *  Seconds Timer Chain managed by the Timer Server.
    372  */
    373 #define _Timer_Server_stop_seconds_timer() \
    374       _Watchdog_Remove( &_Timer_Seconds_timer );
    375 
    376 /**
    377  *  This is a helper function which processes the ticks chain when
    378  *  needed.  It advances time for the ticks chain which results in
    379  *  timers firing.
    380  */
    381 void _Timer_Server_process_ticks_chain(void);
    382 
    383 /**
    384  *  This is a helper function which processes the seconds chain when
    385  *  needed.  It advances time for the seconds chain which results in
    386  *  timers firing.
    387  */
    388 void _Timer_Server_process_seconds_chain(void);
    389 
    390 /**
    391  *  This method resets a timer and places it on the Ticks chain.  It
    392  *  is assumed that the timer has already been canceled.
    393  */
    394 #define _Timer_Server_reset_ticks_timer() \
    395    do { \
    396       if ( !_Chain_Is_empty( &_Timer_Ticks_chain ) ) { \
    397         _Watchdog_Insert_ticks( &_Timer_Server->Timer, \
    398            ((Watchdog_Control *)_Timer_Ticks_chain.first)->delta_interval ); \
    399       } \
    400    } while (0)
     326typedef void (*Timer_Server_schedule_operation_t)(
     327  Timer_Control     *the_timer
     328);
    401329
    402330/**
    403  *  This method resets a timer and places it on the Seconds chain.  It
    404  *  is assumed that the timer has already been canceled.
     331 *  This variable will point to the schedule operation method once the
     332 *  timer server is initialized.
    405333 */
    406 #define _Timer_Server_reset_seconds_timer() \
    407    do { \
    408       if ( !_Chain_Is_empty( &_Timer_Seconds_chain ) ) { \
    409         _Watchdog_Insert_seconds( &_Timer_Seconds_timer, \
    410           ((Watchdog_Control *)_Timer_Seconds_chain.first)->delta_interval ); \
    411       } \
    412    } while (0)
     334RTEMS_TIMER_EXTERN Timer_Server_schedule_operation_t
     335  _Timer_Server_schedule_operation;
    413336
    414337#ifndef __RTEMS_APPLICATION__
    415338#include <rtems/rtems/timer.inl>
  • cpukit/rtems/src/rtemstimer.c

    RCS file: /usr1/CVS/rtems/cpukit/rtems/src/rtemstimer.c,v
    retrieving revision 1.22
    diff -u -r1.22 rtemstimer.c
     
    6262   */
    6363
    6464  _Timer_Server = NULL;
     65  _Timer_Server_schedule_operation = NULL;
    6566}
  • cpukit/rtems/src/timerreset.c

    RCS file: /usr1/CVS/rtems/cpukit/rtems/src/timerreset.c,v
    retrieving revision 1.8
    diff -u -r1.8 timerreset.c
     
    5656          _Watchdog_Insert( &_Watchdog_Ticks_chain, &the_timer->Ticker );
    5757          break;
    5858        case TIMER_INTERVAL_ON_TASK:
    59           _Timer_Server_stop_ticks_timer();
     59          if ( !_Timer_Server_schedule_operation ) {
     60            _Thread_Enable_dispatch();
     61            return RTEMS_INCORRECT_STATE;
     62          }
    6063          _Watchdog_Remove( &the_timer->Ticker );
    61           _Timer_Server_process_ticks_chain();
    62           _Watchdog_Insert( &_Timer_Ticks_chain, &the_timer->Ticker );
    63           _Timer_Server_reset_ticks_timer();
     64          (*_Timer_Server_schedule_operation)( the_timer );
    6465          break;
    6566        case TIMER_TIME_OF_DAY:
    6667        case TIMER_TIME_OF_DAY_ON_TASK:
  • cpukit/rtems/src/timerserver.c

    RCS file: /usr1/CVS/rtems/cpukit/rtems/src/timerserver.c,v
    retrieving revision 1.17
    diff -u -r1.17 timerserver.c
     
    1 /*
     1/**
     2 *  @file timerserver.c
     3 *
    24 *  Timer Manager - rtems_timer_initiate_server directive along with
    3  *      the Timer Server Body and support routines
     5 *  the Timer Server Body and support routines
    46 *
    5  *  COPYRIGHT (c) 1989-2008.
     7 *  @note Data specific to the Timer Server is declared in this
     8 *        file as the Timer Server so it does not have to be in the
     9 *        minimum footprint.  It is only really required when
     10 *        task-based timers are used.  Since task-based timers can
     11 *        not be started until the server is initiated, this structure
     12 *        does not have to be initialized until then.
     13 */
     14
     15/*  COPYRIGHT (c) 1989-2008.
    616 *  On-Line Applications Research Corporation (OAR).
    717 *
    818 *  The license and distribution terms for this file may be
     
    2939#include <rtems/rtems/support.h>
    3040#include <rtems/score/thread.h>
    3141
    32 /*
    33  *  The following chains contain the list of interval timers that are
     42/**
     43 *  This chain contains the list of interval timers that are
    3444 *  executed in the context of the Timer Server.
    35  *
    36  *  NOTE: These are prototyped in rtems/timer/timer.h but since we
    37  *        do not actually use them until after the Timer Server is
    38  *        initiated, we can actually declare them here and avoid forcing
    39  *        them into the minimum footprint.
    4045 */
    41 
    4246Chain_Control _Timer_Ticks_chain;
     47
     48/**
     49 *  This chain contains the list of time of day timers that are
     50 *  executed in the context of the Timer Server.
     51 */
    4352Chain_Control _Timer_Seconds_chain;
    4453
    45 /*
    46  *  These variables keep track of the last time the Timer Server actually
    47  *  processed the chain.
     54/**
     55 *  This chain holds the set of timers to be inserted when the
     56 *  server runs again.
    4857 */
     58Chain_Control _Timer_To_be_inserted;
    4959
    50 Watchdog_Interval _Timer_Server_seconds_last_time;
     60/**
     61 *  This variables keeps track of the last time the Timer Server actually
     62 *  processed the ticks chain.
     63 */
    5164Watchdog_Interval _Timer_Server_ticks_last_time;
    5265
    53 /*
    54  *  The timer used to control when the Timer Server wakes up to service
    55  *  "when" timers.
     66/**
     67 *  This variable keeps track of the last time the Timer Server actually
     68 *  processed the seconds chain.
    5669 */
     70Watchdog_Interval _Timer_Server_seconds_last_time;
    5771
     72/**
     73 *  This is the timer used to control when the Timer Server wakes up to
     74 *  service "when" timers.
     75 *
     76 *  @note The timer in the Timer Server TCB is used for ticks timer.
     77 */
    5878Watchdog_Control _Timer_Seconds_timer;
    5979
    60 /*PAGE
     80/**
     81 *  This method is used to temporarily disable updates to the
     82 *  Ticks Timer Chain managed by the Timer Server.
     83 */
     84#define _Timer_Server_stop_ticks_timer() \
     85      _Watchdog_Remove( &_Timer_Server->Timer )
     86
     87/**
     88 *  This method is used to temporarily disable updates to the
     89 *  Seconds Timer Chain managed by the Timer Server.
     90 */
     91#define _Timer_Server_stop_seconds_timer() \
     92      _Watchdog_Remove( &_Timer_Seconds_timer );
     93
     94/**
     95 *  This method resets a timer and places it on the Ticks chain.  It
     96 *  is assumed that the timer has already been canceled.
     97 */
     98#define _Timer_Server_reset_ticks_timer() \
     99   do { \
     100      if ( !_Chain_Is_empty( &_Timer_Ticks_chain ) ) { \
     101        _Watchdog_Insert_ticks( &_Timer_Server->Timer, \
     102           ((Watchdog_Control *)_Timer_Ticks_chain.first)->delta_interval ); \
     103      } \
     104   } while (0)
     105
     106/**
     107 *  This method resets a timer and places it on the Seconds chain.  It
     108 *  is assumed that the timer has already been canceled.
     109 */
     110#define _Timer_Server_reset_seconds_timer() \
     111   do { \
     112      if ( !_Chain_Is_empty( &_Timer_Seconds_chain ) ) { \
     113        _Watchdog_Insert_seconds( &_Timer_Seconds_timer, \
     114          ((Watchdog_Control *)_Timer_Seconds_chain.first)->delta_interval ); \
     115      } \
     116   } while (0)
     117
     118/**
     119 *  @brief _Timer_Server_process_insertions
    61120 *
    62  *  _Timer_Server_body
     121 *  This method processes the set of timers scheduled for insertion
     122 *  onto one of the Timer Server chains.
     123 *
     124 *  @note It is only to be called from the Timer Server task.
     125 */
     126static void _Timer_Server_process_insertions(void)
     127{
     128  Timer_Control *the_timer;
     129
     130  while ( 1 ) {
     131    the_timer = (Timer_Control *) _Chain_Get( &_Timer_To_be_inserted );
     132    if ( the_timer == NULL )
     133      break;
     134
     135    if ( the_timer->the_class == TIMER_INTERVAL_ON_TASK ) {
     136      _Watchdog_Insert( &_Timer_Ticks_chain, &the_timer->Ticker );
     137    } else if ( the_timer->the_class == TIMER_TIME_OF_DAY_ON_TASK ) {
     138      _Watchdog_Insert( &_Timer_Seconds_chain, &the_timer->Ticker );
     139    }
     140  }
     141}
     142
     143/**
     144 *  @brief _Timer_Server_process_ticks_chain
     145 *
     146 *  This routine is responsible for adjusting the list of task-based
     147 *  interval timers to reflect the passage of time.
     148 *
     149 *  @param[in] to_fire will contain the set of timers that are to be fired.
     150 *
     151 *  @note It is only to be called from the Timer Server task.
     152 */
     153static void _Timer_Server_process_ticks_chain(
     154  Chain_Control *to_fire
     155)
     156{
     157  Watchdog_Interval snapshot;
     158  Watchdog_Interval ticks;
     159
     160  snapshot = _Watchdog_Ticks_since_boot;
     161  if ( snapshot >= _Timer_Server_ticks_last_time )
     162     ticks = snapshot - _Timer_Server_ticks_last_time;
     163  else
     164     ticks = (0xFFFFFFFF - _Timer_Server_ticks_last_time) + snapshot;
     165
     166  _Timer_Server_ticks_last_time = snapshot;
     167  _Watchdog_Adjust_to_chain( &_Timer_Ticks_chain, ticks, to_fire );
     168}
     169
     170/**
     171 *  @brief _Timer_Server_process_seconds_chain
     172 *
     173 *  This routine is responsible for adjusting the list of task-based
     174 *  time of day timers to reflect the passage of time.
     175 *
     176 *  @param[in] to_fire will contain the set of timers that are to be fired.
     177 *
     178 *  @note It is only to be called from the Timer Server task.
     179 */
     180static void _Timer_Server_process_seconds_chain(
     181  Chain_Control *to_fire
     182)
     183{
     184  Watchdog_Interval snapshot;
     185  Watchdog_Interval ticks;
     186
     187  /*
     188   *  Process the seconds chain.  Start by checking that the Time
     189   *  of Day (TOD) has not been set backwards.  If it has then
     190   *  we want to adjust the _Timer_Seconds_chain to indicate this.
     191   */
     192  snapshot =  _TOD_Seconds_since_epoch;
     193  if ( snapshot > _Timer_Server_seconds_last_time ) {
     194    /*
     195     *  This path is for normal forward movement and cases where the
     196     *  TOD has been set forward.
     197     */
     198    ticks = snapshot - _Timer_Server_seconds_last_time;
     199    _Watchdog_Adjust_to_chain( &_Timer_Seconds_chain, ticks, to_fire );
     200
     201  } else if ( snapshot < _Timer_Server_seconds_last_time ) {
     202     /*
     203      *  The current TOD is before the last TOD which indicates that
     204      *  TOD has been set backwards.
     205      */
     206     ticks = _Timer_Server_seconds_last_time - snapshot;
     207     _Watchdog_Adjust( &_Timer_Seconds_chain, WATCHDOG_BACKWARD, ticks );
     208  }
     209  _Timer_Server_seconds_last_time = snapshot;
     210}
     211
     212/**
     213 *  @brief _Timer_Server_body
    63214 *
    64215 *  This is the server for task based timers.  This task executes whenever
    65216 *  a task-based timer should fire.  It services both "after" and "when"
    66217 *  timers.  It is not created automatically but must be created explicitly
    67218 *  by the application before task-based timers may be initiated.
    68219 *
    69  *  Input parameters:
    70  *    Ignored - the task argument is ignored
    71  *
    72  *  Output parameters:  NONE
     220 *  @param[in] ignored is the the task argument that is ignored
    73221 */
    74 
    75222Thread _Timer_Server_body(
    76223  uint32_t   ignored
    77224)
    78225{
     226  Chain_Control to_fire;
     227
     228  _Chain_Initialize_empty( &to_fire );
     229
    79230  /*
    80231   *  Initialize the "last time" markers to indicate the timer that
    81232   *  the server was initiated.
    82233   */
    83 
    84234  _Timer_Server_ticks_last_time   = _Watchdog_Ticks_since_boot;
    85235  _Timer_Server_seconds_last_time = _TOD_Seconds_since_epoch;
    86236
     237  /*
     238   *  Insert the timers that were inserted before we got to run.
     239   *  This should be done with dispatching disabled.
     240   */
    87241  _Thread_Disable_dispatch();
     242    _Timer_Server_process_insertions();
     243  _Thread_Enable_dispatch();
     244
    88245  while(1) {
    89246
    90247    /*
    91248     *  Block until there is something to do.
    92249     */
    93 
     250    _Thread_Disable_dispatch();
    94251      _Thread_Set_state( _Timer_Server, STATES_DELAYING );
    95252      _Timer_Server_reset_ticks_timer();
    96253      _Timer_Server_reset_seconds_timer();
    97254    _Thread_Enable_dispatch();
    98255
     256    /********************************************************************
     257     ********************************************************************
     258     ****                TIMER SERVER BLOCKS HERE                    ****
     259     ********************************************************************
     260     ********************************************************************/
     261
     262    /*
     263     *  Disable dispatching while processing the timers since we want
     264     *  the removal of the timers from the chain to be atomic.
     265     *
     266     *  NOTE: Dispatching is disabled for interrupt based TSRs.
     267     *        Dispatching is enabled for task based TSRs so they
     268     *          can temporarily malloc memory or block.
     269     *        _ISR_Nest_level is 0 for task-based TSRs and non-zero
     270     *          for the others.
     271     */
     272    _Thread_Disable_dispatch();
     273
    99274    /*
    100275     *  At this point, at least one of the timers this task relies
    101276     *  upon has fired.  Stop them both while we process any outstanding
    102277     *  timers.  Before we block, we will restart them.
    103278     */
     279    _Timer_Server_stop_ticks_timer();
     280    _Timer_Server_stop_seconds_timer();
    104281
    105       _Timer_Server_stop_ticks_timer();
    106       _Timer_Server_stop_seconds_timer();
     282    /*
     283     *  Remove all the timers that need to fire so we can invoke them
     284     *  outside the critical section.
     285     */
     286    _Timer_Server_process_ticks_chain( &to_fire );
     287    _Timer_Server_process_seconds_chain( &to_fire );
    107288
    108289    /*
    109      *  Disable dispatching while processing the timers since we want
    110      *  to mimic the environment that non-task-based TSRs execute in.
    111      *  This ensures that the primary difference is that _ISR_Nest_level
    112      *  is 0 for task-based timers and non-zero for the others.
     290     *  Insert the timers that have been requested to be inserted.
    113291     */
     292    _Timer_Server_process_insertions();
    114293
    115     _Thread_Disable_dispatch();
    116       _Timer_Server_process_ticks_chain();
    117       _Timer_Server_process_seconds_chain();
     294    /*
     295     * Enable dispatching to process the set that are ready "to fire."
     296     */
     297    _Thread_Enable_dispatch();
     298
     299    /*
     300     *  Now we actually invoke the TSR for all the timers that fired.
     301     *  This is done with dispatching
     302     */
     303    while (1) {
     304      Watchdog_Control *watch;
     305      ISR_Level         level;
     306
     307      _ISR_Disable( level );
     308      watch = (Watchdog_Control *) _Chain_Get_unprotected( &to_fire );
     309      if ( watch == NULL ) {
     310        _ISR_Enable( level );
     311        break;
     312      }
     313
     314      watch->state = WATCHDOG_INACTIVE;
     315      _ISR_Enable( level );
     316
     317      (*watch->routine)( watch->id, watch->user_data );
     318    }
    118319  }
    119320
    120321  return 0;   /* unreached - only to remove warnings */
    121322}
    122323
    123 /*PAGE
     324/**
     325 *  This method schedules the insertion of timers on the proper list.  It
     326 *  wakes up the Timer Server task to process the insertion.
     327 *
     328 *  @param[in] the_timer is the timer to insert
    124329 *
    125  *  rtems_timer_initiate_server
     330 *  @note It is highly likely the executing task will be preempted after
     331 *        the directive invoking this is executed.
     332 */
     333static void _Timer_Server_schedule_operation_method(
     334  Timer_Control     *the_timer
     335)
     336{
     337  _Chain_Append( &_Timer_To_be_inserted, &the_timer->Object.Node );
     338  _Watchdog_Remove( &_Timer_Server->Timer );
     339  _Thread_Delay_ended( _Timer_Server->Object.id, NULL );
     340}
     341
     342/**
     343 *  @brief rtems_timer_initiate_server
    126344 *
    127345 *  This directive creates and starts the server for task-based timers.
    128346 *  It must be invoked before any task-based timers can be initiated.
    129347 *
    130  *  Input parameters:
    131  *    priority         - timer server priority
    132  *    stack_size       - stack size in bytes
    133  *    attribute_set    - timer server attributes
    134  *
    135  *  Output parameters:
    136  *    RTEMS_SUCCESSFUL - if successful
    137  *    error code       - if unsuccessful
     348 *  @param[in] priority is the timer server priority
     349 *  @param[in] stack_size is the stack size in bytes
     350 *  @param[in] attribute_set is the timer server attributes
     351 *
     352 *  @return This method returns RTEMS_SUCCESSFUL if successful and an
     353 *          error code otherwise.
    138354 */
    139 
    140 
    141355rtems_status_code rtems_timer_initiate_server(
    142356  uint32_t             priority,
    143357  uint32_t             stack_size,
     
    151365  bool                tmpInitialized;
    152366
    153367  /*
    154    *  Make sure the requested priority is valid.  The if is 
     368   *  Make sure the requested priority is valid.  The if is
    155369   *  structured so we check it is invalid before looking for
    156370   *  a specific invalid value as the default.
    157371   */
    158 
    159372  _priority = priority;
    160373  if ( !_RTEMS_tasks_Priority_is_valid( priority ) ) {
    161374    if ( priority != RTEMS_TIMER_SERVER_DEFAULT_PRIORITY )
     
    166379  /*
    167380   *  Just to make sure this is only called once.
    168381   */
    169 
    170382  _Thread_Disable_dispatch();
    171383    tmpInitialized  = initialized;
    172384    initialized = true;
     
    176388    return RTEMS_INCORRECT_STATE;
    177389
    178390  /*
     391   *  Initialize the set of timers to be inserted by the server.
     392   */
     393  _Chain_Initialize_empty( &_Timer_To_be_inserted );
     394
     395  /*
    179396   *  Create the Timer Server with the name the name of "TIME".  The attribute
    180397   *  RTEMS_SYSTEM_TASK allows us to set a priority to 0 which will makes it
    181398   *  higher than any other task in the system.  It can be viewed as a low
     
    189406   *  Otherwise, the priority ceiling for the mutex used to protect the
    190407   *  GNAT run-time is violated.
    191408   */
    192 
    193409  status = rtems_task_create(
    194410    _Objects_Build_name('T','I','M','E'),           /* "TIME" */
    195411    _priority,            /* create with priority 1 since 0 is illegal */
     
    217433   *  NOTE: Setting the pointer to the Timer Server TCB to a value other than
    218434   *        NULL indicates that task-based timer support is initialized.
    219435   */
    220 
    221436  _Timer_Server = (Thread_Control *)_Objects_Get_local_object(
    222437    &_RTEMS_tasks_Information,
    223438    _Objects_Get_index(id)
     
    226441  /*
    227442   *  Initialize the timer lists that the server will manage.
    228443   */
    229 
    230444  _Chain_Initialize_empty( &_Timer_Ticks_chain );
    231445  _Chain_Initialize_empty( &_Timer_Seconds_chain );
    232446
     
    234448   *  Initialize the timers that will be used to control when the
    235449   *  Timer Server wakes up and services the task-based timers.
    236450   */
    237 
    238451  _Watchdog_Initialize( &_Timer_Server->Timer, _Thread_Delay_ended, id, NULL );
    239452  _Watchdog_Initialize( &_Timer_Seconds_timer, _Thread_Delay_ended, id, NULL );
     453
    240454  /*
    241    *  Start the timer server
     455   *  Initialize the pointer to the timer reset method so applications
     456   *  that do not use the Timer Server do not have to pull it in.
    242457   */
     458  _Timer_Server_schedule_operation = _Timer_Server_schedule_operation_method;
    243459
     460  /*
     461   *  Start the timer server
     462   */
    244463  status = rtems_task_start(
    245464    id,                                    /* the id from create */
    246465    (rtems_task_entry) _Timer_Server_body, /* the timer server entry point */
     
    259478
    260479  return status;
    261480}
    262 
    263 /*PAGE
    264  *
    265  *  _Timer_Server_process_ticks_chain
    266  *
    267  *  This routine is responsible for adjusting the list of task-based
    268  *  interval timers to reflect the passage of time.
    269  *
    270  *  Input parameters:   NONE
    271  *
    272  *  Output parameters:  NONE
    273  */
    274 
    275 void _Timer_Server_process_ticks_chain(void)
    276 {
    277   Watchdog_Interval snapshot;
    278   Watchdog_Interval ticks;
    279 
    280   snapshot = _Watchdog_Ticks_since_boot;
    281   if ( snapshot >= _Timer_Server_ticks_last_time )
    282      ticks = snapshot - _Timer_Server_ticks_last_time;
    283   else
    284      ticks = (0xFFFFFFFF - _Timer_Server_ticks_last_time) + snapshot;
    285 
    286   _Timer_Server_ticks_last_time = snapshot;
    287   _Watchdog_Adjust( &_Timer_Ticks_chain, WATCHDOG_FORWARD, ticks );
    288 }
    289 
    290 /*PAGE
    291  *
    292  *  _Timer_Server_process_seconds_chain
    293  *
    294  *  This routine is responsible for adjusting the list of task-based
    295  *  time of day timers to reflect the passage of time.
    296  *
    297  *  Input parameters:   NONE
    298  *
    299  *  Output parameters:  NONE
    300  */
    301 
    302 void _Timer_Server_process_seconds_chain(void)
    303 {
    304   Watchdog_Interval snapshot;
    305   Watchdog_Interval ticks;
    306 
    307   /*
    308    *  Process the seconds chain.  Start by checking that the Time
    309    *  of Day (TOD) has not been set backwards.  If it has then
    310    *  we want to adjust the _Timer_Seconds_chain to indicate this.
    311    */
    312 
    313   snapshot =  _TOD_Seconds_since_epoch;
    314   if ( snapshot > _Timer_Server_seconds_last_time ) {
    315     /*
    316      *  This path is for normal forward movement and cases where the
    317      *  TOD has been set forward.
    318      */
    319 
    320     ticks = snapshot - _Timer_Server_seconds_last_time;
    321     _Watchdog_Adjust( &_Timer_Seconds_chain, WATCHDOG_FORWARD, ticks );
    322 
    323   } else if ( snapshot < _Timer_Server_seconds_last_time ) {
    324      /*
    325       *  The current TOD is before the last TOD which indicates that
    326       *  TOD has been set backwards.
    327       */
    328 
    329      ticks = _Timer_Server_seconds_last_time - snapshot;
    330      _Watchdog_Adjust( &_Timer_Seconds_chain, WATCHDOG_BACKWARD, ticks );
    331   }
    332   _Timer_Server_seconds_last_time = snapshot;
    333 }
  • cpukit/rtems/src/timerserverfireafter.c

    RCS file: /usr1/CVS/rtems/cpukit/rtems/src/timerserverfireafter.c,v
    retrieving revision 1.12
    diff -u -r1.12 timerserverfireafter.c
     
    9292        the_timer->Ticker.initial = ticks;
    9393      _ISR_Enable( level );
    9494
    95       _Timer_Server_stop_ticks_timer();
    96       _Timer_Server_process_ticks_chain();
    97       _Watchdog_Insert( &_Timer_Ticks_chain, &the_timer->Ticker );
    98        _Timer_Server_reset_ticks_timer();
     95      /*
     96       * _Timer_Server_schedule_operation != NULL because we checked that
     97       * _Timer_Server was != NULL above.  Both are set at the same time.
     98       */
     99
     100      (*_Timer_Server_schedule_operation)( the_timer );
    99101
    100102      _Thread_Enable_dispatch();
    101103      return RTEMS_SUCCESSFUL;
  • cpukit/rtems/src/timerserverfirewhen.c

    RCS file: /usr1/CVS/rtems/cpukit/rtems/src/timerserverfirewhen.c,v
    retrieving revision 1.10
    diff -u -r1.10 timerserverfirewhen.c
     
    7979      _Watchdog_Initialize( &the_timer->Ticker, routine, id, user_data );
    8080      the_timer->Ticker.initial = seconds - _TOD_Seconds_since_epoch;
    8181
    82       _Timer_Server_stop_seconds_timer();
    83       _Timer_Server_process_seconds_chain();
    84       _Watchdog_Insert( &_Timer_Seconds_chain, &the_timer->Ticker );
    85        _Timer_Server_reset_seconds_timer();
     82      /*
     83       * _Timer_Server_schedule_operation != NULL because we checked that
     84       * _Timer_Server was != NULL above.  Both are set at the same time.
     85       */
     86
     87      (*_Timer_Server_schedule_operation)( the_timer );
    8688
    8789      _Thread_Enable_dispatch();
    8890      return RTEMS_SUCCESSFUL;
  • cpukit/score/Makefile.am

    RCS file: /usr1/CVS/rtems/cpukit/score/Makefile.am,v
    retrieving revision 1.60
    diff -u -r1.60 Makefile.am
     
    173173
    174174## WATCHDOG_C_FILES
    175175libscore_a_SOURCES += src/watchdog.c src/watchdogadjust.c \
    176     src/watchdoginsert.c src/watchdogremove.c src/watchdogtickle.c \
    177     src/watchdogreport.c src/watchdogreportchain.c
     176    src/watchdogadjusttochain.c src/watchdoginsert.c src/watchdogremove.c \
     177    src/watchdogtickle.c src/watchdogreport.c src/watchdogreportchain.c
    178178
    179179## USEREXT_C_FILES
    180180libscore_a_SOURCES += src/userextaddapiset.c src/userextaddset.c \
  • cpukit/score/include/rtems/score/watchdog.h

    RCS file: /usr1/CVS/rtems/cpukit/score/include/rtems/score/watchdog.h,v
    retrieving revision 1.27
    diff -u -r1.27 watchdog.h
     
    220220  Watchdog_Interval           units
    221221);
    222222
     223/** @brief Watchdog Adjust to Chain
     224 *
     225 *  This routine adjusts the @a header watchdog chain in the forward
     226 *  @a direction for @a units_arg ticks.
     227 *
     228 *  @param[in] header is the watchdog chain to adjust
     229 *  @param[in] units is the number of units to adjust @a header
     230 *  @param[in] to_fire is a pointer to an initialized Chain_Control to which
     231 *             all watchdog instances that are to be fired will be placed.
     232 *
     233 *  @note This always adjusts forward.
     234 */
     235void _Watchdog_Adjust_to_chain(
     236  Chain_Control               *header,
     237  Watchdog_Interval            units_arg,
     238  Chain_Control               *to_fire
     239
     240);
     241
    223242/** @brief Watchdog Insert
    224243 *
    225244 *  This routine inserts @a the_watchdog into the @a header watchdog chain
  • new file cpukit/score/src/watchdogadjusttochain.c

    RCS file: cpukit/score/src/watchdogadjusttochain.c
    diff -N cpukit/score/src/watchdogadjusttochain.c
    - +  
     1/**
     2 *  @file watchdogadjusttochain.c
     3 *
     4 *  This is used by the Timer Server task.
     5 */
     6
     7/*  COPYRIGHT (c) 1989-2008.
     8 *  On-Line Applications Research Corporation (OAR).
     9 *
     10 *  The license and distribution terms for this file may be
     11 *  found in the file LICENSE in this distribution or at
     12 *  http://www.rtems.com/license/LICENSE.
     13 *
     14 *  $Id: watchdogreport.c,v 1.1 2008/11/26 16:33:30 joel Exp $
     15 */
     16
     17#if HAVE_CONFIG_H
     18#include "config.h"
     19#endif
     20
     21#include <rtems/system.h>
     22#include <rtems/score/isr.h>
     23#include <rtems/score/watchdog.h>
     24
     25void _Watchdog_Adjust_to_chain(
     26  Chain_Control               *header,
     27  Watchdog_Interval            units_arg,
     28  Chain_Control               *to_fire
     29
     30)
     31{
     32  Watchdog_Interval  units = units_arg;
     33  ISR_Level          level;
     34  Chain_Node        *node;
     35
     36  if ( !units ) {
     37    return;
     38  }
     39  _ISR_Disable( level );
     40
     41  if ( !_Chain_Is_empty( header ) ) {
     42    while ( units ) {
     43      if ( units < _Watchdog_First( header )->delta_interval ) {
     44        _Watchdog_First( header )->delta_interval -= units;
     45        break;
     46      } else {
     47        units -= _Watchdog_First( header )->delta_interval;
     48        _Watchdog_First( header )->delta_interval = 0;
     49
     50        do {
     51          node = _Chain_Get_unprotected( header );
     52          _Chain_Append_unprotected( to_fire, node );
     53
     54          _ISR_Flash( level );
     55
     56        } while ( !_Chain_Is_empty( header ) &&
     57                  _Watchdog_First( header )->delta_interval == 0 );
     58
     59        if ( _Chain_Is_empty( header ) )
     60          break;
     61      }
     62    }
     63
     64  }
     65  _ISR_Enable( level );
     66}
     67
  • testsuites/sptests/Makefile.am

    RCS file: /usr1/CVS/rtems/testsuites/sptests/Makefile.am,v
    retrieving revision 1.30
    diff -u -r1.30 Makefile.am
     
    88SUBDIRS = sp01 sp02 sp03 sp04 sp05 sp06 sp07 sp08 sp09 sp11 sp12 sp13 sp14 \
    99    sp15 sp16 sp17 sp19 sp20 sp21 sp22 sp23 sp24 sp25 sp26 sp27 sp28 sp29 \
    1010    sp30 sp31 sp32 sp33 sp34 sp35 sp37 sp38 sp39 sp40 sp41 sp42 sp43 sp44 \
    11     spsize spfatal01 spfatal02 spfatal03 spfatal04 spfatal05 spfatal06 \
     11    sp45 spsize spfatal01 spfatal02 spfatal03 spfatal04 spfatal05 spfatal06 \
    1212    spfatal07 spfatal08 spfatal09 spfatal10
    1313
    1414DIST_SUBDIRS = $(SUBDIRS) spfatal spfatal_support
  • testsuites/sptests/configure.ac

    RCS file: /usr1/CVS/rtems/testsuites/sptests/configure.ac,v
    retrieving revision 1.34
    diff -u -r1.34 configure.ac
     
    6969sp42/Makefile
    7070sp43/Makefile
    7171sp44/Makefile
     72sp45/Makefile
    7273spsize/Makefile
    7374spfatal/Makefile
    7475spfatal01/Makefile
  • testsuites/sptests/sp30/resume.c

    RCS file: /usr1/CVS/rtems/testsuites/sptests/sp30/resume.c,v
    retrieving revision 1.4
    diff -u -r1.4 resume.c
     
    2929
    3030  task_to_resume = Task_id[ rtems_object_id_get_index( timer_id ) ];
    3131  status = rtems_task_resume( task_to_resume );
    32   directive_failed_with_level( status, "rtems_task_resume", 1 );
     32  directive_failed( status, "rtems_task_resume" );
    3333}
  • testsuites/sptests/sp30/task1.c

    RCS file: /usr1/CVS/rtems/testsuites/sptests/sp30/task1.c,v
    retrieving revision 1.5
    diff -u -r1.5 task1.c
     
    3636      Timer_id[ argument ],
    3737      (task_number( tid ) - 1) * 5 * TICKS_PER_SECOND,
    3838      Resume_task,
    39       NULL
     39      (void *) tid
    4040    );
    4141    directive_failed( status, "rtems_timer_server_fire_after failed" );
    4242
  • testsuites/sptests/sp31/delay.c

    RCS file: /usr1/CVS/rtems/testsuites/sptests/sp31/delay.c,v
    retrieving revision 1.4
    diff -u -r1.4 delay.c
     
    2727  rtems_status_code status;
    2828
    2929  status = rtems_task_resume( Task_id[ 1 ] );
    30   directive_failed_with_level( status, "rtems_task_resume of self", 1 );
     30  directive_failed( status, "rtems_task_resume of self" );
    3131}
  • new file testsuites/sptests/sp45/.cvsignore

    RCS file: testsuites/sptests/sp45/.cvsignore
    diff -N testsuites/sptests/sp45/.cvsignore
    - +  
     1Makefile
     2Makefile.in
  • new file testsuites/sptests/sp45/Makefile.am

    RCS file: testsuites/sptests/sp45/Makefile.am
    diff -N testsuites/sptests/sp45/Makefile.am
    - +  
     1##
     2## $Id: Makefile.am,v 1.18 2006/07/11 05:00:28 ralf Exp $
     3##
     4
     5MANAGERS = all
     6
     7rtems_tests_PROGRAMS = sp45.exe
     8sp45_exe_SOURCES = init.c
     9
     10dist_rtems_tests_DATA = sp45.scn
     11dist_rtems_tests_DATA += sp45.doc
     12
     13include $(RTEMS_ROOT)/make/custom/@RTEMS_BSP@.cfg
     14include $(top_srcdir)/../automake/compile.am
     15include $(top_srcdir)/../automake/leaf.am
     16
     17sp45_exe_LDADD = $(MANAGERS_NOT_WANTED:%=$(PROJECT_LIB)/no-%.rel)
     18
     19AM_CPPFLAGS += -I$(top_srcdir)/../support/include
     20
     21LINK_OBJS = $(sp45_exe_OBJECTS) $(sp45_exe_LDADD)
     22LINK_LIBS = $(sp45_exe_LDLIBS)
     23
     24sp45.exe$(EXEEXT): $(sp45_exe_OBJECTS) $(sp45_exe_DEPENDENCIES)
     25        @rm -f sp45.exe$(EXEEXT)
     26        $(make-exe)
     27
     28include $(top_srcdir)/../automake/local.am
  • new file testsuites/sptests/sp45/init.c

    RCS file: testsuites/sptests/sp45/init.c
    diff -N testsuites/sptests/sp45/init.c
    - +  
     1/*
     2 *  COPYRIGHT (c) 1989-2008.
     3 *  On-Line Applications Research Corporation (OAR).
     4 *
     5 *  The license and distribution terms for this file may be
     6 *  found in the file LICENSE in this distribution or at
     7 *  http://www.rtems.com/license/LICENSE.
     8 *
     9 *  $Id: init.c,v 1.6 2008/02/01 00:45:11 joel Exp $
     10 */
     11
     12#include <tmacros.h>
     13
     14rtems_id   Timer_id[ 3 ];    /* array of timer ids */
     15rtems_name Timer_name[ 3 ];  /* array of timer names */
     16
     17volatile int TSR_fired;
     18volatile void *TSR_malloc_ptr;
     19
     20rtems_timer_service_routine Malloc_From_TSR(
     21  rtems_id  ignored_id,
     22  void     *ignored_address
     23)
     24{
     25  rtems_status_code  status;
     26
     27  TSR_fired = 2;
     28  puts( "TSR: calling malloc" );
     29  TSR_malloc_ptr = malloc( 64 );
     30
     31  puts( "TSR: calling free" );
     32  free( (void *) TSR_malloc_ptr );
     33
     34  puts( "TSR: delaying with rtems_task_wake_after" );
     35  status = rtems_task_wake_after( TICKS_PER_SECOND / 2 );
     36  directive_failed( status, "rtems_task_wake_after" );
     37}
     38
     39rtems_task Init(
     40  rtems_task_argument argument
     41)
     42{
     43  rtems_status_code  status;
     44
     45  puts( "\n\n*** TEST 45 ***" );
     46
     47  status = rtems_timer_initiate_server(
     48    RTEMS_TIMER_SERVER_DEFAULT_PRIORITY,
     49    RTEMS_MINIMUM_STACK_SIZE,
     50    RTEMS_DEFAULT_ATTRIBUTES
     51  );
     52  directive_failed( status, "rtems_timer_initiate_server" );
     53
     54  /*
     55   * Initialize Timers
     56   */
     57
     58  Timer_name[ 1 ] = rtems_build_name( 'T', 'M', '1', ' ' );
     59  Timer_name[ 2 ] = rtems_build_name( 'T', 'M', '2', ' ' );
     60
     61  puts( "INIT - rtems_timer_create - creating timer 1" );
     62  status = rtems_timer_create( Timer_name[ 1 ], &Timer_id[ 1 ] );
     63  directive_failed( status, "rtems_timer_create" );
     64  printf( "INIT - timer 1 has id (0x%x)\n", Timer_id[ 1 ] );
     65
     66  puts( "INIT - rtems_timer_create - creating timer 2" );
     67  status = rtems_timer_create( Timer_name[ 2 ], &Timer_id[ 2 ] );
     68  directive_failed( status, "rtems_timer_create" );
     69  printf( "INIT - timer 2 has id (0x%x)\n", Timer_id[ 2 ] );
     70
     71  /*
     72   *  Schedule malloc TSR for 1 second from now
     73   */
     74
     75  TSR_fired = 0;
     76  TSR_malloc_ptr = (void *) 0xa5a5a5;
     77  puts( "TA1 - rtems_timer_server_fire_after - timer 1 in 1 seconds" );
     78  status = rtems_timer_server_fire_after(
     79    Timer_id[ 1 ],
     80    1 * TICKS_PER_SECOND,
     81    Malloc_From_TSR,
     82    NULL
     83  );
     84  directive_failed( status, "rtems_timer_server_fire_after" );
     85
     86  puts( "TA1 - rtems_task_wake_after - 2 second" );
     87  status = rtems_task_wake_after( 2 * TICKS_PER_SECOND );
     88  directive_failed( status, "rtems_task_wake_after" );
     89
     90  if ( TSR_fired == 2 &&
     91       (TSR_malloc_ptr && TSR_malloc_ptr != (void *)0xa5a5a5) )
     92    puts( "TSR appears to have executed OK" );
     93  else {
     94    printf( "FAILURE ptr=%p TSR_fired=%d\n", TSR_malloc_ptr, TSR_fired );
     95    rtems_test_exit( 0 );
     96  }
     97
     98  /*
     99   *  Delete timer and exit test
     100   */
     101  puts( "TA1 - timer_deleting - timer 1" );
     102  status = rtems_timer_delete( Timer_id[ 1 ] );
     103  directive_failed( status, "rtems_timer_delete" );
     104
     105
     106  puts( "*** END OF TEST 45 *** " );
     107  rtems_test_exit( 0 );
     108}
     109
     110#define CONFIGURE_INIT
     111/* configuration information */
     112
     113#define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER
     114#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
     115
     116/* Two Tasks: Init and Timer Server */
     117#define CONFIGURE_MAXIMUM_TASKS           2
     118#define CONFIGURE_MAXIMUM_TIMERS          2
     119#define CONFIGURE_INIT_TASK_STACK_SIZE    (RTEMS_MINIMUM_STACK_SIZE * 2)
     120
     121#define CONFIGURE_RTEMS_INIT_TASKS_TABLE
     122
     123#define CONFIGURE_EXTRA_TASK_STACKS       (1 * RTEMS_MINIMUM_STACK_SIZE)
     124
     125#include <rtems/confdefs.h>
     126
  • new file testsuites/sptests/sp45/sp45.doc

    RCS file: testsuites/sptests/sp45/sp45.doc
    diff -N testsuites/sptests/sp45/sp45.doc
    - +  
     1#
     2#  $Id: sp31.doc,v 1.1.1.1 2002/01/02 16:18:27 joel Exp $
     3#
     4#  COPYRIGHT (c) 1989-2002.
     5#  On-Line Applications Research Corporation (OAR).
     6#
     7#  The license and distribution terms for this file may be
     8#  found in the file LICENSE in this distribution or at
     9#  http://www.rtems.com/license/LICENSE.
     10#
     11
     12
     13This file describes the directives and concepts tested by this test set.
     14
     15test set name:  test44
     16
     17directives:
     18
     19concepts:
     20
     21allocating memory from a Timer Service Routine fired from a server
     22delaying in a Timer Service Routine fired from a server