diff options
author | Joel Sherrill <joel.sherrill@OARcorp.com> | 2010-11-24 15:51:28 +0000 |
---|---|---|
committer | Joel Sherrill <joel.sherrill@OARcorp.com> | 2010-11-24 15:51:28 +0000 |
commit | 0faa9dad0768f0291cb44d8d0dcb74fd3f362cc2 (patch) | |
tree | 5fdf3fb63a7b901897891cf25b3958c9a750ed69 /cpukit/score/inline/rtems | |
parent | Remove duplicate entry. (diff) | |
download | rtems-0faa9dad0768f0291cb44d8d0dcb74fd3f362cc2.tar.bz2 |
2010-11-24 Gedare Bloom <giddyup44@yahoo.com>
PR 1647/cpukit
* posix/src/nanosleep.c, posix/src/sched_yield.c,
rtems/src/taskwakeafter.c, sapi/include/confdefs.h,
sapi/include/rtems/config.h, sapi/src/exinit.c, score/Makefile.am,
score/preinstall.am, score/include/rtems/score/prioritybitmap.h,
score/include/rtems/score/thread.h,
score/inline/rtems/score/thread.inl, score/src/thread.c,
score/src/threadchangepriority.c, score/src/threadclearstate.c,
score/src/threadclose.c, score/src/threadinitialize.c,
score/src/threadready.c, score/src/threadresume.c,
score/src/threadsetpriority.c, score/src/threadsetstate.c,
score/src/threadsettransient.c, score/src/threadsuspend.c,
score/src/threadtickletimeslice.c: Refactor scheduler out of thread
handler to facilitate alternate scheduler implementations.
* score/src/threadyieldprocessor.c: Removed.
* score/src/schedulerprioritythreadschedulerupdate.c,
score/src/schedulerprioritythreadschedulerfree.c,
score/src/schedulerpriorityblock.c, score/src/scheduler.c,
score/src/schedulerprioritythreadschedulerallocate.c,
score/src/schedulerpriorityunblock.c,
score/src/schedulerpriority.c, score/src/schedulerpriorityyield.c,
score/include/rtems/score/schedulerpriority.h,
score/include/rtems/score/scheduler.h,
score/inline/rtems/score/scheduler.inl,
score/inline/rtems/score/schedulerpriority.inl: New files.
Diffstat (limited to 'cpukit/score/inline/rtems')
-rw-r--r-- | cpukit/score/inline/rtems/score/scheduler.inl | 139 | ||||
-rw-r--r-- | cpukit/score/inline/rtems/score/schedulerpriority.inl | 286 | ||||
-rw-r--r-- | cpukit/score/inline/rtems/score/thread.inl | 11 |
3 files changed, 425 insertions, 11 deletions
diff --git a/cpukit/score/inline/rtems/score/scheduler.inl b/cpukit/score/inline/rtems/score/scheduler.inl new file mode 100644 index 0000000000..4a0f10a3f3 --- /dev/null +++ b/cpukit/score/inline/rtems/score/scheduler.inl @@ -0,0 +1,139 @@ +/** + * @file rtems/score/scheduler.inl + * + * This inline file contains all of the inlined routines associated with + * the manipulation of the scheduler. + */ + +/* + * Copyright (C) 2010 Gedare Bloom. + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#ifndef _RTEMS_SCORE_SCHEDULER_H +# error "Never use <rtems/score/scheduler.inl> directly; include <rtems/score/scheduler.h> instead." +#endif + +#ifndef _RTEMS_SCORE_SCHEDULER_INL +#define _RTEMS_SCORE_SCHEDULER_INL + +/** + * @addtogroup ScoreScheduler + * @{ + */ + +/** + * The preferred method to add a new scheduler is to define the jump table + * entries and add a case to the _Scheduler_Initialize routine. + * + * Generic scheduling implementations that rely on the ready queue only can + * be found in the _Scheduler_queue_XXX functions. + * + */ + +/* Passing the Scheduler_Control* to these functions allows for multiple + * scheduler's to exist simultaneously, which could be useful on an SMP + * system. Then remote Schedulers may be accessible. How to protect such + * accesses remains an open problem. + */ + +/** @brief _Scheduler_Schedule + * + * This kernel routine implements the scheduling decision logic for + * @a the_scheduler. It does NOT dispatch. + */ +RTEMS_INLINE_ROUTINE void _Scheduler_Schedule( + Scheduler_Control *the_scheduler +) +{ + the_scheduler->operations.schedule( the_scheduler ); +} + +/** @brief _Scheduler_Yield + * + * This routine is invoked when a thread wishes to voluntarily + * transfer control of the processor to another thread. This routine + * always operates on the scheduler that 'owns' the currently executing + * thread. + */ +RTEMS_INLINE_ROUTINE void _Scheduler_Yield( void ) +{ + _Scheduler.operations.yield( &_Scheduler ); +} + +/** @brief _Scheduler_Block + * + * This routine removes @a the_thread from the scheduling decision for + * @a the_scheduler. The primary task is to remove the thread from the + * ready queue. It performs any necessary schedulering operations + * including the selection of a new heir thread. + */ +RTEMS_INLINE_ROUTINE void _Scheduler_Block( + Scheduler_Control *the_scheduler, + Thread_Control *the_thread +) +{ + the_scheduler->operations.block( the_scheduler, the_thread ); +} + +/** @brief _Scheduler_Unblock + * + * This routine adds @a the_thread to the scheduling decision for + * @a the_scheduler. The primary task is to add the thread to the + * ready queue per the schedulering policy and update any appropriate + * scheduling variables, for example the heir thread. + */ +RTEMS_INLINE_ROUTINE void _Scheduler_Unblock( + Scheduler_Control *the_scheduler, + Thread_Control *the_thread +) +{ + the_scheduler->operations.unblock( the_scheduler, the_thread ); +} + +/** @brief _Scheduler_Thread_scheduler_allocate + * + * This routine allocates @a the_thread->scheduler + */ +RTEMS_INLINE_ROUTINE void* _Scheduler_Thread_scheduler_allocate( + Scheduler_Control *the_scheduler, + Thread_Control *the_thread +) +{ + return + the_scheduler->operations.scheduler_allocate( the_scheduler, the_thread ); +} + +/** @brief _Scheduler_Thread_scheduler_free + * + * This routine frees @a the_thread->scheduler + */ +RTEMS_INLINE_ROUTINE void _Scheduler_Thread_scheduler_free( + Scheduler_Control *the_scheduler, + Thread_Control *the_thread +) +{ + return the_scheduler->operations.scheduler_free( the_scheduler, the_thread ); +} + +/** @brief _Scheduler_Thread_scheduler_update + * + * This routine updates @a the_thread->scheduler + */ +RTEMS_INLINE_ROUTINE void _Scheduler_Thread_scheduler_update( + Scheduler_Control *the_scheduler, + Thread_Control *the_thread +) +{ + the_scheduler->operations.scheduler_update( the_scheduler, the_thread ); +} + +/**@}*/ + +#endif +/* end of include file */ diff --git a/cpukit/score/inline/rtems/score/schedulerpriority.inl b/cpukit/score/inline/rtems/score/schedulerpriority.inl new file mode 100644 index 0000000000..da6de2802d --- /dev/null +++ b/cpukit/score/inline/rtems/score/schedulerpriority.inl @@ -0,0 +1,286 @@ +/** + * @file rtems/score/schedulerpriority.inl + * + * This inline file contains all of the inlined routines associated with + * the manipulation of the priority-based scheduling structures. + */ + +/* + * Copyright (C) 2010 Gedare Bloom. + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#ifndef _RTEMS_SCORE_SCHEDULERPRIORITY_H +# error "Never use <rtems/score/schedulerpriority.inl> directly; include <rtems/score/schedulerpriority.h> instead." +#endif + +#ifndef _RTEMS_SCORE_SCHEDULERPRIORITY_INL +#define _RTEMS_SCORE_SCHEDULERPRIORITY_INL + +/** + * @addtogroup ScoreScheduler + * @{ + */ + +/** @brief Scheduler priority Ready queue initialize + * + * This routine initializes @a the_ready_queue for priority-based scheduling. + */ +RTEMS_INLINE_ROUTINE void _Scheduler_priority_Ready_queue_initialize( + Scheduler_Control *the_scheduler +) { + uint32_t index; + + /* allocate ready queue structures */ + the_scheduler->ready_queues.Priority = (Chain_Control *) + _Workspace_Allocate_or_fatal_error( + (PRIORITY_MAXIMUM + 1) * sizeof(Chain_Control) + ); + + /* initialize ready queue structures */ + for( index=0; index <= PRIORITY_MAXIMUM; index++) + _Chain_Initialize_empty( &the_scheduler->ready_queues.Priority[index] ); +} + +/* + * _Scheduler_priority_Ready_queue_enqueue + * + * This routine puts @a the_thread on to the priority-based ready queue. + * + * Input parameters: + * the_thread - pointer to thread + * + * Output parameters: NONE + * + * INTERRUPT LATENCY: + */ + +RTEMS_INLINE_ROUTINE void _Scheduler_priority_Ready_queue_enqueue( + Thread_Control *the_thread +) +{ + _Priority_bit_map_Add( &the_thread->scheduler.priority->Priority_map ); + + _Chain_Append_unprotected( the_thread->scheduler.priority->ready_chain, + &the_thread->Object.Node ); +} + +/* + * _Scheduler_priority_Ready_queue_Enqueue_first + * + * This routine puts @a the_thread to the head of the ready queue. + * For priority-based ready queues, the thread will be the first thread + * at its priority level. + * + * Input parameters: + * the_thread - pointer to thread + * + * Output parameters: NONE + * + * INTERRUPT LATENCY: + */ + +RTEMS_INLINE_ROUTINE void _Scheduler_priority_Ready_queue_enqueue_first( + Thread_Control *the_thread +) +{ + _Priority_bit_map_Add( &the_thread->scheduler.priority->Priority_map ); + + _Chain_Prepend_unprotected( the_thread->scheduler.priority->ready_chain, + &the_thread->Object.Node ); +} + +/* + * _Scheduler_priority_Ready_queue_extract + * + * This routine removes a specific thread from the specified + * priority-based ready queue. + * + * Input parameters: + * the_thread - pointer to a thread control block + * + * Output parameters: NONE + * + * INTERRUPT LATENCY: NONE + */ + +RTEMS_INLINE_ROUTINE void _Scheduler_priority_Ready_queue_extract( + Thread_Control *the_thread +) +{ + Chain_Control *ready = the_thread->scheduler.priority->ready_chain; + + if ( _Chain_Has_only_one_node( ready ) ) { + _Chain_Initialize_empty( ready ); + _Priority_bit_map_Remove( &the_thread->scheduler.priority->Priority_map ); + } else + _Chain_Extract_unprotected( &the_thread->Object.Node ); +} + +/* + * _Scheduler_priority_Ready_queue_first + * + * This routines returns a pointer to the first thread on @a the_ready_queue. + * + * Input parameters: + * the_ready_queue - pointer to thread queue + * + * Output parameters: + * returns - first thread or NULL + */ + +RTEMS_INLINE_ROUTINE Thread_Control *_Scheduler_priority_Ready_queue_first( + Chain_Control *the_ready_queue +) +{ + uint32_t index = _Priority_bit_map_Get_highest(); + + if ( !_Chain_Is_empty( &the_ready_queue[ index ] ) ) + return (Thread_Control *) the_ready_queue[ index ].first; + + return NULL; +} + +/* + * _Scheduler_priority_Ready_queue_requeue + * + * This routine is invoked when a thread changes priority and should be + * moved to a different position on the ready queue. + * + * Input parameters: + * the_thread - pointer to a thread control block + * + * Output parameters: NONE + * + * INTERRUPT LATENCY: NONE + */ + +RTEMS_INLINE_ROUTINE void _Scheduler_priority_Ready_queue_requeue( + Thread_Control *the_thread +) +{ + if ( !_Chain_Has_only_one_node( + the_thread->scheduler.priority->ready_chain + ) ) { + _Chain_Extract_unprotected( &the_thread->Object.Node ); + + _Chain_Append_unprotected( the_thread->scheduler.priority->ready_chain, + &the_thread->Object.Node ); + } +} + +/* + * _Scheduler_priority_Schedule_body + * + * This kernel routine implements scheduling decision logic for priority-based + * scheduling. + * + * Input parameters: + * the_scheduler - pointer to scheduler control + * the_thread - pointer to thread control block + * + * Output parameters: NONE + * + * INTERRUPT LATENCY: + */ + +RTEMS_INLINE_ROUTINE void _Scheduler_priority_Schedule_body( + Scheduler_Control *the_scheduler +) +{ + _Thread_Heir = _Scheduler_priority_Ready_queue_first( + the_scheduler->ready_queues.Priority + ); +} + +/* + * _Scheduler_priority_Block_body + * + * This kernel routine removes the_thread from scheduling decisions based + * on simple queue extraction. + * + * Input parameters: + * the_scheduler - pointer to scheduler control + * the_thread - pointer to thread control block + * + * Output parameters: NONE + * + * INTERRUPT LATENCY: + */ + +RTEMS_INLINE_ROUTINE void _Scheduler_priority_Block_body( + Scheduler_Control *the_scheduler, + Thread_Control *the_thread +) +{ + _Scheduler_priority_Ready_queue_extract(the_thread); + + /* TODO: flash critical section */ + + if ( _Thread_Is_heir( the_thread ) ) + _Scheduler_priority_Schedule_body(the_scheduler); + + if ( _Thread_Is_executing( the_thread ) ) + _Thread_Dispatch_necessary = true; + + return; +} + +/* + * _Scheduler_priority_Unblock_body + * + * This kernel routine readies the requested thread according to the queuing + * discipline. A new heir thread may be selected. + * + * Input parameters: + * the_scheduler - pointer to scheduler control + * the_thread - pointer to thread control block + * + * Output parameters: NONE + * + * NOTE: This routine uses the "blocking" heir selection mechanism. + * This ensures the correct heir after a thread restart. + * + * INTERRUPT LATENCY: + */ + +RTEMS_INLINE_ROUTINE void _Scheduler_priority_Unblock_body ( + Scheduler_Control *the_scheduler, + Thread_Control *the_thread +) +{ + _Scheduler_priority_Ready_queue_enqueue( + the_thread + ); + + /* TODO: flash critical section */ + + /* + * If the thread that was unblocked is more important than the heir, + * then we have a new heir. This may or may not result in a + * context switch. + * + * Normal case: + * If the current thread is preemptible, then we need to do + * a context switch. + * Pseudo-ISR case: + * Even if the thread isn't preemptible, if the new heir is + * a pseudo-ISR system task, we need to do a context switch. + */ + if ( the_thread->current_priority < _Thread_Heir->current_priority ) { + _Thread_Heir = the_thread; + if ( _Thread_Executing->is_preemptible || + the_thread->current_priority == 0 ) + _Thread_Dispatch_necessary = true; + } +} + +/**@}*/ + +#endif +/* end of include file */ diff --git a/cpukit/score/inline/rtems/score/thread.inl b/cpukit/score/inline/rtems/score/thread.inl index d0a9e703f7..e700bdfb53 100644 --- a/cpukit/score/inline/rtems/score/thread.inl +++ b/cpukit/score/inline/rtems/score/thread.inl @@ -120,17 +120,6 @@ RTEMS_INLINE_ROUTINE void _Thread_Restart_self( void ) } /** - * This function returns a pointer to the highest priority - * ready thread. - */ - -RTEMS_INLINE_ROUTINE void _Thread_Calculate_heir( void ) -{ - _Thread_Heir = (Thread_Control *) - _Thread_Ready_chain[ _Priority_bit_map_Get_highest() ].first; -} - -/** * This function returns true if the floating point context of * the_thread is currently loaded in the floating point unit, and * false otherwise. |