📄 time.cxx
字号:
cyg_ticks_to_timespec( ticks, tp );
TIME_RETURN(0);
}
//-----------------------------------------------------------------------------
// Get the clocks resolution
externC int clock_getres( clockid_t clock_id, struct timespec *tp)
{
TIME_ENTRY();
if( clock_id != CLOCK_REALTIME )
TIME_RETURN(EINVAL);
if( tp == NULL )
TIME_RETURN(EINVAL);
// Get the resolution of 1 tick
cyg_ticks_to_timespec( 1, tp );
TIME_RETURN(0);
}
//==========================================================================
// Timer functions
#ifdef CYGPKG_POSIX_TIMERS
//-----------------------------------------------------------------------------
// Create a timer based on the given clock.
externC int timer_create( clockid_t clock_id,
struct sigevent *evp,
timer_t *timer_id)
{
TIME_ENTRY();
if( clock_id != CLOCK_REALTIME )
TIME_RETURN(EINVAL);
timer_mutex.lock();
posix_timer *timer;
int next = timer_next;
// Look for an unused slot in the table
while( timer_table[next].id != 0 )
{
next++;
if( next >= _POSIX_TIMER_MAX )
next = 0;
if( next == timer_next )
{
timer_mutex.unlock();
TIME_RETURN(EAGAIN);
}
}
timer = &timer_table[next];
timer_next = next;
// Make sure we never allocate a zero timer id.
while( timer->id == 0 )
{
timer_id_cookie += TIMER_ID_COOKIE_INC;
timer->id = next+timer_id_cookie;
}
if( evp == NULL )
{
// If no evp is supplied, set up the timer
// to use a default set.
timer->sigev.sigev_notify = SIGEV_SIGNAL;
timer->sigev.sigev_signo = SIGALRM;
timer->sigev.sigev_value.sival_int = timer->id;
}
else timer->sigev = *evp;
timer->alarm = new( timer->alarm_obj )
Cyg_Alarm( Cyg_Clock::real_time_clock,
alarm_action,
(CYG_ADDRWORD)timer );
timer->armed = false;
timer->overrun = 0;
*timer_id = timer->id;
timer_mutex.unlock();
TIME_RETURN(0);
}
//-----------------------------------------------------------------------------
// Delete the timer
externC int timer_delete( timer_t timerid )
{
int err = EINVAL;
TIME_ENTRY();
posix_timer *timer = &timer_table[timerid & TIMER_ID_COOKIE_MASK];
timer_mutex.lock();
if( timer->id == timerid )
{
// This is a valid timer, disable the kernel
// alarm and delete it.
// disable alarm
timer->alarm->disable();
// destroy it
timer->alarm->~Cyg_Alarm();
// Mark POSIX timer free
timer->id = 0;
err = 0;
}
timer_mutex.unlock();
TIME_RETURN( err );
}
//-----------------------------------------------------------------------------
// Set the expiration time of the timer.
externC int timer_settime( timer_t timerid, int flags,
const struct itimerspec *value,
struct itimerspec *ovalue )
{
int err = EINVAL;
TIME_ENTRY();
if( value == NULL )
TIME_RETURN(EINVAL);
// convert trigger and interval values to ticks.
cyg_tick_count trigger = cyg_timespec_to_ticks( &value->it_value, true );
cyg_tick_count interval = cyg_timespec_to_ticks( &value->it_interval, true );
posix_timer *timer = &timer_table[timerid & TIMER_ID_COOKIE_MASK];
timer_mutex.lock();
if( timer->id == timerid )
{
// disable the timer
timer->alarm->disable();
if( ovalue != NULL )
{
cyg_tick_count otrigger, ointerval;
timer->alarm->get_times( &otrigger, &ointerval );
if( timer->armed )
{
// convert absolute trigger time to interval until next trigger
otrigger -= Cyg_Clock::real_time_clock->current_value();
}
else otrigger = 0;
// convert ticks to timespecs
cyg_ticks_to_timespec( otrigger, &ovalue->it_value );
cyg_ticks_to_timespec( ointerval, &ovalue->it_interval );
}
if( trigger == 0 )
{
// Mark timer disarmed
timer->armed = false;
}
else
{
// If the ABSTIME flag is not set, add the current time
if( (flags & TIMER_ABSTIME) == 0 )
trigger += Cyg_Clock::real_time_clock->current_value();
// Set the alarm running.
timer->alarm->initialize( trigger, interval );
// Mark timer armed
timer->armed = true;
}
err = 0;
}
timer_mutex.unlock();
TIME_RETURN(err);
}
//-----------------------------------------------------------------------------
// Get current timer values
externC int timer_gettime( timer_t timerid, struct itimerspec *value )
{
int err = EINVAL;
TIME_ENTRY();
if( value == NULL )
TIME_RETURN(EINVAL);
posix_timer *timer = &timer_table[timerid & TIMER_ID_COOKIE_MASK];
timer_mutex.lock();
if( timer->id == timerid )
{
cyg_tick_count trigger, interval;
timer->alarm->get_times( &trigger, &interval );
if( timer->armed )
{
// convert absolute trigger time to interval until next trigger
trigger -= Cyg_Clock::real_time_clock->current_value();
}
else trigger = 0;
// convert ticks to timespecs
cyg_ticks_to_timespec( trigger, &value->it_value );
cyg_ticks_to_timespec( interval, &value->it_interval );
err = 0;
}
timer_mutex.unlock();
TIME_RETURN(err);
}
//-----------------------------------------------------------------------------
// Get number of missed triggers
externC int timer_getoverrun( timer_t timerid )
{
int overrun = 0;
TIME_ENTRY();
posix_timer *timer = &timer_table[timerid & TIMER_ID_COOKIE_MASK];
timer_mutex.lock();
if( timer->id == timerid )
{
overrun = timer->overrun;
}
timer_mutex.unlock();
CYG_REPORT_RETVAL(overrun);
return overrun;
}
#endif // ifdef CYGPKG_POSIX_TIMERS
//==========================================================================
// Nanosleep
// Sleep for the given time.
externC int nanosleep( const struct timespec *rqtp,
struct timespec *rmtp)
{
cyg_tick_count ticks, now, then;
TIME_ENTRY();
// check for cancellation first.
PTHREAD_TESTCANCEL();
// Fail an invalid timespec
if( !valid_timespec( rqtp ) )
TIME_RETURN(EINVAL);
// Return immediately for a zero delay.
if( rqtp->tv_sec == 0 && rqtp->tv_nsec == 0 )
TIME_RETURN(0);
// Convert timespec to ticks
ticks = cyg_timespec_to_ticks( rqtp, true );
CYG_ASSERT( ticks != 0, "Zero tick count");
Cyg_Thread *self = Cyg_Thread::self();
// Do the delay, keeping track of how long we actually slept for.
then = Cyg_Clock::real_time_clock->current_value();
self->delay( ticks );
now = Cyg_Clock::real_time_clock->current_value();
if( rmtp != NULL && (then+ticks) > now )
{
// We woke up early, return the time left.
// FIXME: strictly we only need to do this if we were woken
// by a signal.
// Calculate remaining number of ticks.
ticks -= (now-then);
cyg_ticks_to_timespec( ticks, rmtp );
}
// check if we were woken up because we were cancelled.
PTHREAD_TESTCANCEL();
TIME_RETURN(0);
}
// -------------------------------------------------------------------------
// Wait for a signal, or the given number of seconds
externC unsigned int sleep( unsigned int seconds )
{
TIME_ENTRY();
struct timespec timeout;
timeout.tv_sec = seconds;
timeout.tv_nsec = 0;
if( nanosleep( &timeout, &timeout ) != 0 )
{
CYG_REPORT_RETVAL(timeout.tv_sec);
return timeout.tv_sec;
}
TIME_RETURN(0);
}
#endif // ifdef CYGPKG_POSIX_CLOCKS
// -------------------------------------------------------------------------
// EOF time.cxx
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -