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

📄 clock.cxx

📁 ecos为实时嵌入式操作系统
💻 CXX
📖 第 1 页 / 共 2 页
字号:
//==========================================================================////      common/clock.cxx////      Clock class implementations////==========================================================================//####COPYRIGHTBEGIN####//// -------------------------------------------// The contents of this file are subject to the Cygnus eCos Public License// Version 1.0 (the "License"); you may not use this file except in// compliance with the License.  You may obtain a copy of the License at// http://sourceware.cygnus.com/ecos// // Software distributed under the License is distributed on an "AS IS"// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.  See the// License for the specific language governing rights and limitations under// the License.// // The Original Code is eCos - Embedded Cygnus Operating System, released// September 30, 1998.// // The Initial Developer of the Original Code is Cygnus.  Portions created// by Cygnus are Copyright (C) 1998,1999 Cygnus Solutions.  All Rights Reserved.// -------------------------------------------////####COPYRIGHTEND####//==========================================================================//#####DESCRIPTIONBEGIN####//// Author(s):   nickg// Contributors:        nickg// Date:        1997-09-15// Purpose:     Clock class implementation// Description: This file contains the definitions of the counter,//              clock and alarm class member functions that are common//              to all clock implementations.////####DESCRIPTIONEND####////==========================================================================#include <pkgconf/kernel.h>#include <cyg/kernel/ktypes.h>         // base kernel types#include <cyg/infra/cyg_trac.h>        // tracing macros#include <cyg/infra/cyg_ass.h>         // assertion macros#include <cyg/kernel/clock.hxx>        // our header#include <cyg/kernel/sched.hxx>        // scheduler definitions#include <cyg/kernel/thread.hxx>       // thread definitions#include <cyg/kernel/intr.hxx>         // interrupt definitions#include <cyg/kernel/sched.inl>        // scheduler inlines#include <cyg/kernel/clock.inl>        // Clock inlines// -------------------------------------------------------------------------// Static variables#ifdef CYGVAR_KERNEL_COUNTERS_CLOCKCyg_Clock *Cyg_Clock::real_time_clock = NULL;   // System real time clock#endif//==========================================================================// Constructor for counter objectCyg_Counter::Cyg_Counter(    cyg_uint32      incr    ){    CYG_REPORT_FUNCTION();    counter = 0;    increment = incr;#if defined(CYGIMP_KERNEL_COUNTERS_SINGLE_LIST)    alarm_list = NULL;    // Linear list of Alarms#elif defined(CYGIMP_KERNEL_COUNTERS_MULTI_LIST)    for(cyg_ucount32 i=0; i < CYGNUM_KERNEL_COUNTERS_MULTI_LIST_SIZE; i++) {        alarm_list[i] = NULL;    }#else#error "No CYGIMP_KERNEL_COUNTERS_x_LIST config"#endif}// -------------------------------------------------------------------------// Destructor for Counter objectCyg_Counter::~Cyg_Counter(){    CYG_REPORT_FUNCTION();}// -------------------------------------------------------------------------// #ifdef CYGDBG_USE_ASSERTSbool Cyg_Counter::check_this( cyg_assert_class_zeal zeal) const{    // check that we have a non-NULL pointer first    if( this == NULL ) return false;        switch( zeal )    {    case cyg_system_test:    case cyg_extreme:    case cyg_thorough:    case cyg_quick:    case cyg_trivial:    case cyg_none:    default:        break;    };    return true;}#endif// -------------------------------------------------------------------------// Counter tick functionvoid Cyg_Counter::tick( cyg_uint32 ticks ){//    CYG_REPORT_FUNCTION();    CYG_ASSERTCLASS( this, "Bad counter object" );    // Increment the counter in a loop so we process    // each tick separately. This is easier than trying    // to cope with a range of increments.        while( ticks-- )    {        Cyg_Scheduler::lock();        // increment the counter, note that it is        // allowed to wrap.        counter += increment;        // now check for any expired alarms        Cyg_Alarm **alarm_list_ptr;     // pointer to list#if defined(CYGIMP_KERNEL_COUNTERS_SINGLE_LIST)        alarm_list_ptr = &alarm_list;#elif defined(CYGIMP_KERNEL_COUNTERS_MULTI_LIST)        // With multiple lists, each one contains only the alarms        // that will expire at a given tick modulo the list number.        // So we only have a fraction of the alarms to check here.                alarm_list_ptr = &(alarm_list[            (counter/increment) % CYGNUM_KERNEL_COUNTERS_MULTI_LIST_SIZE ] );    #else#error "No CYGIMP_KERNEL_COUNTERS_x_LIST config"#endif        // Now that we have the list pointer, we can use common code for        // both list oragnizations.#ifdef CYGIMP_KERNEL_COUNTERS_SORT_LIST        // With a sorted alarm list, we can simply pick alarms off the        // front of the list until we find one that is in the future.                while( *alarm_list_ptr != NULL )        {            Cyg_Alarm *alarm = *alarm_list_ptr;            CYG_ASSERTCLASS(alarm, "Bad alarm in counter list" );                        if( alarm->trigger <= counter )            {                // remove alarm from list                *alarm_list_ptr = alarm->next;                if( alarm->interval != 0 )                {                    // The alarm has a retrigger interval.                    // Reset the trigger time and requeue                    // the alarm.                    alarm->trigger += alarm->interval;                    add_alarm( alarm );                }                else alarm->enabled = false;                CYG_INSTRUMENT_ALARM( CALL, this, alarm );                                // call alarm function                alarm->alarm(alarm, alarm->data);                // all done, loop            }            else break;        }#else        // With an unsorted list, we must scan the whole list for        // candidates. We move the whole list to a temporary location        // before doing this so that we are not disturbed by new        // alarms being added to the list. As we consider and        // eliminate alarms we put them onto the done_list and at the        // end we then move it back to where it belongs.                Cyg_Alarm *done_list = NULL;        Cyg_Alarm *alarm_list = *alarm_list_ptr;        *alarm_list_ptr = NULL;                while( alarm_list != NULL )        {            Cyg_Alarm *alarm = alarm_list;            CYG_ASSERTCLASS(alarm, "Bad alarm in counter list" );                        // remove alarm from list            alarm_list = alarm->next;            if( alarm->trigger <= counter )            {                if( alarm->interval != 0 )                {                    // The alarm has a retrigger interval.                    // Reset the trigger time and requeue                    // the alarm.                    alarm->trigger += alarm->interval;                    add_alarm( alarm );                }                else alarm->enabled = false;                CYG_INSTRUMENT_ALARM( CALL, this, alarm );                                // call alarm function                alarm->alarm(alarm, alarm->data);                // all done, loop            }            else            {                // add unused alarm to done list.                alarm->next = done_list;                done_list = alarm;            }        }        // Transfer any alarms that might have been added to the        // alarm list by alarm callbacks to the done list. This        // happens very rarely.        while( *alarm_list_ptr != NULL )        {            Cyg_Alarm *alarm = *alarm_list_ptr;                        *alarm_list_ptr = alarm->next;            alarm->next = done_list;            done_list = alarm;        }                // return done list to real list        *alarm_list_ptr = done_list;        #endif                Cyg_Scheduler::unlock();        }    }// -------------------------------------------------------------------------// Add an alarm to this countervoid Cyg_Counter::add_alarm( Cyg_Alarm *alarm ){    CYG_REPORT_FUNCTION();    CYG_ASSERTCLASS( this, "Bad counter object" );    CYG_ASSERTCLASS( alarm, "Bad alarm passed" );        Cyg_Scheduler::lock();    // set this now to allow an immediate handler call to manipulate    // this alarm sensibly.    alarm->enabled = true;    // Check here for an alarm that triggers now or in the past and    // call its alarm function immediately.     if( alarm->trigger <= counter )    {        CYG_INSTRUMENT_ALARM( CALL, this, alarm );        // call alarm function. Note that this is being        // called here before the add_alarm has returned.        // Note that this function may disable the alarm.                alarm->alarm(alarm, alarm->data);        // Note that this extra check on alarm->enabled is in case the        // handler function disables this alarm!        if( alarm->interval != 0 && alarm->enabled )        {            // The alarm has a retrigger interval.            // Reset the trigger interval and drop            // through to queue it.            alarm->trigger += alarm->interval;            // ensure the next alarm time is in our future, and in phase            // with the original time requested.            alarm->synchronize();        }        else        {            // The alarm is all done with, disable it            // unlock and return.            alarm->enabled = false;            Cyg_Scheduler::unlock();            return;        }    }        CYG_INSTRUMENT_ALARM( ADD, this, alarm );     {        // Find the pointer to the relevant list _after_ a retrigger        // alarm has been given its new trigger time.        Cyg_Alarm **alarm_list_ptr;     // pointer to list#if defined(CYGIMP_KERNEL_COUNTERS_SINGLE_LIST)        alarm_list_ptr = &alarm_list;#elif defined(CYGIMP_KERNEL_COUNTERS_MULTI_LIST)        // Each alarm must go into the list that covers the tick that is        // going to happen _after_ the trigger time (or at it if trigger        // happens to fall on a tick.            alarm_list_ptr = &(alarm_list[            ((alarm->trigger+increment-1)/increment) %                                CYGNUM_KERNEL_COUNTERS_MULTI_LIST_SIZE ] );    #else#error "No CYGIMP_KERNEL_COUNTERS_x_LIST config"#endif#ifdef CYGIMP_KERNEL_COUNTERS_SORT_LIST                // Now that we have the list pointer, we can use common code for        // both list oragnizations.        while( *alarm_list_ptr != NULL )        {            Cyg_Alarm *list_alarm = *alarm_list_ptr;                    CYG_ASSERTCLASS(list_alarm, "Bad alarm in counter list" );

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -