summaryrefslogtreecommitdiffstats
path: root/cpukit/score/inline/rtems/score
diff options
context:
space:
mode:
authorJoel Sherrill <joel.sherrill@OARcorp.com>2010-11-24 15:51:28 +0000
committerJoel Sherrill <joel.sherrill@OARcorp.com>2010-11-24 15:51:28 +0000
commit0faa9dad0768f0291cb44d8d0dcb74fd3f362cc2 (patch)
tree5fdf3fb63a7b901897891cf25b3958c9a750ed69 /cpukit/score/inline/rtems/score
parentRemove duplicate entry. (diff)
downloadrtems-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/score')
-rw-r--r--cpukit/score/inline/rtems/score/scheduler.inl139
-rw-r--r--cpukit/score/inline/rtems/score/schedulerpriority.inl286
-rw-r--r--cpukit/score/inline/rtems/score/thread.inl11
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.