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; }