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

📄 mlqueue.cxx

📁 ecos实时嵌入式操作系统
💻 CXX
📖 第 1 页 / 共 2 页
字号:
Cyg_Scheduler_Implementation::unique( cyg_priority priority){    CYG_REPORT_FUNCTYPE("returning %d");    CYG_REPORT_FUNCARG1("priority=%d", priority);    // Priorities are not unique    CYG_REPORT_RETVAL(true);    return true;}//==========================================================================// Support for timeslicing option#ifdef CYGSEM_KERNEL_SCHED_TIMESLICE// -------------------------------------------------------------------------voidCyg_Scheduler_Implementation::timeslice(void){#ifdef CYGDBG_KERNEL_TRACE_TIMESLICE    CYG_REPORT_FUNCTION();#endif#ifdef CYGPKG_KERNEL_SMP_SUPPORT    HAL_SMP_CPU_TYPE cpu;    HAL_SMP_CPU_TYPE cpu_count = CYG_KERNEL_CPU_COUNT();    HAL_SMP_CPU_TYPE cpu_this = CYG_KERNEL_CPU_THIS();        for( cpu = 0; cpu < cpu_count; cpu++ )    {        if( --timeslice_count[cpu] == 0 )            if( cpu == cpu_this )                timeslice_cpu();            else CYG_KERNEL_CPU_TIMESLICE_INTERRUPT( cpu, 0 );    }#else        if( --timeslice_count[CYG_KERNEL_CPU_THIS()] == 0 )        timeslice_cpu();    #endif#ifdef CYGDBG_KERNEL_TRACE_TIMESLICE    CYG_REPORT_RETURN();#endif    }// -------------------------------------------------------------------------voidCyg_Scheduler_Implementation::timeslice_cpu(void){#ifdef CYGDBG_KERNEL_TRACE_TIMESLICE    CYG_REPORT_FUNCTION();#endif    Cyg_Thread *thread = get_current_thread();    HAL_SMP_CPU_TYPE cpu_this = CYG_KERNEL_CPU_THIS();        CYG_ASSERT( queue_map != 0, "Run queue empty");    CYG_ASSERT( queue_map & (1<<CYG_THREAD_MIN_PRIORITY), "Idle thread vanished!!!");#ifdef CYGSEM_KERNEL_SCHED_TIMESLICE_ENABLE    if( thread->timeslice_enabled &&        timeslice_count[cpu_this] == 0 )#else        if( timeslice_count[cpu_this] == 0 )#endif    {        CYG_INSTRUMENT_SCHED(TIMESLICE,0,0);#ifdef CYGDBG_KERNEL_TRACE_TIMESLICE        CYG_TRACE0( true, "quantum consumed, time to reschedule" );#endif        CYG_ASSERT( get_sched_lock() > 0 , "Timeslice called with zero sched_lock");        // Only try to rotate the run queue if the current thread is running.        // Otherwise we are going to reschedule anyway.        if( thread->get_state() == Cyg_Thread::RUNNING )        {            Cyg_Scheduler *sched = &Cyg_Scheduler::scheduler;            CYG_INSTRUMENT_MLQ( TIMESLICE, thread, 0);                            CYG_ASSERTCLASS( thread, "Bad current thread");            CYG_ASSERTCLASS( sched, "Bad scheduler");                cyg_priority pri    = thread->priority;            Cyg_RunQueue *queue = &sched->run_queue[pri];#ifdef CYGPKG_KERNEL_SMP_SUPPORT            // In SMP systems we set the head of the queue to point to            // the thread immediately after the current            // thread. schedule() will then pick that thread, or one            // after it to run next.                        queue->to_head( thread->get_next() );#else                        queue->rotate();#endif                        if( queue->get_head() != thread )                sched->set_need_reschedule();            timeslice_count[cpu_this] = CYGNUM_KERNEL_SCHED_TIMESLICE_TICKS;        }    }        CYG_ASSERT( queue_map & (1<<CYG_THREAD_MIN_PRIORITY), "Idle thread vanished!!!");    CYG_ASSERT( !run_queue[CYG_THREAD_MIN_PRIORITY].empty(), "Idle thread vanished!!!");#ifdef CYGDBG_KERNEL_TRACE_TIMESLICE    CYG_REPORT_RETURN();#endif}// -------------------------------------------------------------------------__externC void cyg_scheduler_timeslice_cpu(void){    Cyg_Scheduler::scheduler.timeslice_cpu();}#endif//==========================================================================// Cyg_SchedThread_Implementation class membersCyg_SchedThread_Implementation::Cyg_SchedThread_Implementation(    CYG_ADDRWORD sched_info){    CYG_REPORT_FUNCTION();    CYG_REPORT_FUNCARG1("sched_info=%08x", sched_info);            // Set priority to the supplied value.    priority = (cyg_priority)sched_info;#ifdef CYGSEM_KERNEL_SCHED_TIMESLICE_ENABLE    // If timeslice_enabled exists, set it true by default    timeslice_enabled = true;#endif#ifdef CYGPKG_KERNEL_SMP_SUPPORT    cpu = CYG_KERNEL_CPU_NONE;#endif        CYG_REPORT_RETURN();}// -------------------------------------------------------------------------// Yield the processor to another threadvoidCyg_SchedThread_Implementation::yield(void){    CYG_REPORT_FUNCTION();            // Prevent preemption    Cyg_Scheduler::lock();    Cyg_Thread *thread  = CYG_CLASSFROMBASE(Cyg_Thread,                                            Cyg_SchedThread_Implementation,                                            this);    // Only do this if this thread is running. If it is not, there    // is no point.        if( thread->get_state() == Cyg_Thread::RUNNING )    {        // To yield we simply rotate the appropriate        // run queue to the next thread and reschedule.        CYG_INSTRUMENT_MLQ( YIELD, thread, 0);                CYG_ASSERTCLASS( thread, "Bad current thread");            Cyg_Scheduler *sched = &Cyg_Scheduler::scheduler;        CYG_ASSERTCLASS( sched, "Bad scheduler");            cyg_priority pri    = thread->priority;        Cyg_RunQueue *queue = &sched->run_queue[pri];#ifdef CYGPKG_KERNEL_SMP_SUPPORT            // In SMP systems we set the head of the queue to point to            // the thread immediately after the current            // thread. schedule() will then pick that thread, or one            // after it to run next.                        queue->to_head( thread->get_next() );#else                        queue->rotate();#endif                if( queue->get_head() != thread )            sched->set_need_reschedule();#ifdef CYGSEM_KERNEL_SCHED_TIMESLICE            // Reset the timeslice counter so that this thread gets a full            // quantum.         else Cyg_Scheduler::reset_timeslice_count();#endif    }        // Unlock the scheduler and switch threads#ifdef CYGDBG_USE_ASSERTS    // This test keeps the assertions in unlock_inner() happy if    // need_reschedule was not set above.    if( !Cyg_Scheduler::get_need_reschedule() )        Cyg_Scheduler::unlock();    else #endif        Cyg_Scheduler::unlock_reschedule();        CYG_REPORT_RETURN();}// -------------------------------------------------------------------------// Rotate the run queue at a specified priority.// (pri is the decider, not this, so the routine is static)voidCyg_SchedThread_Implementation::rotate_queue( cyg_priority pri ){    CYG_REPORT_FUNCTION();    CYG_REPORT_FUNCARG1("priority=%d", pri);            // Prevent preemption    Cyg_Scheduler::lock();    Cyg_Scheduler *sched = &Cyg_Scheduler::scheduler;    CYG_ASSERTCLASS( sched, "Bad scheduler");        Cyg_RunQueue *queue = &sched->run_queue[pri];    if ( !queue->empty() ) {        queue->rotate();        sched->set_need_reschedule();    }    // Unlock the scheduler and switch threads    Cyg_Scheduler::unlock();    CYG_REPORT_RETURN();}// -------------------------------------------------------------------------// Move this thread to the head of its queue// (not necessarily a scheduler queue)voidCyg_SchedThread_Implementation::to_queue_head( void ){    CYG_REPORT_FUNCTION();            // Prevent preemption    Cyg_Scheduler::lock();    Cyg_Thread *thread  = CYG_CLASSFROMBASE(Cyg_Thread,                                            Cyg_SchedThread_Implementation,                                            this);    CYG_ASSERTCLASS( thread, "Bad current thread");        Cyg_ThreadQueue *q = thread->get_current_queue();    if( q != NULL )        q->to_head( thread );    else if( thread->in_list() )    {        // If the queue pointer is NULL then it is on a run        // queue. Move the thread to the head of it's priority list        // and force a reschedule.                Cyg_Scheduler *sched = &Cyg_Scheduler::scheduler;        sched->run_queue[thread->priority].to_head( thread );        sched->set_need_reschedule( thread );    }    // Unlock the scheduler and switch threads    Cyg_Scheduler::unlock();    CYG_REPORT_RETURN();}//==========================================================================// Cyg_ThreadQueue_Implementation class members// -------------------------------------------------------------------------        voidCyg_ThreadQueue_Implementation::enqueue(Cyg_Thread *thread){    CYG_REPORT_FUNCTION();    CYG_REPORT_FUNCARG1("thread=%08x", thread);    CYG_INSTRUMENT_MLQ( ENQUEUE, this, thread );    #ifdef CYGIMP_KERNEL_SCHED_SORTED_QUEUES    // Insert the thread into the queue in priority order.    Cyg_Thread *qhead = get_head();    if( qhead == NULL ) add_tail( thread );    else if( qhead == qhead->get_next() )    {        // There is currently only one thread in the queue, join it        // and adjust the queue pointer to point to the highest        // priority of the two. If they are the same priority,        // leave the pointer pointing to the oldest.        qhead->insert( thread );        if( thread->priority < qhead->priority )            to_head(thread);    }    else    {        // There is more than one thread in the queue. First check        // whether we are of higher priority than the head and if        // so just jump in at the front. Also check whether we are        // lower priority than the tail and jump onto the end.        // Otherwise we really have to search the queue to find        // our place.        if( thread->priority < qhead->priority )        {            qhead->insert( thread );            to_head(thread);        }        else if( thread->priority > get_tail()->priority )        {            // We are lower priority than any thread in the queue,            // go in at the end.            add_tail( thread );        }        else        {            // Search the queue. We do this backwards so that we            // always add new threads after any that have the same            // priority.            // Because of the previous tests we know that this            // search will terminate before we hit the head of the            // queue, hence we do not need to check for that            // condition.                            Cyg_Thread *qtmp = get_tail();            // Scan the queue until we find a higher or equal            // priority thread.            while( thread->priority > qtmp->priority )                qtmp = qtmp->get_prev();            // Append ourself after the node pointed to by qtmp.                            qtmp->append( thread );        }    }#else    // Just add the thread to the tail of the list    add_tail( thread );#endif        thread->queue = CYG_CLASSFROMBASE(Cyg_ThreadQueue,                                      Cyg_ThreadQueue_Implementation,                                      this);    CYG_REPORT_RETURN();}// -------------------------------------------------------------------------Cyg_Thread *Cyg_ThreadQueue_Implementation::dequeue(void){    CYG_REPORT_FUNCTYPE("returning thread %08x");            Cyg_Thread *thread = rem_head();    CYG_INSTRUMENT_MLQ( DEQUEUE, this, thread );        if( thread != NULL )        thread->queue = NULL;    CYG_REPORT_RETVAL(thread);    return thread;}// -------------------------------------------------------------------------voidCyg_ThreadQueue_Implementation::remove( Cyg_Thread *thread ){    CYG_REPORT_FUNCTION();    CYG_REPORT_FUNCARG1("thread=%08x", thread);    CYG_INSTRUMENT_MLQ( REMOVE, this, thread );        thread->queue = NULL;    Cyg_CList_T<Cyg_Thread>::remove( thread );    CYG_REPORT_RETURN();}// -------------------------------------------------------------------------Cyg_Thread *Cyg_ThreadQueue_Implementation::highpri(void){    CYG_REPORT_FUNCTYPE("returning thread %08x");    CYG_REPORT_RETVAL(get_head());    return get_head();}// -------------------------------------------------------------------------inline voidCyg_ThreadQueue_Implementation::set_thread_queue(Cyg_Thread *thread,                                                 Cyg_ThreadQueue *tq ){    thread->queue = tq;}// -------------------------------------------------------------------------#endif// -------------------------------------------------------------------------// EOF sched/mlqueue.cxx

⌨️ 快捷键说明

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