Example #1
0
int clock_settime(
  clockid_t              clock_id,
  const struct timespec *tp
)
{
  if ( !tp )
    rtems_set_errno_and_return_minus_one( EINVAL );

  if ( clock_id == CLOCK_REALTIME ) {
    if ( tp->tv_sec < TOD_SECONDS_1970_THROUGH_1988 )
      rtems_set_errno_and_return_minus_one( EINVAL );

    _Thread_Disable_dispatch();
      _TOD_Set( tp );
    _Thread_Enable_dispatch();
  }
#ifdef _POSIX_CPUTIME
  else if ( clock_id == CLOCK_PROCESS_CPUTIME_ID )
    rtems_set_errno_and_return_minus_one( ENOSYS );
#endif
#ifdef _POSIX_THREAD_CPUTIME
  else if ( clock_id == CLOCK_THREAD_CPUTIME_ID )
    rtems_set_errno_and_return_minus_one( ENOSYS );
#endif
  else
    rtems_set_errno_and_return_minus_one( EINVAL );

  return 0;
}
rtems_status_code rtems_clock_set(
  rtems_time_of_day *time_buffer
)
{
  struct timespec  newtime;

  if ( !time_buffer )
    return RTEMS_INVALID_ADDRESS;

  if ( _TOD_Validate( time_buffer ) ) {
    newtime.tv_sec = _TOD_To_seconds( time_buffer );
    newtime.tv_nsec = time_buffer->ticks *
      rtems_configuration_get_nanoseconds_per_tick();

    _Thread_Disable_dispatch();
      _TOD_Set( &newtime );
    _Thread_Enable_dispatch();
    return RTEMS_SUCCESSFUL;
  }
  return RTEMS_INVALID_CLOCK;
}
rtems_status_code rtems_clock_set(
  rtems_time_of_day *time_buffer
)
{
  struct timespec  newtime;

  if ( !time_buffer )
    return RTEMS_INVALID_ADDRESS;

  if ( _TOD_Validate( time_buffer ) ) {
    newtime.tv_sec = _TOD_To_seconds( time_buffer );
    newtime.tv_nsec = time_buffer->ticks * 
                 (_TOD_Microseconds_per_tick * TOD_NANOSECONDS_PER_MICROSECOND);

    _Thread_Disable_dispatch();
      _TOD_Set( &newtime );
    _Thread_Enable_dispatch();
    return RTEMS_SUCCESSFUL;
  }
  return RTEMS_INVALID_CLOCK;
}
int  adjtime(
  struct timeval *delta,
  struct timeval *olddelta
)
{
  struct timespec ts;
  long   adjustment;

  /*
   * Simple validations
   */
  if ( !delta )
    rtems_set_errno_and_return_minus_one( EINVAL );

  if ( delta->tv_usec >= TOD_MICROSECONDS_PER_SECOND )
    rtems_set_errno_and_return_minus_one( EINVAL );

  if ( olddelta ) {
    olddelta->tv_sec  = 0;
    olddelta->tv_usec = 0;
  }

  /* convert delta to microseconds */
  adjustment  = (delta->tv_sec * TOD_MICROSECONDS_PER_SECOND);
  adjustment += delta->tv_usec;

  /* too small to account for */
  if ( adjustment < rtems_configuration_get_microseconds_per_tick() )
    return 0;

  /*
   * This prevents context switches while we are adjusting the TOD
   */

  _Thread_Disable_dispatch();

    _TOD_Get( &ts );

    ts.tv_sec  += delta->tv_sec;
    ts.tv_nsec += delta->tv_usec * TOD_NANOSECONDS_PER_MICROSECOND;

    /* if adjustment is too much positive */
    while ( ts.tv_nsec >= TOD_NANOSECONDS_PER_SECOND ) {
      ts.tv_nsec -= TOD_NANOSECONDS_PER_SECOND;
      ts.tv_sec++;
    }

    /* if adjustment is too much negative */
    while ( ts.tv_nsec <= (-1 * TOD_NANOSECONDS_PER_SECOND) ) {
      ts.tv_nsec += TOD_NANOSECONDS_PER_SECOND;
      ts.tv_sec--;
    }

    _TOD_Set( &ts );

  _Thread_Enable_dispatch();

  /* set the user's output */
  if ( olddelta )
    *olddelta = *delta;

  return 0;
}