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

📄 thread.cxx

📁 ecos为实时嵌入式操作系统
💻 CXX
📖 第 1 页 / 共 3 页
字号:
    // Allow preemption    Cyg_Scheduler::unlock();    CYG_REPORT_RETURN();}// -------------------------------------------------------------------------// Set thread priority#ifdef CYGIMP_THREAD_PRIORITYvoidCyg_Thread::set_priority( cyg_priority new_priority ){    CYG_REPORT_FUNCTION();//    CYG_ASSERT( new_priority >=  CYG_THREAD_MAX_PRIORITY, "Priority out of range");//    CYG_ASSERT( new_priority <=  CYG_THREAD_MIN_PRIORITY, "Priority out of range");        CYG_INSTRUMENT_THREAD(PRIORITY,this,priority);            // Prevent preemption    Cyg_Scheduler::lock();    Cyg_ThreadQueue *queue = NULL;        // If running, remove from run qs    if( state == RUNNING )        Cyg_Scheduler::scheduler.rem_thread(this);    else if( state & SLEEPING )    {        // Remove thread from current queue.        queue = get_current_queue();        // if indeed we are on a queue        if ( NULL != queue ) {            CYG_CHECK_DATA_PTR(queue, "Bad queue pointer");                    remove();        }    }    Cyg_Scheduler::scheduler.deregister_thread(this);    #if CYG_SCHED_UNIQUE_PRIORITIES    // Check that there are no other threads at this priority.    // If so, leave is as it is.    CYG_ASSERT( Cyg_Scheduler::scheduler.unique(new_priority), "Priority not unique");        if( Cyg_Scheduler::scheduler.unique(new_priority) )        priority = new_priority;#else // !CYG_SCHED_UNIQUE_PRIORITIES#ifdef CYGSEM_KERNEL_SYNCH_MUTEX_PRIORITY_INHERITANCE_SIMPLE    // When we have priority inheritance, we must update the original    // priority and not the inherited one.  If the new priority is    // better than the current inherited one, then use that    // immediately. We remain in inherited state to avoid problems    // with multiple mutex inheritances.        if( priority_inherited )    {        original_priority = new_priority;        if( priority > new_priority ) priority = new_priority;    }    else priority = new_priority;    #else        priority = new_priority;#endif    #endif // CYG_SCHED_UNIQUE_PRIORITIES    Cyg_Scheduler::scheduler.register_thread(this);        // Return thread to scheduler if runnable    if( state == RUNNING )        Cyg_Scheduler::scheduler.add_thread(this);    else if ( state & SLEEPING )    {        // return to current queue        // if indeed we are on a queue        if ( NULL != queue ) {            CYG_CHECK_DATA_PTR(queue, "Bad queue pointer");            queue->enqueue(this);        }    }    // If the current thread is being reprioritized, set the    // reschedule flag to ensure that it gets rescheduled if    // necessary. (Strictly we only need to do this if the new    // priority is less than that of some other runnable thread, in    // practice checking that is as expensive as what the scheduler    // will do anyway).        if( this == Cyg_Scheduler::get_current_thread() )        Cyg_Scheduler::need_reschedule = true;        // Unlock the scheduler and maybe switch threads    Cyg_Scheduler::unlock();    CYG_REPORT_RETURN();}#endif// -------------------------------------------------------------------------// Thread delay functionvoidCyg_Thread::delay( cyg_tick_count delay){    CYG_REPORT_FUNCTION();#ifdef CYGFUN_KERNEL_THREADS_TIMER    CYG_INSTRUMENT_THREAD(DELAY,this,delay);    // Prevent preemption    Cyg_Scheduler::lock();        sleep();    set_timer( Cyg_Clock::real_time_clock->current_value()+delay, DELAY );    // Unlock the scheduler and maybe switch threads    Cyg_Scheduler::unlock();    // Clear the timeout. It is irrelevant whether the alarm has    // actually gone off or not.    clear_timer();    // and deal with anything else we must do when we return    switch( wake_reason ) {    case DESTRUCT:    case EXIT:                    exit();        break;            default:        break;    }#endif    CYG_REPORT_RETURN();}// -------------------------------------------------------------------------//#ifdef CYGPKG_KERNEL_EXCEPTIONSvoidCyg_Thread::deliver_exception(    cyg_code            exception_number,       // exception being raised    CYG_ADDRWORD        exception_info          // exception specific info    ){    if( this == Cyg_Scheduler::get_current_thread() )    {        // Delivering to current thread, probably as a result        // of a real hardware exception. Simply invoke the appropriate        // handler.        exception_control.deliver_exception( exception_number, exception_info );    }#ifdef CYGIMP_EXCEPTION_ASYNC        else    {        // Delivering to another thread, probably as a result of one thread        // invoking this function on another thread. Adjust the other thread's        // state to make it execute the exception routine when it next runs.        // At present there is an unresolved problem here. We do not know what        // state the destination thread is in. It may not be a suitable point at        // which to invoke an exception routine. In most cases the exception        // routine will be run in the scheduler thread switch code, where the world is        // in an inconsistent state. We really need to run the routine at the        // end of unlock_inner(). However this would add extra code to the scheduler,        // and require a way of storing pending exceptions. So for now this option is        // disabled and not yet implemented, it may never be.            }#endif    }#endif// -------------------------------------------------------------------------// Per-thread data support#ifdef CYGVAR_KERNEL_THREADS_DATA// Set the data map bits for each free slot in the data array.cyg_ucount32 Cyg_Thread::thread_data_map = (~CYGNUM_KERNEL_THREADS_DATA_ALL) &                                           ((1<<CYGNUM_KERNEL_THREADS_DATA_MAX)-1);cyg_ucount32Cyg_Thread::new_data_index(){    Cyg_Scheduler::lock();    cyg_ucount32 index;    CYG_ASSERT( thread_data_map != 0 , "No more thread data indexes");        // find ls set bit    HAL_LSBIT_INDEX( index, thread_data_map );    // clear the bit    thread_data_map &= ~(1<<index);        Cyg_Scheduler::unlock();    return index;}void Cyg_Thread::free_data_index( cyg_ucount32 index ){    Cyg_Scheduler::lock();    thread_data_map |= (1<<index);        Cyg_Scheduler::unlock();    }#endif// =========================================================================// Cyg_ThreadTimer member functions// -------------------------------------------------------------------------// Timer alarm function. Inspect the sleep_reason and if necessary wake// up the thread with an appropriate wake_reason.#ifdef CYGFUN_KERNEL_THREADS_TIMERvoidCyg_ThreadTimer::alarm(    Cyg_Alarm           *alarm,    CYG_ADDRWORD        data){    CYG_REPORT_FUNCTION();    Cyg_ThreadTimer *self = (Cyg_ThreadTimer *)data;    Cyg_Thread *thread = self->thread;        CYG_INSTRUMENT_THREAD(ALARM, 0, 0);        Cyg_Scheduler::lock();    Cyg_Thread::cyg_reason sleep_reason = thread->get_sleep_reason();        switch( sleep_reason ) {            case Cyg_Thread::DESTRUCT:    case Cyg_Thread::BREAK:    case Cyg_Thread::EXIT:    case Cyg_Thread::NONE:    case Cyg_Thread::WAIT:    case Cyg_Thread::DONE:        // Do nothing in any of these cases. Most are here to        // keep the compiler happy.        Cyg_Scheduler::unlock();        CYG_REPORT_RETURN();        return;    case Cyg_Thread::DELAY:        // The thread was simply delaying, unless it has been        // woken up for some other reason, wake it now.        thread->set_wake_reason(Cyg_Thread::DONE);        break;    case Cyg_Thread::TIMEOUT:        // The thread has timed out, set the wake reason to        // TIMEOUT and restart.        thread->set_wake_reason(Cyg_Thread::TIMEOUT);        break;    }    thread->wake();    Cyg_Scheduler::unlock();    CYG_REPORT_RETURN();}#endif// =========================================================================// The Idle thread// The idle thread is implemented as a single instance of the// Cyg_IdleThread class. This is so that it can be initialized before// main in a static constructor.// -------------------------------------------------------------------------// Data definitions// stack#ifdef CYGNUM_HAL_STACK_SIZE_MINIMUM# ifdef CYGNUM_KERNEL_THREADS_IDLE_STACK_SIZE#  if CYGNUM_KERNEL_THREADS_IDLE_STACK_SIZE < CYGNUM_HAL_STACK_SIZE_MINIMUM// then override the configured stack size#   undef CYGNUM_KERNEL_THREADS_IDLE_STACK_SIZE#   define CYGNUM_KERNEL_THREADS_IDLE_STACK_SIZE CYGNUM_HAL_STACK_SIZE_MINIMUM#  endif // CYGNUM_KERNEL_THREADS_IDLE_STACK_SIZE < CYGNUM_HAL_STACK_SIZE_MINIMUM# endif // CYGNUM_KERNEL_THREADS_IDLE_STACK_SIZE#endif // CYGNUM_HAL_STACK_SIZE_MINIMUMstatic char idle_thread_stack[CYGNUM_KERNEL_THREADS_IDLE_STACK_SIZE];// Loop counter for debugging/housekeepingcyg_uint32 idle_thread_loops = 1;// -------------------------------------------------------------------------// Idle thread code.voididle_thread_main( CYG_ADDRESS data ){    CYG_REPORT_FUNCTION();    for(;;)    {        idle_thread_loops++;        HAL_IDLE_THREAD_ACTION(idle_thread_loops);#if 0        // For testing, it is useful to be able to fake        // clock interrupts in the idle thread.                Cyg_Clock::real_time_clock->tick();#endif#ifdef CYGIMP_IDLE_THREAD_YIELD        // In single priority and non-preemptive systems,        // the idle thread should yield repeatedly to        // other threads.        Cyg_Thread::yield();#endif    }}// -------------------------------------------------------------------------// Idle thread classclass Cyg_IdleThread : public Cyg_Thread{public:    Cyg_IdleThread(        cyg_thread_entry        *entry,           // entry point function        CYG_ADDRWORD            entry_data,       // entry data        cyg_ucount32            stack_size = 0,   // stack size, 0 = use default        CYG_ADDRESS             stack_base = 0    // stack base, NULL = allocate        );        };// -------------------------------------------------------------------------// Idle threads constructorCyg_IdleThread::Cyg_IdleThread(    cyg_thread_entry        *entry,           // entry point function    CYG_ADDRWORD            entry_data,       // entry data    cyg_ucount32            stack_size,       // stack size, 0 = use default    CYG_ADDRESS             stack_base        // stack base, NULL = allocate    )    : Cyg_Thread( CYG_THREAD_MIN_PRIORITY,                  entry,                  entry_data,                  "Idle Thread",                  stack_base,                  stack_size){    CYG_REPORT_FUNCTION();    resume();    CYG_REPORT_RETURN();}// -------------------------------------------------------------------------// Instantiate the idle threadCyg_IdleThread idle_thread CYG_INIT_PRIORITY( IDLE_THREAD ) =Cyg_IdleThread( idle_thread_main,                0,                CYGNUM_KERNEL_THREADS_IDLE_STACK_SIZE,                CYG_ADDRESS(idle_thread_stack)    ); // -------------------------------------------------------------------------// EOF common/thread.cxx

⌨️ 快捷键说明

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