⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 time.cxx

📁 eCos/RedBoot for勤研ARM AnywhereII(4510) 含全部源代码
💻 CXX
📖 第 1 页 / 共 2 页
字号:
    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 + -