Changeset 9f95a19 in rtems


Ignore:
Timestamp:
11/02/99 18:35:52 (24 years ago)
Author:
Joel Sherrill <joel.sherrill@…>
Branches:
4.10, 4.11, 4.8, 4.9, 5, master
Children:
cec0371
Parents:
98dca75
Message:

Split time.c into multiple files.

Files:
20 added
7 edited

Legend:

Unmodified
Added
Removed
  • c/src/exec/posix/src/Makefile.in

    r98dca75 r9f95a19  
    6363    semunlink semwait
    6464
     65TIME_C_PIECES= time posixtimespecsubtract posixtimespectointerval \
     66    posixintervaltotimespec clockgetcpuclockid clockgetenableattr \
     67    clockgetres clockgettime clocksetenableattr clocksettime nanosleep
     68
    6569C_PIECES = adasupp $(CONDITION_VARIABLE_C_PIECES) \
    6670    getpid key $(MESSAGE_QUEUE_C_PIECES) \
    6771    $(MUTEX_C_PIECES) $(PTHREAD_C_PIECES) \
    6872    $(PSIGNAL_C_PIECES) ptimer sched $(SEMAPHORE_C_PIECES) \
    69     time types unistd $(ENOSYS_C_PIECES) \
     73    $(TIME_C_PIECES) types unistd $(ENOSYS_C_PIECES) \
    7074    $(BUILD_FOR_NOW_C_PIECES)
    7175
  • c/src/exec/posix/src/mutexgetprioceiling.c

    r98dca75 r9f95a19  
    1919/*PAGE
    2020 *
    21  *  13.6.1 Mutex Initialization Scheduling Attributes, P1003.1c/Draft 10, p. 128
     21 *  13.6.2 Change the Priority Ceiling of a Mutex, P1003.1c/Draft 10, p. 131
    2222 */
    23  
    24 int pthread_mutexattr_getprioceiling(
    25   const pthread_mutexattr_t   *attr,
    26   int                         *prioceiling
     23
     24int pthread_mutex_getprioceiling(
     25  pthread_mutex_t   *mutex,
     26  int               *prioceiling
    2727)
    2828{
    29   if ( !attr || !attr->is_initialized || !prioceiling )
     29  register POSIX_Mutex_Control *the_mutex;
     30  Objects_Locations             location;
     31
     32  if ( !prioceiling )
    3033    return EINVAL;
    3134
    32   *prioceiling = attr->prio_ceiling;
    33   return 0;
     35  the_mutex = _POSIX_Mutex_Get( mutex, &location );
     36  switch ( location ) {
     37    case OBJECTS_REMOTE:
     38#if defined(RTEMS_MULTIPROCESSING)
     39      return POSIX_MP_NOT_IMPLEMENTED();   /* XXX feels questionable */
     40#endif
     41    case OBJECTS_ERROR:
     42      return EINVAL;
     43    case OBJECTS_LOCAL:
     44      *prioceiling = _POSIX_Priority_From_core(
     45        the_mutex->Mutex.Attributes.priority_ceiling
     46      );
     47      _Thread_Enable_dispatch();
     48      return 0;
     49  }
     50  return POSIX_BOTTOM_REACHED();
    3451}
  • c/src/exec/posix/src/mutexsetprioceiling.c

    r98dca75 r9f95a19  
    1919/*PAGE
    2020 *
    21  *  13.6.1 Mutex Initialization Scheduling Attributes, P1003.1c/Draft 10, p. 128
     21 *  13.6.2 Change the Priority Ceiling of a Mutex, P1003.1c/Draft 10, p. 131
    2222 */
    23  
    24 int pthread_mutexattr_setprioceiling(
    25   pthread_mutexattr_t   *attr,
    26   int                    prioceiling
     23
     24int pthread_mutex_setprioceiling(
     25  pthread_mutex_t   *mutex,
     26  int                prioceiling,
     27  int               *old_ceiling
    2728)
    2829{
    29   if ( !attr || !attr->is_initialized )
     30  register POSIX_Mutex_Control *the_mutex;
     31  Objects_Locations             location;
     32  Priority_Control              the_priority;
     33  int                           status;
     34
     35  if ( !old_ceiling )
    3036    return EINVAL;
    3137
     
    3339    return EINVAL;
    3440
    35   attr->prio_ceiling = prioceiling;
    36   return 0;
     41  the_priority = _POSIX_Priority_To_core( prioceiling );
     42
     43  /*
     44   *  Must acquire the mutex before we can change it's ceiling
     45   */
     46
     47  status = pthread_mutex_lock( mutex );
     48  if ( status )
     49    return status;
     50
     51  the_mutex = _POSIX_Mutex_Get( mutex, &location );
     52  switch ( location ) {
     53    case OBJECTS_REMOTE:
     54#if defined(RTEMS_MULTIPROCESSING)
     55      /*  XXX It feels questionable to set the ceiling on a remote mutex. */
     56      return EINVAL;
     57#endif
     58    case OBJECTS_ERROR:
     59      return EINVAL;        /* impossible to get here */
     60    case OBJECTS_LOCAL:
     61      *old_ceiling = _POSIX_Priority_From_core(
     62        the_mutex->Mutex.Attributes.priority_ceiling
     63      );
     64      the_mutex->Mutex.Attributes.priority_ceiling = the_priority;
     65      _CORE_mutex_Surrender(
     66        &the_mutex->Mutex,
     67        the_mutex->Object.id,
     68#if defined(RTEMS_MULTIPROCESSING)
     69        POSIX_Threads_mutex_MP_support
     70#else
     71        NULL
     72#endif
     73      );
     74      _Thread_Enable_dispatch();
     75      return 0;
     76  }
     77  return POSIX_BOTTOM_REACHED();
    3778}
  • c/src/exec/posix/src/time.c

    r98dca75 r9f95a19  
    1414#include <rtems/posix/seterr.h>
    1515#include <rtems/posix/time.h>
    16 
    17 /*PAGE
    18  *
    19  *  _POSIX_Timespec_subtract
    20  */
    21 
    22 void _POSIX_Timespec_subtract(
    23   const struct timespec *the_start,
    24   const struct timespec *end,
    25   struct timespec *result
    26 )
    27 {
    28   struct timespec  start_struct = *the_start;
    29   struct timespec *start = &start_struct;
    30   unsigned int nsecs_per_sec = TOD_NANOSECONDS_PER_SECOND;
    31  
    32   if (end->tv_nsec < start->tv_nsec) {
    33     int seconds = (start->tv_nsec - end->tv_nsec) / nsecs_per_sec + 1;
    34     start->tv_nsec -= nsecs_per_sec * seconds;
    35     start->tv_sec += seconds;
    36   }
    37  
    38   if (end->tv_nsec - start->tv_nsec > nsecs_per_sec) {
    39     int seconds = (start->tv_nsec - end->tv_nsec) / nsecs_per_sec;
    40     start->tv_nsec += nsecs_per_sec * seconds;
    41     start->tv_sec -= seconds;
    42   }
    43  
    44   result->tv_sec  = end->tv_sec - start->tv_sec;
    45   result->tv_nsec = end->tv_nsec - start->tv_nsec;
    46 }
    47 
    48 /*PAGE
    49  *
    50  *  _POSIX_Timespec_to_interval
    51  */
    52 
    53 Watchdog_Interval _POSIX_Timespec_to_interval(
    54   const struct timespec *time
    55 )
    56 {
    57   Watchdog_Interval  ticks;
    58 
    59   ticks  = (time->tv_sec * TOD_MICROSECONDS_PER_SECOND) /
    60              _TOD_Microseconds_per_tick;
    61 
    62   ticks += (time->tv_nsec / TOD_NANOSECONDS_PER_MICROSECOND) /
    63              _TOD_Microseconds_per_tick;
    64 
    65   if (ticks)
    66     return ticks;
    67 
    68   return 1;
    69 }
    70 
    71 /*PAGE
    72  *
    73  *  _POSIX_Interval_to_timespec
    74  */
    75  
    76 void _POSIX_Interval_to_timespec(
    77   Watchdog_Interval  ticks,
    78   struct timespec   *time
    79 )
    80 {
    81   unsigned32  usecs;
    82 
    83   usecs = ticks * _TOD_Microseconds_per_tick;
    84 
    85   time->tv_sec  = usecs / TOD_MICROSECONDS_PER_SECOND;
    86   time->tv_nsec = (usecs % TOD_MICROSECONDS_PER_SECOND) *
    87                     TOD_NANOSECONDS_PER_MICROSECOND;
    88 }
    8916
    9017/*PAGE
     
    12047}
    12148#endif
    122 
    123 /*PAGE
    124  *
    125  *  14.2.1 Clocks, P1003.1b-1993, p. 263
    126  */
    127 
    128 int clock_settime(
    129   clockid_t              clock_id,
    130   const struct timespec *tp
    131 )
    132 {
    133   struct tm         split_time;
    134   TOD_Control       tod;
    135   Watchdog_Interval seconds;
    136 
    137   assert( tp );
    138 
    139   switch ( clock_id ) {
    140  
    141     case CLOCK_REALTIME:
    142       (void) gmtime_r( &tp->tv_sec, &split_time );
    143  
    144       /*
    145        *  Convert the tm structure format to that used by the TOD Handler
    146        *
    147        *  NOTE: TOD Handler does not honor leap seconds.
    148        */
    149 
    150       tod.year   = split_time.tm_year + 1900;  /* RHS is years since 1900 */
    151       tod.month  = split_time.tm_mon + 1;      /* RHS uses 0-11 */
    152       tod.day    = split_time.tm_mday;
    153       tod.hour   = split_time.tm_hour;
    154       tod.minute = split_time.tm_min;
    155       tod.second = split_time.tm_sec;  /* RHS allows 0-61 for leap seconds */
    156 
    157       tod.ticks  = (tp->tv_nsec / TOD_NANOSECONDS_PER_MICROSECOND) /
    158                       _TOD_Microseconds_per_tick;
    159 
    160       if ( !_TOD_Validate( &tod ) )
    161         set_errno_and_return_minus_one( EINVAL );
    162  
    163       /*
    164        *  We can't use the tp->tv_sec field because it is based on
    165        *  a different EPOCH.
    166        */
    167 
    168       seconds = _TOD_To_seconds( &tod );
    169       _Thread_Disable_dispatch();
    170         _TOD_Set( &tod, seconds );
    171       _Thread_Enable_dispatch();
    172       break;
    173  
    174 #ifdef _POSIX_CPUTIME
    175     case CLOCK_PROCESS_CPUTIME:
    176       return POSIX_NOT_IMPLEMENTED();
    177       break;
    178 #endif
    179  
    180 #ifdef _POSIX_THREAD_CPUTIME
    181     case CLOCK_THREAD_CPUTIME:
    182       return POSIX_NOT_IMPLEMENTED();
    183       break;
    184 #endif
    185     default:
    186       set_errno_and_return_minus_one( EINVAL );
    187  
    188   }
    189   return 0;
    190 }
    191 
    192 /*PAGE
    193  *
    194  *  14.2.1 Clocks, P1003.1b-1993, p. 263
    195  */
    196 
    197 int clock_gettime(
    198   clockid_t        clock_id,
    199   struct timespec *tp
    200 )
    201 {
    202   ISR_Level      level;
    203   time_t         seconds;
    204   long           ticks;
    205 
    206   if ( !tp )
    207     set_errno_and_return_minus_one( EINVAL );
    208 
    209   switch ( clock_id ) {
    210 
    211     case CLOCK_REALTIME:
    212  
    213       _ISR_Disable( level );
    214         seconds = _TOD_Seconds_since_epoch;
    215         ticks   = _TOD_Current.ticks;
    216       _ISR_Enable( level );
    217  
    218       tp->tv_sec  = seconds + POSIX_TIME_SECONDS_1970_THROUGH_1988;
    219       tp->tv_nsec = ticks * _TOD_Microseconds_per_tick *
    220                       TOD_NANOSECONDS_PER_MICROSECOND;
    221       break;
    222 
    223 #ifdef _POSIX_CPUTIME
    224     case CLOCK_PROCESS_CPUTIME:
    225       /* don't base this on _Watchdog_Ticks_since_boot--duration is too short*/
    226       return POSIX_NOT_IMPLEMENTED();
    227       break;
    228 #endif
    229 
    230 #ifdef _POSIX_THREAD_CPUTIME
    231     case CLOCK_THREAD_CPUTIME:
    232       return POSIX_NOT_IMPLEMENTED();
    233       break;
    234 #endif
    235     default:
    236       set_errno_and_return_minus_one( EINVAL );
    237 
    238   }
    239   return 0;
    240 }
    241 
    242 /*PAGE
    243  *
    244  *  14.2.1 Clocks, P1003.1b-1993, p. 263
    245  */
    246 
    247 int clock_getres(
    248   clockid_t        clock_id,
    249   struct timespec *res
    250 )
    251 {
    252   if ( !res )
    253     set_errno_and_return_minus_one( EINVAL );
    254  
    255   switch ( clock_id ) {
    256  
    257     /*
    258      *  All time in rtems is based on the same clock tick.
    259      */
    260 
    261     case CLOCK_REALTIME:
    262     case CLOCK_PROCESS_CPUTIME:
    263     case CLOCK_THREAD_CPUTIME:
    264       if ( res )
    265         _POSIX_Interval_to_timespec( _TOD_Microseconds_per_tick, res );
    266       break;
    267  
    268     default:
    269       set_errno_and_return_minus_one( EINVAL );
    270  
    271   }
    272   return 0;
    273 }
    274 
    275 /*PAGE
    276  *
    277  *  14.2.5 High Resolution Sleep, P1003.1b-1993, p. 269
    278  */
    279 
    280 int nanosleep(
    281   const struct timespec  *rqtp,
    282   struct timespec        *rmtp
    283 )
    284 {
    285   Watchdog_Interval  ticks;
    286   struct timespec   *the_rqtp;
    287 
    288   if ( !rqtp )
    289     set_errno_and_return_minus_one( EINVAL );
    290 
    291   the_rqtp = (struct timespec *)rqtp;
    292 
    293   /*
    294    *  Return EAGAIN if the delay interval is negative. 
    295    *
    296    *  NOTE:  This behavior is beyond the POSIX specification. 
    297    *         FSU pthreads shares this behavior.
    298    */
    299 
    300   if ( the_rqtp->tv_sec < 0 )
    301     the_rqtp->tv_sec = 0;
    302 
    303   if ( /* the_rqtp->tv_sec < 0 || */ the_rqtp->tv_nsec < 0 )
    304     set_errno_and_return_minus_one( EAGAIN );
    305 
    306   if ( the_rqtp->tv_nsec >= TOD_NANOSECONDS_PER_SECOND )
    307     set_errno_and_return_minus_one( EINVAL );
    308  
    309   ticks = _POSIX_Timespec_to_interval( the_rqtp );
    310 
    311   /*
    312    *  This behavior is also beyond the POSIX specification but is
    313    *  consistent with the RTEMS api and yields desirable behavior.
    314    */
    315 
    316   if ( !ticks ) {
    317     _Thread_Disable_dispatch();
    318       _Thread_Yield_processor();
    319     _Thread_Enable_dispatch();
    320     if ( rmtp ) {
    321        rmtp->tv_sec = 0;
    322        rmtp->tv_nsec = 0;
    323     }
    324     return 0;
    325   }
    326  
    327   _Thread_Disable_dispatch();
    328     _Thread_Set_state(
    329       _Thread_Executing,
    330       STATES_DELAYING | STATES_INTERRUPTIBLE_BY_SIGNAL
    331     );
    332     _Watchdog_Initialize(
    333       &_Thread_Executing->Timer,
    334       _Thread_Delay_ended,
    335       _Thread_Executing->Object.id,
    336       NULL
    337     );
    338     _Watchdog_Insert_ticks( &_Thread_Executing->Timer, ticks );
    339   _Thread_Enable_dispatch();
    340 
    341   /* calculate time remaining */
    342 
    343   if ( rmtp ) {
    344     ticks -=
    345       _Thread_Executing->Timer.stop_time - _Thread_Executing->Timer.start_time;
    346 
    347     _POSIX_Interval_to_timespec( ticks, rmtp );
    348 
    349     /*
    350      *  If there is time remaining, then we were interrupted by a signal.
    351      */
    352 
    353     if ( ticks )
    354       set_errno_and_return_minus_one( EINTR );
    355   }
    356 
    357   return 0;
    358 }
    359 
    360 /*PAGE
    361  *
    362  *  20.1.3 Accessing a Process CPU-time CLock, P1003.4b/D8, p. 55
    363  */
    364 
    365 int clock_getcpuclockid(
    366   pid_t      pid,
    367   clockid_t *clock_id
    368 )
    369 {
    370   return POSIX_NOT_IMPLEMENTED();
    371 }
    372 
    373 /*PAGE
    374  *
    375  *  20.1.5 CPU-time Clock Attribute Access, P1003.4b/D8, p. 58
    376  */
    377 
    378 int clock_setenable_attr(
    379   clockid_t    clock_id,
    380   int          attr
    381 )
    382 {
    383   return POSIX_NOT_IMPLEMENTED();
    384 }
    385 
    386 /*PAGE
    387  *
    388  *  20.1.5 CPU-time Clock Attribute Access, P1003.4b/D8, p. 58
    389  */
    390 
    391 int clock_getenable_attr(
    392   clockid_t    clock_id,
    393   int         *attr
    394 )
    395 {
    396   return POSIX_NOT_IMPLEMENTED();
    397 }
  • cpukit/posix/src/mutexgetprioceiling.c

    r98dca75 r9f95a19  
    1919/*PAGE
    2020 *
    21  *  13.6.1 Mutex Initialization Scheduling Attributes, P1003.1c/Draft 10, p. 128
     21 *  13.6.2 Change the Priority Ceiling of a Mutex, P1003.1c/Draft 10, p. 131
    2222 */
    23  
    24 int pthread_mutexattr_getprioceiling(
    25   const pthread_mutexattr_t   *attr,
    26   int                         *prioceiling
     23
     24int pthread_mutex_getprioceiling(
     25  pthread_mutex_t   *mutex,
     26  int               *prioceiling
    2727)
    2828{
    29   if ( !attr || !attr->is_initialized || !prioceiling )
     29  register POSIX_Mutex_Control *the_mutex;
     30  Objects_Locations             location;
     31
     32  if ( !prioceiling )
    3033    return EINVAL;
    3134
    32   *prioceiling = attr->prio_ceiling;
    33   return 0;
     35  the_mutex = _POSIX_Mutex_Get( mutex, &location );
     36  switch ( location ) {
     37    case OBJECTS_REMOTE:
     38#if defined(RTEMS_MULTIPROCESSING)
     39      return POSIX_MP_NOT_IMPLEMENTED();   /* XXX feels questionable */
     40#endif
     41    case OBJECTS_ERROR:
     42      return EINVAL;
     43    case OBJECTS_LOCAL:
     44      *prioceiling = _POSIX_Priority_From_core(
     45        the_mutex->Mutex.Attributes.priority_ceiling
     46      );
     47      _Thread_Enable_dispatch();
     48      return 0;
     49  }
     50  return POSIX_BOTTOM_REACHED();
    3451}
  • cpukit/posix/src/mutexsetprioceiling.c

    r98dca75 r9f95a19  
    1919/*PAGE
    2020 *
    21  *  13.6.1 Mutex Initialization Scheduling Attributes, P1003.1c/Draft 10, p. 128
     21 *  13.6.2 Change the Priority Ceiling of a Mutex, P1003.1c/Draft 10, p. 131
    2222 */
    23  
    24 int pthread_mutexattr_setprioceiling(
    25   pthread_mutexattr_t   *attr,
    26   int                    prioceiling
     23
     24int pthread_mutex_setprioceiling(
     25  pthread_mutex_t   *mutex,
     26  int                prioceiling,
     27  int               *old_ceiling
    2728)
    2829{
    29   if ( !attr || !attr->is_initialized )
     30  register POSIX_Mutex_Control *the_mutex;
     31  Objects_Locations             location;
     32  Priority_Control              the_priority;
     33  int                           status;
     34
     35  if ( !old_ceiling )
    3036    return EINVAL;
    3137
     
    3339    return EINVAL;
    3440
    35   attr->prio_ceiling = prioceiling;
    36   return 0;
     41  the_priority = _POSIX_Priority_To_core( prioceiling );
     42
     43  /*
     44   *  Must acquire the mutex before we can change it's ceiling
     45   */
     46
     47  status = pthread_mutex_lock( mutex );
     48  if ( status )
     49    return status;
     50
     51  the_mutex = _POSIX_Mutex_Get( mutex, &location );
     52  switch ( location ) {
     53    case OBJECTS_REMOTE:
     54#if defined(RTEMS_MULTIPROCESSING)
     55      /*  XXX It feels questionable to set the ceiling on a remote mutex. */
     56      return EINVAL;
     57#endif
     58    case OBJECTS_ERROR:
     59      return EINVAL;        /* impossible to get here */
     60    case OBJECTS_LOCAL:
     61      *old_ceiling = _POSIX_Priority_From_core(
     62        the_mutex->Mutex.Attributes.priority_ceiling
     63      );
     64      the_mutex->Mutex.Attributes.priority_ceiling = the_priority;
     65      _CORE_mutex_Surrender(
     66        &the_mutex->Mutex,
     67        the_mutex->Object.id,
     68#if defined(RTEMS_MULTIPROCESSING)
     69        POSIX_Threads_mutex_MP_support
     70#else
     71        NULL
     72#endif
     73      );
     74      _Thread_Enable_dispatch();
     75      return 0;
     76  }
     77  return POSIX_BOTTOM_REACHED();
    3778}
  • cpukit/posix/src/time.c

    r98dca75 r9f95a19  
    1414#include <rtems/posix/seterr.h>
    1515#include <rtems/posix/time.h>
    16 
    17 /*PAGE
    18  *
    19  *  _POSIX_Timespec_subtract
    20  */
    21 
    22 void _POSIX_Timespec_subtract(
    23   const struct timespec *the_start,
    24   const struct timespec *end,
    25   struct timespec *result
    26 )
    27 {
    28   struct timespec  start_struct = *the_start;
    29   struct timespec *start = &start_struct;
    30   unsigned int nsecs_per_sec = TOD_NANOSECONDS_PER_SECOND;
    31  
    32   if (end->tv_nsec < start->tv_nsec) {
    33     int seconds = (start->tv_nsec - end->tv_nsec) / nsecs_per_sec + 1;
    34     start->tv_nsec -= nsecs_per_sec * seconds;
    35     start->tv_sec += seconds;
    36   }
    37  
    38   if (end->tv_nsec - start->tv_nsec > nsecs_per_sec) {
    39     int seconds = (start->tv_nsec - end->tv_nsec) / nsecs_per_sec;
    40     start->tv_nsec += nsecs_per_sec * seconds;
    41     start->tv_sec -= seconds;
    42   }
    43  
    44   result->tv_sec  = end->tv_sec - start->tv_sec;
    45   result->tv_nsec = end->tv_nsec - start->tv_nsec;
    46 }
    47 
    48 /*PAGE
    49  *
    50  *  _POSIX_Timespec_to_interval
    51  */
    52 
    53 Watchdog_Interval _POSIX_Timespec_to_interval(
    54   const struct timespec *time
    55 )
    56 {
    57   Watchdog_Interval  ticks;
    58 
    59   ticks  = (time->tv_sec * TOD_MICROSECONDS_PER_SECOND) /
    60              _TOD_Microseconds_per_tick;
    61 
    62   ticks += (time->tv_nsec / TOD_NANOSECONDS_PER_MICROSECOND) /
    63              _TOD_Microseconds_per_tick;
    64 
    65   if (ticks)
    66     return ticks;
    67 
    68   return 1;
    69 }
    70 
    71 /*PAGE
    72  *
    73  *  _POSIX_Interval_to_timespec
    74  */
    75  
    76 void _POSIX_Interval_to_timespec(
    77   Watchdog_Interval  ticks,
    78   struct timespec   *time
    79 )
    80 {
    81   unsigned32  usecs;
    82 
    83   usecs = ticks * _TOD_Microseconds_per_tick;
    84 
    85   time->tv_sec  = usecs / TOD_MICROSECONDS_PER_SECOND;
    86   time->tv_nsec = (usecs % TOD_MICROSECONDS_PER_SECOND) *
    87                     TOD_NANOSECONDS_PER_MICROSECOND;
    88 }
    8916
    9017/*PAGE
     
    12047}
    12148#endif
    122 
    123 /*PAGE
    124  *
    125  *  14.2.1 Clocks, P1003.1b-1993, p. 263
    126  */
    127 
    128 int clock_settime(
    129   clockid_t              clock_id,
    130   const struct timespec *tp
    131 )
    132 {
    133   struct tm         split_time;
    134   TOD_Control       tod;
    135   Watchdog_Interval seconds;
    136 
    137   assert( tp );
    138 
    139   switch ( clock_id ) {
    140  
    141     case CLOCK_REALTIME:
    142       (void) gmtime_r( &tp->tv_sec, &split_time );
    143  
    144       /*
    145        *  Convert the tm structure format to that used by the TOD Handler
    146        *
    147        *  NOTE: TOD Handler does not honor leap seconds.
    148        */
    149 
    150       tod.year   = split_time.tm_year + 1900;  /* RHS is years since 1900 */
    151       tod.month  = split_time.tm_mon + 1;      /* RHS uses 0-11 */
    152       tod.day    = split_time.tm_mday;
    153       tod.hour   = split_time.tm_hour;
    154       tod.minute = split_time.tm_min;
    155       tod.second = split_time.tm_sec;  /* RHS allows 0-61 for leap seconds */
    156 
    157       tod.ticks  = (tp->tv_nsec / TOD_NANOSECONDS_PER_MICROSECOND) /
    158                       _TOD_Microseconds_per_tick;
    159 
    160       if ( !_TOD_Validate( &tod ) )
    161         set_errno_and_return_minus_one( EINVAL );
    162  
    163       /*
    164        *  We can't use the tp->tv_sec field because it is based on
    165        *  a different EPOCH.
    166        */
    167 
    168       seconds = _TOD_To_seconds( &tod );
    169       _Thread_Disable_dispatch();
    170         _TOD_Set( &tod, seconds );
    171       _Thread_Enable_dispatch();
    172       break;
    173  
    174 #ifdef _POSIX_CPUTIME
    175     case CLOCK_PROCESS_CPUTIME:
    176       return POSIX_NOT_IMPLEMENTED();
    177       break;
    178 #endif
    179  
    180 #ifdef _POSIX_THREAD_CPUTIME
    181     case CLOCK_THREAD_CPUTIME:
    182       return POSIX_NOT_IMPLEMENTED();
    183       break;
    184 #endif
    185     default:
    186       set_errno_and_return_minus_one( EINVAL );
    187  
    188   }
    189   return 0;
    190 }
    191 
    192 /*PAGE
    193  *
    194  *  14.2.1 Clocks, P1003.1b-1993, p. 263
    195  */
    196 
    197 int clock_gettime(
    198   clockid_t        clock_id,
    199   struct timespec *tp
    200 )
    201 {
    202   ISR_Level      level;
    203   time_t         seconds;
    204   long           ticks;
    205 
    206   if ( !tp )
    207     set_errno_and_return_minus_one( EINVAL );
    208 
    209   switch ( clock_id ) {
    210 
    211     case CLOCK_REALTIME:
    212  
    213       _ISR_Disable( level );
    214         seconds = _TOD_Seconds_since_epoch;
    215         ticks   = _TOD_Current.ticks;
    216       _ISR_Enable( level );
    217  
    218       tp->tv_sec  = seconds + POSIX_TIME_SECONDS_1970_THROUGH_1988;
    219       tp->tv_nsec = ticks * _TOD_Microseconds_per_tick *
    220                       TOD_NANOSECONDS_PER_MICROSECOND;
    221       break;
    222 
    223 #ifdef _POSIX_CPUTIME
    224     case CLOCK_PROCESS_CPUTIME:
    225       /* don't base this on _Watchdog_Ticks_since_boot--duration is too short*/
    226       return POSIX_NOT_IMPLEMENTED();
    227       break;
    228 #endif
    229 
    230 #ifdef _POSIX_THREAD_CPUTIME
    231     case CLOCK_THREAD_CPUTIME:
    232       return POSIX_NOT_IMPLEMENTED();
    233       break;
    234 #endif
    235     default:
    236       set_errno_and_return_minus_one( EINVAL );
    237 
    238   }
    239   return 0;
    240 }
    241 
    242 /*PAGE
    243  *
    244  *  14.2.1 Clocks, P1003.1b-1993, p. 263
    245  */
    246 
    247 int clock_getres(
    248   clockid_t        clock_id,
    249   struct timespec *res
    250 )
    251 {
    252   if ( !res )
    253     set_errno_and_return_minus_one( EINVAL );
    254  
    255   switch ( clock_id ) {
    256  
    257     /*
    258      *  All time in rtems is based on the same clock tick.
    259      */
    260 
    261     case CLOCK_REALTIME:
    262     case CLOCK_PROCESS_CPUTIME:
    263     case CLOCK_THREAD_CPUTIME:
    264       if ( res )
    265         _POSIX_Interval_to_timespec( _TOD_Microseconds_per_tick, res );
    266       break;
    267  
    268     default:
    269       set_errno_and_return_minus_one( EINVAL );
    270  
    271   }
    272   return 0;
    273 }
    274 
    275 /*PAGE
    276  *
    277  *  14.2.5 High Resolution Sleep, P1003.1b-1993, p. 269
    278  */
    279 
    280 int nanosleep(
    281   const struct timespec  *rqtp,
    282   struct timespec        *rmtp
    283 )
    284 {
    285   Watchdog_Interval  ticks;
    286   struct timespec   *the_rqtp;
    287 
    288   if ( !rqtp )
    289     set_errno_and_return_minus_one( EINVAL );
    290 
    291   the_rqtp = (struct timespec *)rqtp;
    292 
    293   /*
    294    *  Return EAGAIN if the delay interval is negative. 
    295    *
    296    *  NOTE:  This behavior is beyond the POSIX specification. 
    297    *         FSU pthreads shares this behavior.
    298    */
    299 
    300   if ( the_rqtp->tv_sec < 0 )
    301     the_rqtp->tv_sec = 0;
    302 
    303   if ( /* the_rqtp->tv_sec < 0 || */ the_rqtp->tv_nsec < 0 )
    304     set_errno_and_return_minus_one( EAGAIN );
    305 
    306   if ( the_rqtp->tv_nsec >= TOD_NANOSECONDS_PER_SECOND )
    307     set_errno_and_return_minus_one( EINVAL );
    308  
    309   ticks = _POSIX_Timespec_to_interval( the_rqtp );
    310 
    311   /*
    312    *  This behavior is also beyond the POSIX specification but is
    313    *  consistent with the RTEMS api and yields desirable behavior.
    314    */
    315 
    316   if ( !ticks ) {
    317     _Thread_Disable_dispatch();
    318       _Thread_Yield_processor();
    319     _Thread_Enable_dispatch();
    320     if ( rmtp ) {
    321        rmtp->tv_sec = 0;
    322        rmtp->tv_nsec = 0;
    323     }
    324     return 0;
    325   }
    326  
    327   _Thread_Disable_dispatch();
    328     _Thread_Set_state(
    329       _Thread_Executing,
    330       STATES_DELAYING | STATES_INTERRUPTIBLE_BY_SIGNAL
    331     );
    332     _Watchdog_Initialize(
    333       &_Thread_Executing->Timer,
    334       _Thread_Delay_ended,
    335       _Thread_Executing->Object.id,
    336       NULL
    337     );
    338     _Watchdog_Insert_ticks( &_Thread_Executing->Timer, ticks );
    339   _Thread_Enable_dispatch();
    340 
    341   /* calculate time remaining */
    342 
    343   if ( rmtp ) {
    344     ticks -=
    345       _Thread_Executing->Timer.stop_time - _Thread_Executing->Timer.start_time;
    346 
    347     _POSIX_Interval_to_timespec( ticks, rmtp );
    348 
    349     /*
    350      *  If there is time remaining, then we were interrupted by a signal.
    351      */
    352 
    353     if ( ticks )
    354       set_errno_and_return_minus_one( EINTR );
    355   }
    356 
    357   return 0;
    358 }
    359 
    360 /*PAGE
    361  *
    362  *  20.1.3 Accessing a Process CPU-time CLock, P1003.4b/D8, p. 55
    363  */
    364 
    365 int clock_getcpuclockid(
    366   pid_t      pid,
    367   clockid_t *clock_id
    368 )
    369 {
    370   return POSIX_NOT_IMPLEMENTED();
    371 }
    372 
    373 /*PAGE
    374  *
    375  *  20.1.5 CPU-time Clock Attribute Access, P1003.4b/D8, p. 58
    376  */
    377 
    378 int clock_setenable_attr(
    379   clockid_t    clock_id,
    380   int          attr
    381 )
    382 {
    383   return POSIX_NOT_IMPLEMENTED();
    384 }
    385 
    386 /*PAGE
    387  *
    388  *  20.1.5 CPU-time Clock Attribute Access, P1003.4b/D8, p. 58
    389  */
    390 
    391 int clock_getenable_attr(
    392   clockid_t    clock_id,
    393   int         *attr
    394 )
    395 {
    396   return POSIX_NOT_IMPLEMENTED();
    397 }
Note: See TracChangeset for help on using the changeset viewer.