time.cxx

来自「eCos操作系统源码」· CXX 代码 · 共 701 行 · 第 1/2 页

CXX
701
字号
    cyg_ticks_to_timespec( ticks, tp );    TIME_RETURN(0);}   //-----------------------------------------------------------------------------// Get the clocks resolutionexternC 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 timerexternC 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 valuesexternC 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 triggersexternC 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 secondsexternC 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 + =
减小字号Ctrl + -
显示快捷键?