Changeset 0243b0d in rtems


Ignore:
Timestamp:
Jun 8, 2006, 8:47:48 PM (14 years ago)
Author:
Joel Sherrill <joel.sherrill@…>
Branches:
4.10, 4.11, 4.8, 4.9, master
Children:
25571ae
Parents:
7c99007
Message:

2006-06-08 Joel Sherrill <joel@…>

  • posix/Makefile.am, posix/preinstall.am, posix/include/rtems/posix/timer.h, posix/src/ptimer.c, posix/src/ptimer1.c, sapi/src/posixapi.c, score/include/rtems/score/object.h:
Location:
cpukit
Files:
8 edited

Legend:

Unmodified
Added
Removed
  • cpukit/ChangeLog

    r7c99007 r0243b0d  
     12006-06-08      Joel Sherrill <joel@OARcorp.com>
     2
     3        * posix/Makefile.am, posix/preinstall.am,
     4        posix/include/rtems/posix/timer.h, posix/src/ptimer.c,
     5        posix/src/ptimer1.c, sapi/src/posixapi.c,
     6        score/include/rtems/score/object.h:
     7
    182006-06-02      Joel Sherrill <joel@OARcorp.com>
    29
  • cpukit/posix/Makefile.am

    r7c99007 r0243b0d  
    2424    include/rtems/posix/mutex.h include/rtems/posix/posixapi.h \
    2525    include/rtems/posix/priority.h include/rtems/posix/psignal.h \
    26     include/rtems/posix/pthread.h include/rtems/posix/ptimer.h \
    27     include/rtems/posix/semaphore.h include/rtems/posix/threadsup.h \
    28     include/rtems/posix/time.h include/rtems/posix/timer.h
     26    include/rtems/posix/pthread.h include/rtems/posix/semaphore.h \
     27    include/rtems/posix/threadsup.h include/rtems/posix/time.h \
     28    include/rtems/posix/timer.h
    2929
    3030if HAS_MP
  • cpukit/posix/include/rtems/posix/timer.h

    r7c99007 r0243b0d  
    1010#define _RTEMS_POSIX_TIMER_H
    1111
    12 /* ************
     12#include <rtems/posix/config.h>
     13/*
    1314 * Constants
    14  * ************/
     15 */
    1516
    1617#define STATE_FREE_C        0x01 /* Free position of the table of timers   */
     
    2728#define NSEC_PER_SEC_C (uint32_t  )1000000000
    2829
    29 #define NO_MORE_TIMERS_C      -1 /* There is not available timers          */
    30 #define BAD_TIMER_C           -2 /* The timer does not exist in the table  */
    31 
    3230#define SECONDS_PER_YEAR_C    (uint32_t  )(360 * 24) * (uint32_t  )(60 * 60)
    3331#define SECONDS_PER_MONTH_C   (uint32_t  )( 30 * 24) * (uint32_t  )(60 * 60)
     
    4341typedef struct {
    4442  Objects_Control   Object;
    45   Watchdog_Control  Ticker;
    46 
     43  Watchdog_Control  Timer;      /* Internal Timer                        */
    4744  pthread_t         thread_id;  /* Thread identifier                     */
    4845  char              state;      /* State of the timer                    */
    4946  struct sigevent   inf;        /* Information associated to the timer   */
    50   timer_t           timer_id;   /* Created timer identifier              */
    5147  struct itimerspec timer_data; /* Timing data of the timer              */
    5248  uint32_t          ticks;      /* Number of ticks of the initialization */
    5349  uint32_t          overrun;    /* Number of expirations of the timer    */
    54   rtems_time_of_day time;       /* Time in which the timer was started   */
     50  TOD_Control      time;       /* Time in which the timer was started   */
    5551} POSIX_Timer_Control;
    5652
    5753/*
    58  * Array of Timers
     54 *  _POSIX_Timers_Manager_initialization
     55 *
     56 *  DESCRIPTION:
     57 *
     58 *  This routine performs the initialization necessary for this manager.
    5959 */
    6060
    61 extern int timer_max;
    62 extern POSIX_Timer_Control *timer_struct;
     61void _POSIX_Timer_Manager_initialization ( int max_timers );
    6362
    6463/*
     
    6766 */
    6867
    69 RTEMS_EXTERN Objects_Information  _POSIX_Timer_Information;
     68POSIX_EXTERN Objects_Information  _POSIX_Timer_Information;
    7069
    7170#ifndef __RTEMS_APPLICATION__
  • cpukit/posix/preinstall.am

    r7c99007 r0243b0d  
    8484        $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/posix/pthread.h
    8585PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/posix/pthread.h
    86 
    87 $(PROJECT_INCLUDE)/rtems/posix/ptimer.h: include/rtems/posix/ptimer.h $(PROJECT_INCLUDE)/rtems/posix/$(dirstamp)
    88         $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/posix/ptimer.h
    89 PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/posix/ptimer.h
    9086
    9187$(PROJECT_INCLUDE)/rtems/posix/semaphore.h: include/rtems/posix/semaphore.h $(PROJECT_INCLUDE)/rtems/posix/$(dirstamp)
  • cpukit/posix/src/ptimer.c

    r7c99007 r0243b0d  
    3333#include <signal.h>
    3434
    35 /*****************************/
    36 /* End of necessary includes */
    37 /*****************************/
    38 
    3935#include <rtems/posix/timer.h>
    4036
    41 /* ***************************************************************************
    42  * TIMER_INITIALIZE_S
    43  *
    44  *  Description: Initialize the data of a timer
    45  * ***************************************************************************/
    46 
    47 void TIMER_INITIALIZE_S ( int timer_pos )
    48 {
    49 
    50    /*
    51     * Indicates that the position in the table is free
    52     */
    53 
    54     timer_struct[timer_pos].state = STATE_FREE_C;
    55 
    56    /*
    57     * The initial data of timing are set with null value
    58     */
    59 
    60     timer_struct[timer_pos].timer_data.it_value.tv_sec     = 0;
    61     timer_struct[timer_pos].timer_data.it_value.tv_nsec    = 0;
    62     timer_struct[timer_pos].timer_data.it_interval.tv_sec  = 0;
    63     timer_struct[timer_pos].timer_data.it_interval.tv_nsec = 0;
    64 
    65    /*
    66     * The count of expirations is 0
    67     */
    68 
    69     timer_struct[timer_pos].overrun = 0;
    70 
    71 }
    72 
    73 /* ***************************************************************************
     37/*
    7438 * _POSIX_Timer_Manager_initialization
    7539 *
    7640 *  Description: Initialize the internal structure in which the data of all
    7741 *               the timers are stored
    78  * ***************************************************************************/
     42 */
    7943
    80 int timer_max;
    81 POSIX_Timer_Control *timer_struct;
    82 
    83 
    84 void _POSIX_Timer_Manager_initialization ( int max_timers )
     44void _POSIX_Timer_Manager_initialization ( int maximum_timers )
    8545{
    86    int index;
    87 
    88    timer_struct = _Workspace_Allocate_or_fatal_error(
    89       max_timers * sizeof(POSIX_Timer_Control) );
    90 
    91    /*
    92     *  Initialize all the timers
    93     */
    94 
    95    timer_max = max_timers;
    96 
    97    for (index=0; index<max_timers; index++)
    98      TIMER_INITIALIZE_S( index );
    99 
    100    timer_max = max_timers;
     46  _Objects_Initialize_information(
     47    &_POSIX_Timer_Information,  /* object information table */
     48    OBJECTS_POSIX_API,          /* object API */
     49    OBJECTS_POSIX_TIMERS,       /* object class */
     50    maximum_timers,             /* maximum objects of this class */
     51    sizeof( POSIX_Timer_Control ),
     52                                /* size of this object's control block */
     53    FALSE,                      /* TRUE if names for this object are strings */
     54    _POSIX_PATH_MAX             /* maximum length of each object's name */
     55#if defined(RTEMS_MULTIPROCESSING)
     56    ,
     57    FALSE,                      /* TRUE if this is a global object class */
     58    NULL                        /* Proxy extraction support callout */
     59#endif
     60  );
    10161}
  • cpukit/posix/src/ptimer1.c

    r7c99007 r0243b0d  
    2828#include <rtems/rtems/clock.h>
    2929#include <rtems/posix/psignal.h>
    30 #include <rtems/score/wkspace.h>
    3130#include <pthread.h>
    3231#include <stdio.h>
     
    3635#include <rtems/posix/timer.h>
    3736
    38 /*****************************/
    39 /* End of necessary includes */
    40 /*****************************/
    41 
    42 /* ************
    43  * Constants
    44  * ************/
    45 
    46 /*
    47 #define DEBUG_MESSAGES
    48  */
    49 
    50 /*
    51  * Data for the signals
    52  */
    53 
    54 /***********************************
    55  * Definition of Internal Functions
    56  ***********************************/
    57 
    58 /* ***************************************************************************
    59  * TIMER_INITIALIZE_S
    60  *
    61  *  Description: Initialize the data of a timer
    62  * ***************************************************************************/
    63 
    64 extern void TIMER_INITIALIZE_S ( int timer_pos );
    65 
    66 /* ***************************************************************************
    67  * _POSIX_Timer_Manager_initialization
    68  *
    69  *  Description: Initialize the internal structure in which the data of all
    70  *               the timers are stored
    71  * ***************************************************************************/
    72 
    73 /* split to reduce minimum size */
    74 
    75 /* ***************************************************************************
    76  * FIRST_FREE_POSITION_F
    77  *
    78  *  Description: Returns the first free position in the table of timers.
    79  *               If there is not a free position, it returns NO_MORE_TIMERS_C
    80  * ***************************************************************************/
    81 
    82 int FIRST_FREE_POSITION_F ()
    83 {
    84    int index;
    85 
    86    for (index=0; index<timer_max; index++) {
    87       if ( timer_struct[index].state == STATE_FREE_C ) {
    88          return index;
    89       }
    90    }
    91 
    92    /* The function reaches this point only if all the position are occupied */
    93 
    94    return NO_MORE_TIMERS_C;
    95 }
    96 
    97 /* ***************************************************************************
    98  * TIMER_POSITION_F
    99  *
    100  *  Description: Returns the position in the table of timers in which the
    101  *               data of the timer are stored.
    102  *               If the timer identifier does not exist, it returns
    103  *               BAD_TIMER_C
    104  * ***************************************************************************/
    105 
    106 int TIMER_POSITION_F ( timer_t timer_id )
    107 {
    108   int index;
    109 
    110   for (index=0; index<timer_max; index++ ) {
    111 
    112      /* Looks for the position of the timer. The timer must exist and the
    113       * position can not be free */
    114      if ( ( timer_struct[index].timer_id == timer_id ) &&
    115           ( timer_struct[index].state != STATE_FREE_C ) ) {
    116         return index;
    117      }
    118   }
    119 
    120   /* If the function reaches this point is because the timer identifier
    121    * is not correct */
    122 
    123    return BAD_TIMER_C;
    124 
    125 }
    126 
    127 /* ***************************************************************************
    128  * COPY_ITIMERSPEC_S
    129  *
    130  *  Description: Does a copy of a variable of type struct itimerspec
    131  * ***************************************************************************/
    132 
    133 void COPY_ITIMERSPEC_S ( const struct itimerspec *source,
    134                          struct itimerspec *target )
    135 {
    136 
    137    target->it_value.tv_sec     = source->it_value.tv_sec;
    138    target->it_value.tv_nsec    = source->it_value.tv_nsec;
    139    target->it_interval.tv_sec  = source->it_interval.tv_sec;
    140    target->it_interval.tv_nsec = source->it_interval.tv_nsec;
    141 
    142 }
    143 
    144 /* ***************************************************************************
     37boolean _Watchdog_Insert_ticks_helper(
     38  Watchdog_Control               *timer,
     39  Watchdog_Interval               ticks,
     40  Objects_Id                      id,
     41  Watchdog_Service_routine_entry  TSR,
     42  void                           *arg
     43)
     44{
     45  ISR_Level            level;
     46
     47  (void) _Watchdog_Remove( timer );
     48  _ISR_Disable( level );
     49
     50    /*
     51     *  Check to see if the watchdog has just been inserted by a
     52     *  higher priority interrupt.  If so, abandon this insert.
     53     */
     54    if ( timer->state != WATCHDOG_INACTIVE ) {
     55      _ISR_Enable( level );
     56      return FALSE;
     57    }
     58
     59    /*
     60     *  OK.  Now we now the timer was not rescheduled by an interrupt
     61     *  so we can atomically initialize it as in use.
     62     */
     63    _Watchdog_Initialize( timer, TSR, id, arg );
     64    _Watchdog_Insert_ticks( timer, ticks );
     65  _ISR_Enable( level );
     66  return TRUE;
     67}
     68
     69/* #define DEBUG_MESSAGES */
     70
     71/*
    14572 * ITIMERSPEC_TO_RTEMS_TIME_OF_DAY_S
    14673 *
    14774 *  Description: This function converts the data of a structure itimerspec
    14875 *               into structure rtems_time_of_day
    149  * ***************************************************************************/
    150 
    151 void ITIMERSPEC_TO_RTEMS_TIME_OF_DAY_S
    152    ( const struct itimerspec *itimer, rtems_time_of_day *rtems_time )
     76  */
     77
     78void ITIMERSPEC_TO_RTEMS_TIME_OF_DAY_S(
     79  const struct itimerspec *itimer,
     80  rtems_time_of_day *rtems_time
     81)
    15382{
    15483   unsigned long int seconds;
    15584
    15685   /* The leap years and the months with 28, 29 or 31 days have not been
    157     * considerated. It will be made in the future */
     86    * considered. It will be made in the future */
    15887
    15988   seconds            = itimer->it_value.tv_sec;
     
    183112
    184113/* ***************************************************************************
    185  * FIRE_TIMER_S
     114 * _POSIX_Timer_TSR
    186115 *
    187116 *  Description: This is the operation that is ran when a timer expires
     
    189118
    190119
    191 rtems_timer_service_routine FIRE_TIMER_S (rtems_id timer, void *data)
    192 {
    193   int               timer_pos;  /* Position in the table of the timer that
    194                                  *  has expirated                            */
    195   rtems_status_code return_v;   /* Return value of rtems_timer_fire_after    */
    196   int               sig_number; /* Number of the signal to send              */
    197 
    198 
    199   /* The position of the table of timers that contains the data of the
    200    * expired timer will be stored in "timer_pos". In theory a timer can not
    201    * expire if it has not been created or has been deleted */
    202 
    203   timer_pos = TIMER_POSITION_F(timer);
    204 
    205   /* Increases the number of expiration of the timer in one unit. */
    206   timer_struct[timer_pos].overrun = timer_struct[timer_pos].overrun + 1;
    207 
    208 
    209   if ( ( timer_struct[timer_pos].timer_data.it_interval.tv_sec  != 0 ) ||
    210        ( timer_struct[timer_pos].timer_data.it_interval.tv_nsec != 0 ) ) {
    211 
    212      /* The timer must be reprogrammed */
    213 
    214      return_v = rtems_timer_fire_after ( timer,
    215                                         timer_struct[timer_pos].ticks,
    216                                         FIRE_TIMER_S,
    217                                         NULL );
    218 
    219      /* Stores the time when the timer was started again */
    220 
    221      timer_struct[timer_pos].time = _TOD_Current;
    222 
    223      /* The state has not to be actualized, because nothing modifies it */
    224 
    225      timer_struct[timer_pos].state = STATE_CREATE_RUN_C;
    226 
     120void _POSIX_Timer_TSR(Objects_Id timer, void *data)
     121{
     122  POSIX_Timer_Control *ptimer;
     123  boolean              activated;
     124
     125  ptimer = (POSIX_Timer_Control *)data;
     126
     127  /* Increment the number of expirations. */
     128  ptimer->overrun = ptimer->overrun + 1;
     129  /* The timer must be reprogrammed */
     130  if ( ( ptimer->timer_data.it_interval.tv_sec  != 0 ) ||
     131       ( ptimer->timer_data.it_interval.tv_nsec != 0 ) ) {
     132#if 0
     133    status = rtems_timer_fire_after(
     134         ptimer->timer_id, ptimer->ticks, _POSIX_Timer_TSR, ptimer );
     135#endif
     136    activated = _Watchdog_Insert_ticks_helper(
     137      &ptimer->Timer,
     138      ptimer->ticks,
     139      ptimer->Object.id,
     140      _POSIX_Timer_TSR,
     141      ptimer
     142    );
     143    if ( !activated )
     144      return;
     145
     146    /* Store the time when the timer was started again */
     147    ptimer->time = _TOD_Current;
     148
     149    /* The state really did not change but just to be safe */
     150    ptimer->state = STATE_CREATE_RUN_C;
    227151  } else {
    228      /* Indicates that the timer is stopped */
    229 
    230      timer_struct[timer_pos].state = STATE_CREATE_STOP_C;
    231 
     152   /* Indicates that the timer is stopped */
     153   ptimer->state = STATE_CREATE_STOP_C;
    232154  }
    233155
     
    237159   */
    238160
    239   sig_number = timer_struct[timer_pos].inf.sigev_signo;
    240 
    241   if( pthread_kill ( timer_struct[timer_pos].thread_id ,
    242                      timer_struct[timer_pos].inf.sigev_signo ) ) {
    243      /* XXX error handling */
    244   }
    245 
    246   /*
    247    * After the signal handler returns, the count of expirations of the
     161  if ( pthread_kill ( ptimer->thread_id, ptimer->inf.sigev_signo ) ) {
     162    /* XXX error handling */
     163  }
     164
     165  /* After the signal handler returns, the count of expirations of the
    248166   * timer must be set to 0.
    249167   */
    250 
    251   timer_struct[timer_pos].overrun = 0;
    252 
     168  ptimer->overrun = 0;
    253169}
    254170
     
    267183)
    268184{
    269 
    270   rtems_status_code return_v;  /* return value of the operation    */
    271   rtems_id          timer_id;  /* created timer identifier         */
    272   int               timer_pos; /* Position in the table of timers  */
     185  POSIX_Timer_Control *ptimer;
    273186
    274187  if ( clock_id != CLOCK_REALTIME )
     
    295208  }
    296209
    297  /*
    298   *  A timer is created using the primitive rtems_timer_create
    299   */
    300 
    301   return_v = rtems_timer_create ( clock_id, &timer_id );
    302 
    303   switch (return_v) {
    304      case RTEMS_SUCCESSFUL :
    305 
    306        /*
    307         * The timer has been created properly
    308         */
    309 
    310         /* Obtains the first free position in the table of timers */
    311 
    312         timer_pos = FIRST_FREE_POSITION_F();
    313 
    314         if ( timer_pos == NO_MORE_TIMERS_C ) {
    315            /* There is not position for another timers in spite of RTEMS
    316             * supports it. It will necessaty to increase the structure used */
    317 
    318            rtems_set_errno_and_return_minus_one( EAGAIN );
    319         }
    320 
    321         /* Exit parameter */
    322 
    323         *timerid  = timer_id;
    324 
    325         /* The data of the created timer are stored to use them later */
    326 
    327         timer_struct[timer_pos].state     = STATE_CREATE_NEW_C;
    328 
    329         /* NEW VERSION*/
    330         timer_struct[timer_pos].thread_id = pthread_self ();
    331 
    332         if ( evp != NULL ) {
    333            timer_struct[timer_pos].inf.sigev_notify = evp->sigev_notify;
    334            timer_struct[timer_pos].inf.sigev_signo  = evp->sigev_signo;
    335            timer_struct[timer_pos].inf.sigev_value  = evp->sigev_value;
    336         }
    337 
    338         timer_struct[timer_pos].timer_id = timer_id;
    339         timer_struct[timer_pos].overrun  = 0;
    340 
    341         timer_struct[timer_pos].timer_data.it_value.tv_sec     = 0;
    342         timer_struct[timer_pos].timer_data.it_value.tv_nsec    = 0;
    343         timer_struct[timer_pos].timer_data.it_interval.tv_sec  = 0;
    344         timer_struct[timer_pos].timer_data.it_interval.tv_nsec = 0;
    345 
    346         return 0;
    347 
    348      case RTEMS_INVALID_NAME : /* The assigned name is not valid */
    349 
    350        rtems_set_errno_and_return_minus_one( EINVAL );
    351 
    352      case RTEMS_TOO_MANY :
    353 
    354        /* There has been created too much timers for the same process */
    355        rtems_set_errno_and_return_minus_one( EAGAIN );
    356 
    357      default :
    358 
    359        /*
    360         * Does nothing. It only returns the error without assigning a value
    361         * to errno. In theory, it can not happen because the call to
    362         * rtems_timer_create can not return other different value.
    363         */
    364 
    365        rtems_set_errno_and_return_minus_one( EINVAL );
    366   }
     210  _Thread_Disable_dispatch();         /* to prevent deletion */
    367211
    368212  /*
    369    * The next sentence is used to avoid singular situations
     213   *  Allocate a timer
    370214   */
    371 
    372   rtems_set_errno_and_return_minus_one( EINVAL );
     215  ptimer = _POSIX_Timer_Allocate();
     216  if ( !ptimer ) {
     217    _Thread_Enable_dispatch();
     218    rtems_set_errno_and_return_minus_one( EAGAIN );
     219  }
     220
     221  /* The data of the created timer are stored to use them later */
     222
     223  ptimer->state     = STATE_CREATE_NEW_C;
     224  ptimer->thread_id = _Thread_Executing->Object.id;
     225
     226  if ( evp != NULL ) {
     227    ptimer->inf.sigev_notify = evp->sigev_notify;
     228    ptimer->inf.sigev_signo  = evp->sigev_signo;
     229    ptimer->inf.sigev_value  = evp->sigev_value;
     230  }
     231
     232  ptimer->overrun  = 0;
     233  ptimer->timer_data.it_value.tv_sec     = 0;
     234  ptimer->timer_data.it_value.tv_nsec    = 0;
     235  ptimer->timer_data.it_interval.tv_sec  = 0;
     236  ptimer->timer_data.it_interval.tv_nsec = 0;
     237
     238  _Watchdog_Initialize( &ptimer->Timer, NULL, 0, NULL );
     239  _Objects_Open(&_POSIX_Timer_Information, &ptimer->Object, (Objects_Name) 0);
     240
     241  *timerid  = ptimer->Object.id;
     242  _Thread_Enable_dispatch();
     243  return 0;
    373244}
    374245
     
    381252)
    382253{
    383 
    384254 /*
    385255  * IDEA: This function must probably stop the timer first and then delete it
     
    390260  *       because rtems_timer_delete stops the timer before deleting it.
    391261  */
    392 
    393   int               timer_pos;
    394   rtems_status_code status;
    395 
    396 
    397    /* First the position in the table of timers is obtained */
    398 
    399    timer_pos = TIMER_POSITION_F ( timerid );
    400 
    401    if ( timer_pos == BAD_TIMER_C ) {
    402       /* The timer identifier is erroneus */
    403       rtems_set_errno_and_return_minus_one( EINVAL );
    404    }
    405 
    406    /* The timer is deleted */
    407 
    408    status = rtems_timer_delete ( timerid );
    409 
    410    if ( status == RTEMS_INVALID_ID ) {
    411      /* The timer identifier is erroneus */
    412      rtems_set_errno_and_return_minus_one( EINVAL );
    413    }
    414 
    415    /* Initializes the data of the timer */
    416 
    417    TIMER_INITIALIZE_S ( timer_pos );
    418    return 0;
     262  POSIX_Timer_Control *ptimer;
     263  Objects_Locations    location;
     264
     265  ptimer = _POSIX_Timer_Get( timerid, &location );
     266  switch ( location ) {
     267    case OBJECTS_REMOTE:
     268#if defined(RTEMS_MULTIPROCESSING)
     269      _Thread_Dispatch();
     270      rtems_set_errno_and_return_minus_one( EINVAL );
     271#endif
     272
     273    case OBJECTS_ERROR:
     274      rtems_set_errno_and_return_minus_one( EINVAL );
     275
     276    case OBJECTS_LOCAL:
     277      _Objects_Close( &_POSIX_Timer_Information, &ptimer->Object );
     278      ptimer->state = STATE_FREE_C;
     279      (void) _Watchdog_Remove( &ptimer->Timer );
     280      _POSIX_Timer_Free( ptimer );
     281      _Thread_Enable_dispatch();
     282      return 0;
     283  }
     284  return -1;   /* unreached - only to remove warnings */
    419285}
    420286
     
    435301)
    436302{
    437 
    438    rtems_status_code return_v;   /* Return of the calls to RTEMS        */
    439    int               timer_pos;  /* Position of the timer in the table  */
    440    rtems_time_of_day rtems_time; /* Time in RTEMS                       */
    441 
    442 
    443    /* First the position in the table of timers is obtained */
    444 
    445    timer_pos = TIMER_POSITION_F ( timerid );
    446 
    447    if ( timer_pos == BAD_TIMER_C ) {
    448      /* The timer identifier is erroneus */
     303  POSIX_Timer_Control *ptimer;
     304  Objects_Locations    location;
     305  boolean              activated;
     306
     307  if ( value == NULL ) {
     308    rtems_set_errno_and_return_minus_one( EINVAL );
     309  }
     310
     311  /* First, it verifies if the structure "value" is correct */
     312  if ( ( value->it_value.tv_nsec > MAX_NSEC_C ) ||
     313       ( value->it_value.tv_nsec < MIN_NSEC_C ) ) {
     314    /* The number of nanoseconds is not correct */
     315    rtems_set_errno_and_return_minus_one( EINVAL );
     316  }
     317 
     318  /* XXX check for seconds in the past */
     319
     320  if ( flags != TIMER_ABSTIME && flags != TIMER_RELATIVE_C ) {
     321    rtems_set_errno_and_return_minus_one( EINVAL );
     322  }
     323
     324  /* If the function reaches this point, then it will be necessary to do
     325   * something with the structure of times of the timer: to stop, start
     326   * or start it again
     327   */
     328
     329  ptimer = _POSIX_Timer_Get( timerid, &location );
     330  switch ( location ) {
     331    case OBJECTS_REMOTE:
     332#if defined(RTEMS_MULTIPROCESSING)
     333      _Thread_Dispatch();
     334      return -1;
    449335     rtems_set_errno_and_return_minus_one( EINVAL );
    450    }
    451 
    452    if ( value == NULL ) {
    453      /* The stucture of times of the timer is free, and then returns an
    454         error but the variable errno is not actualized */
    455 
    456      rtems_set_errno_and_return_minus_one( EINVAL );
    457    }
    458 
    459    /* If the function reaches this point, then it will be necessary to do
    460     * something with the structure of times of the timer: to stop, start
    461     * or start it again */
    462 
    463    /* First, it verifies if the timer must be stopped */
    464 
    465    if ( value->it_value.tv_sec == 0 && value->it_value.tv_nsec == 0 ) {
    466       /* The timer is stopped */
    467 
    468       return_v = rtems_timer_cancel ( timerid );
    469 
    470       /* The old data of the timer are returned */
    471 
    472       if ( ovalue )
    473         *ovalue = timer_struct[timer_pos].timer_data;
    474 
    475       /* The new data are set */
    476 
    477       timer_struct[timer_pos].timer_data = *value;
    478 
    479       /* Indicates that the timer is created and stopped */
    480 
    481       timer_struct[timer_pos].state = STATE_CREATE_STOP_C;
    482 
    483       /* Returns with success */
    484 
    485       return 0;
    486    }
    487 
    488    /*
    489     * If the function reaches this point, then the timer will have to be
    490     * initialized with new values: to start it or start it again
    491     */
    492 
    493    /* First, it verifies if the structure "value" is correct */
    494 
    495     if ( ( value->it_value.tv_nsec > MAX_NSEC_C ) ||
    496          ( value->it_value.tv_nsec < MIN_NSEC_C ) ) {
    497        /* The number of nanoseconds is not correct */
    498 
    499        rtems_set_errno_and_return_minus_one( EINVAL );
    500     }
    501 
    502    /* Then, "value" must be converted from seconds and nanoseconds to clock
    503     * ticks, to use it in the calls to RTEMS */
    504 
    505    /* It is also necessary to take in account if the time is absolute
    506     * or relative */
    507 
    508    switch (flags) {
    509       case TIMER_ABSTIME:
    510 
    511         /* The fire time is absolute:
    512          * It has to use "rtems_time_fire_when" */
    513 
    514         /* First, it converts from struct itimerspec to rtems_time_of_day */
    515 
    516         ITIMERSPEC_TO_RTEMS_TIME_OF_DAY_S ( value, &rtems_time );
    517 
    518         return_v = rtems_timer_fire_when ( timerid, &rtems_time, FIRE_TIMER_S, NULL);
    519 
    520         switch ( return_v ) {
    521            case RTEMS_SUCCESSFUL:
    522 
    523               /* The timer has been started and is running */
    524 
    525               /* Actualizes the data of the structure and
    526                * returns the old ones in "ovalue" */
    527 
    528               if ( ovalue )
    529                 *ovalue = timer_struct[timer_pos].timer_data;
    530 
    531               timer_struct[timer_pos].timer_data = *value;
    532 
    533               /* It indicates that the time is running */
    534 
    535               timer_struct[timer_pos].state = STATE_CREATE_RUN_C;
    536 
    537               /* Stores the time in which the timer was started again */
    538 
    539               timer_struct[timer_pos].time = _TOD_Current;
    540               return 0;
    541 
    542               break;
    543 
    544            case RTEMS_INVALID_ID:
    545 
    546               /* XXX error handling */
    547               break;
    548 
    549            case RTEMS_NOT_DEFINED:
    550 
    551               /* XXX error handling */
    552               break;
    553 
    554            case RTEMS_INVALID_CLOCK:
    555 
    556               /* XXX error handling */
    557               break;
    558 
    559            default: break;
    560 
    561 
    562         }
    563 
    564         break;
    565 
    566       case TIMER_RELATIVE_C:
    567 
    568         /* The fire time is relative:
    569          * It has to use "rtems_time_fire_after" */
    570 
    571         /* First, it converts from seconds and nanoseconds to ticks */
    572 
    573         /* The form in which this operation is done can produce a lost
    574          * of precision of 1 second */
    575 
    576 /*      This is the process to convert from nanoseconds to ticks
    577  *
    578  *      There is a tick every 10 miliseconds, then the nanoseconds are
    579  *      divided between 10**7. The result of this operation will be the
    580  *      number of ticks
    581  */
    582 
    583         timer_struct[timer_pos].ticks =
    584              ( SEC_TO_TICKS_C * value->it_value.tv_sec ) +
    585              ( value->it_value.tv_nsec / (NSEC_PER_SEC_C / SEC_TO_TICKS_C));
    586 
    587         return_v = rtems_timer_fire_after ( timerid,
    588                                            timer_struct[timer_pos].ticks,
    589                                            FIRE_TIMER_S,
    590                                            NULL );
    591 
    592         switch (return_v) {
    593            case RTEMS_SUCCESSFUL:
    594 
    595               /* The timer has been started and is running */
    596 
    597               /* Actualizes the data of the structure and
    598                * returns the old ones in "ovalue" */
    599 
    600               if ( ovalue )
    601                 *ovalue = timer_struct[timer_pos].timer_data;
    602 
    603               timer_struct[timer_pos].timer_data = *value;
    604 
    605               /* It indicates that the time is running */
    606 
    607               timer_struct[timer_pos].state = STATE_CREATE_RUN_C;
    608 
    609               /* Stores the time in which the timer was started again */
    610 
    611               timer_struct[timer_pos].time = _TOD_Current;
    612 
    613               return 0;
    614 
    615               break;
    616 
    617            case RTEMS_INVALID_ID:
    618 
    619               /* The timer identifier is not correct. In theory, this
    620                * situation can not occur, but the solution is easy */
    621 
    622               rtems_set_errno_and_return_minus_one( EINVAL );
    623 
    624               break;
    625 
    626            case RTEMS_INVALID_NUMBER:
    627 
    628               /* In this case, RTEMS fails because the values of timing
    629                * are incorrect */
    630 
    631               /*
    632                * I do not know if errno must be actualized
    633                *
    634                * errno = EINVAL;
    635                */
    636 
    637               rtems_set_errno_and_return_minus_one( EINVAL );
    638               break;
    639 
    640            default: break;
    641         }
    642 
    643         break;
    644 
    645       default: break;
    646 
    647         /* It does nothing, although it will be probably necessary to
    648          * return an error */
    649    }
    650 
    651    /* To avoid problems */
    652    return 0;
    653 }
    654 
     336#endif
     337
     338    case OBJECTS_ERROR:
     339      return -1;
     340
     341    case OBJECTS_LOCAL:
     342      /* First, it verifies if the timer must be stopped */
     343      if ( value->it_value.tv_sec == 0 && value->it_value.tv_nsec == 0 ) {
     344         /* Stop the timer */
     345         (void) _Watchdog_Remove( &ptimer->Timer );
     346         /* The old data of the timer are returned */
     347         if ( ovalue )
     348           *ovalue = ptimer->timer_data;
     349         /* The new data are set */
     350         ptimer->timer_data = *value;
     351         /* Indicates that the timer is created and stopped */
     352         ptimer->state = STATE_CREATE_STOP_C;
     353         /* Returns with success */
     354        _Thread_Enable_dispatch();
     355        return 0;
     356       }
     357
     358       /* absolute or relative? */
     359       switch (flags) {
     360         case TIMER_ABSTIME:
     361
     362           /* The fire time is absolute: use "rtems_time_fire_when" */
     363           /* First, it converts from struct itimerspec to rtems_time_of_day */
     364
     365#if 0
     366           ITIMERSPEC_TO_RTEMS_TIME_OF_DAY_S( value, &tod );
     367           status = rtems_timer_fire_when(
     368             ptimer->timer_id, &tod, _POSIX_Timer_TSR, ptimer);
     369#endif
     370           _Watchdog_Initialize(
     371             &ptimer->Timer, _POSIX_Timer_TSR, ptimer->Object.id, ptimer );
     372
     373           _Watchdog_Insert_seconds(
     374              &ptimer->Timer,
     375              value->it_value.tv_sec - _TOD_Seconds_since_epoch
     376           );
     377
     378           /* Returns the old ones in "ovalue" */
     379           if ( ovalue )
     380             *ovalue = ptimer->timer_data;
     381           ptimer->timer_data = *value;
     382
     383           /* Indicate that the time is running */
     384           ptimer->state = STATE_CREATE_RUN_C;
     385
     386           /* Stores the time in which the timer was started again */
     387           ptimer->time = _TOD_Current;
     388           _Thread_Enable_dispatch();
     389           return 0;
     390           break;
     391
     392         /* The fire time is relative: use "rtems_time_fire_after" */
     393         case TIMER_RELATIVE_C:
     394           /* First, convert from seconds and nanoseconds to ticks */
     395           ptimer->ticks = ( SEC_TO_TICKS_C * value->it_value.tv_sec ) +
     396                ( value->it_value.tv_nsec / (NSEC_PER_SEC_C / SEC_TO_TICKS_C));
     397
     398#if 0
     399           status = rtems_timer_fire_after(
     400             ptimer->timer_id, ptimer->ticks, _POSIX_Timer_TSR, ptimer );
     401#endif
     402           activated = _Watchdog_Insert_ticks_helper(
     403             &ptimer->Timer,
     404             ptimer->ticks,
     405             ptimer->Object.id,
     406             _POSIX_Timer_TSR,
     407             ptimer
     408           );
     409           if ( !activated )
     410             return 0;
     411
     412           /* The timer has been started and is running */
     413           /* return the old ones in "ovalue" */
     414           if ( ovalue )
     415             *ovalue = ptimer->timer_data;
     416           ptimer->timer_data = *value;
     417
     418           /* Indicate that the time is running */
     419           ptimer->state = STATE_CREATE_RUN_C;
     420           ptimer->time = _TOD_Current;
     421            _Thread_Enable_dispatch();
     422           return 0;
     423      }
     424      _Thread_Enable_dispatch();
     425      rtems_set_errno_and_return_minus_one( EINVAL );
     426  }
     427  return -1;   /* unreached - only to remove warnings */
     428}
    655429
    656430/*
     
    680454  */
    681455
    682   rtems_time_of_day current_time;
    683   int               timer_pos;
    684   uint32_t          hours;
    685   uint32_t          minutes;
    686   uint32_t          seconds;
    687   uint32_t          ticks;
    688   uint32_t          nanosec;
    689 
     456  POSIX_Timer_Control *ptimer;
     457  Objects_Locations    location;
     458  rtems_time_of_day    current_time;
     459  uint32_t             hours;
     460  uint32_t             minutes;
     461  uint32_t             seconds;
     462  uint32_t             ticks;
     463  uint32_t             nanosec;
    690464
    691465  /* Reads the current time */
    692 
    693466  current_time = _TOD_Current;
    694467
    695   timer_pos = TIMER_POSITION_F ( timerid );
    696 
    697   if ( timer_pos == BAD_TIMER_C ) {
    698     /* The timer identifier is erroneus */
    699     rtems_set_errno_and_return_minus_one( EINVAL );
    700   }
    701 
    702   /* Calculates the difference between the start time of the timer and
    703    * the current one */
    704 
    705   hours    = current_time.hour - timer_struct[timer_pos].time.hour;
    706 
    707   if ( current_time.minute < timer_struct[timer_pos].time.minute ) {
    708      minutes = 60 - timer_struct[timer_pos].time.minute + current_time.minute;
    709      hours--;
    710   } else {
    711      minutes = current_time.minute - timer_struct[timer_pos].time.minute;
    712   }
    713 
    714   if ( current_time.second < timer_struct[timer_pos].time.second ) {
    715      seconds = 60 - timer_struct[timer_pos].time.second + current_time.second;
    716      minutes--;
    717   } else {
    718      seconds = current_time.second - timer_struct[timer_pos].time.second;
    719   }
    720 
    721   if ( current_time.ticks < timer_struct[timer_pos].time.ticks ) {
    722      ticks = 100 - timer_struct[timer_pos].time.ticks + current_time.ticks;
    723      seconds--;
    724   } else {
    725      ticks = current_time.ticks - timer_struct[timer_pos].time.ticks;
    726   }
    727 
    728   /* The time that the timer is running is calculated */
    729   seconds = hours   * 60 * 60 +
    730             minutes * 60      +
    731             seconds;
    732 
    733   nanosec  = ticks * 10 *  /* msec    */
    734              1000  *       /* microsec */
    735              1000;         /* nanosec  */
    736 
    737 
    738   /* Calculates the time left before the timer finishes */
    739 
    740   value->it_value.tv_sec =
    741     timer_struct[timer_pos].timer_data.it_value.tv_sec - seconds;
    742 
    743   value->it_value.tv_nsec =
    744     timer_struct[timer_pos].timer_data.it_value.tv_nsec - nanosec;
    745 
    746 
    747   value->it_interval.tv_sec  =
    748     timer_struct[timer_pos].timer_data.it_interval.tv_sec;
    749   value->it_interval.tv_nsec =
    750     timer_struct[timer_pos].timer_data.it_interval.tv_nsec;
    751 
    752 
    753   return 0;
    754 
     468  ptimer = _POSIX_Timer_Get( timerid, &location );
     469  switch ( location ) {
     470    case OBJECTS_REMOTE:
     471#if defined(RTEMS_MULTIPROCESSING)
     472      _Thread_Dispatch();
     473      rtems_set_errno_and_return_minus_one( EINVAL );
     474#endif
     475
     476    case OBJECTS_ERROR:
     477      rtems_set_errno_and_return_minus_one( EINVAL );
     478
     479    case OBJECTS_LOCAL:
     480      /* Calculates the difference between the start time of the timer and
     481       * the current one */
     482
     483      hours    = current_time.hour - ptimer->time.hour;
     484
     485      if ( current_time.minute < ptimer->time.minute ) {
     486        minutes = 60 - ptimer->time.minute + current_time.minute;
     487        hours--;
     488      } else {
     489        minutes = current_time.minute - ptimer->time.minute;
     490      }
     491
     492      if ( current_time.second < ptimer->time.second ) {
     493        seconds = 60 - ptimer->time.second + current_time.second;
     494        minutes--;
     495      } else {
     496        seconds = current_time.second - ptimer->time.second;
     497      }
     498
     499      if ( current_time.ticks < ptimer->time.ticks ) {
     500        ticks = 100 - ptimer->time.ticks + current_time.ticks;
     501        seconds--;
     502      } else {
     503        ticks = current_time.ticks - ptimer->time.ticks;
     504      }
     505
     506      /* The time that the timer is running is calculated */
     507      seconds = hours   * 60 * 60 +
     508                minutes * 60      +
     509                seconds;
     510
     511      nanosec  = ticks * 10 *  /* msec    */
     512                 1000  *       /* microsec */
     513                 1000;         /* nanosec  */
     514
     515
     516      /* Calculates the time left before the timer finishes */
     517
     518      value->it_value.tv_sec  = ptimer->timer_data.it_value.tv_sec - seconds;
     519      value->it_value.tv_nsec = ptimer->timer_data.it_value.tv_nsec - nanosec;
     520
     521      value->it_interval.tv_sec  = ptimer->timer_data.it_interval.tv_sec;
     522      value->it_interval.tv_nsec = ptimer->timer_data.it_interval.tv_nsec;
     523
     524      _Thread_Enable_dispatch();
     525      return 0;
     526  }
     527  return -1;   /* unreached - only to remove warnings */
    755528}
    756529
     
    759532 */
    760533
    761 /* *****************
     534/*
    762535 * timer_getoverrun
    763  * *****************/
     536 *
     537 * The expiration of a timer must increase by one a counter.
     538 * After the signal handler associated to the timer finishes
     539 * its execution, _POSIX_Timer_TSR will have to set this counter to 0.
     540 */
    764541
    765542int timer_getoverrun(
     
    767544)
    768545{
    769 
    770  /*
    771   * IDEA: This function must count the times the timer expires.
    772   *
    773   *       The expiration of a timer must increase by one a counter.
    774   *       After the signal handler associated to the timer finishs
    775   *       its execution, FIRE_TIMER_S will have to set this counter to 0.
    776   */
    777 
    778   int timer_pos; /* Position of the timer in the structure     */
    779   int overrun;   /* Overflow count                             */
    780 
    781 
    782   timer_pos = TIMER_POSITION_F ( timerid );
    783 
    784   if ( timer_pos == BAD_TIMER_C ) {
    785     /* The timer identifier is erroneus */
    786     rtems_set_errno_and_return_minus_one( EINVAL );
    787   }
    788 
    789   /* The overflow count of the timer is stored in "overrun" */
    790 
    791   overrun = timer_struct[timer_pos].overrun;
    792 
    793   /* It is set to 0 */
    794 
    795   timer_struct[timer_pos].overrun = 0;
    796 
    797   return overrun;
    798 
    799 }
     546  int                  overrun;
     547  POSIX_Timer_Control *ptimer;
     548  Objects_Locations    location;
     549
     550  ptimer = _POSIX_Timer_Get( timerid, &location );
     551  switch ( location ) {
     552    case OBJECTS_REMOTE:
     553#if defined(RTEMS_MULTIPROCESSING)
     554      _Thread_Dispatch();
     555      rtems_set_errno_and_return_minus_one( EINVAL );
     556#endif
     557
     558    case OBJECTS_ERROR:
     559      rtems_set_errno_and_return_minus_one( EINVAL );
     560
     561    case OBJECTS_LOCAL:
     562      overrun = ptimer->overrun;
     563      ptimer->overrun = 0;
     564      _Thread_Enable_dispatch();
     565      return overrun;
     566  }
     567  return -1;   /* unreached - only to remove warnings */
     568}
  • cpukit/sapi/src/posixapi.c

    r7c99007 r0243b0d  
    4242#include <rtems/posix/psignal.h>
    4343#include <rtems/posix/pthread.h>
    44 #include <rtems/posix/ptimer.h>
     44#include <rtems/posix/timer.h>
    4545#include <rtems/posix/semaphore.h>
    4646#include <rtems/posix/time.h>
  • cpukit/score/include/rtems/score/object.h

    r7c99007 r0243b0d  
    250250  OBJECTS_POSIX_MUTEXES             = 6,
    251251  OBJECTS_POSIX_SEMAPHORES          = 7,
    252   OBJECTS_POSIX_CONDITION_VARIABLES = 8
     252  OBJECTS_POSIX_CONDITION_VARIABLES = 8,
     253  OBJECTS_POSIX_TIMERS              = 9
    253254} Objects_POSIX_API;
    254255
    255256/** This macro is used to generically specify the last API index. */
    256 #define OBJECTS_POSIX_CLASSES_LAST OBJECTS_POSIX_CONDITION_VARIABLES
     257#define OBJECTS_POSIX_CLASSES_LAST OBJECTS_POSIX_TIMERS
    257258
    258259/**
Note: See TracChangeset for help on using the changeset viewer.