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 | |
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.
37 files changed, 1434 insertions, 164 deletions
diff --git a/cpukit/ChangeLog b/cpukit/ChangeLog index 3ee1ccc9aa..9a1cfcb872 100644 --- a/cpukit/ChangeLog +++ b/cpukit/ChangeLog @@ -1,3 +1,31 @@ +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. + 2010-11-23 Sebastian Huber <sebastian.huber@embedded-brains.de> * score/src/iterateoverthreads.c, libmisc/cpuuse/cpuusagereport.c: diff --git a/cpukit/posix/src/nanosleep.c b/cpukit/posix/src/nanosleep.c index 5031039c24..dc81a378d5 100644 --- a/cpukit/posix/src/nanosleep.c +++ b/cpukit/posix/src/nanosleep.c @@ -18,6 +18,7 @@ #include <rtems/system.h> #include <rtems/score/isr.h> +#include <rtems/score/scheduler.h> #include <rtems/score/thread.h> #include <rtems/score/tod.h> @@ -56,7 +57,7 @@ int nanosleep( if ( !ticks ) { _Thread_Disable_dispatch(); - _Thread_Yield_processor(); + _Scheduler_Yield(); _Thread_Enable_dispatch(); if ( rmtp ) { rmtp->tv_sec = 0; diff --git a/cpukit/posix/src/sched_yield.c b/cpukit/posix/src/sched_yield.c index 0925e3cbd0..b6c5c4fce4 100644 --- a/cpukit/posix/src/sched_yield.c +++ b/cpukit/posix/src/sched_yield.c @@ -19,6 +19,7 @@ #include <errno.h> #include <rtems/system.h> +#include <rtems/score/scheduler.h> #include <rtems/score/tod.h> #include <rtems/score/thread.h> #include <rtems/seterr.h> @@ -28,7 +29,7 @@ int sched_yield( void ) { _Thread_Disable_dispatch(); - _Thread_Yield_processor(); + _Scheduler_Yield(); _Thread_Enable_dispatch(); return 0; } diff --git a/cpukit/rtems/src/taskwakeafter.c b/cpukit/rtems/src/taskwakeafter.c index 85f2e6307d..2f6fecfe5d 100644 --- a/cpukit/rtems/src/taskwakeafter.c +++ b/cpukit/rtems/src/taskwakeafter.c @@ -21,6 +21,7 @@ #include <rtems/rtems/support.h> #include <rtems/rtems/modes.h> #include <rtems/score/object.h> +#include <rtems/score/scheduler.h> #include <rtems/score/stack.h> #include <rtems/score/states.h> #include <rtems/rtems/tasks.h> @@ -52,7 +53,7 @@ rtems_status_code rtems_task_wake_after( { _Thread_Disable_dispatch(); if ( ticks == 0 ) { - _Thread_Yield_processor(); + _Scheduler_Yield(); } else { _Thread_Set_state( _Thread_Executing, STATES_DELAYING ); _Watchdog_Initialize( diff --git a/cpukit/sapi/include/confdefs.h b/cpukit/sapi/include/confdefs.h index e6f8edaed2..0a1b49d173 100644 --- a/cpukit/sapi/include/confdefs.h +++ b/cpukit/sapi/include/confdefs.h @@ -535,6 +535,116 @@ rtems_fs_init_functions_t rtems_fs_init_helper = #endif /* + * Scheduler configuration. + * + * The scheduler configuration allows an application to select the + * scheduling policy to use. The supported configurations are: + * CONFIGURE_SCHEDULER_USER + * CONFIGURE_SCHEDULER_PRIORITY + * + * If no configuration is specified by the application, then + * CONFIGURE_SCHEDULER_PRIORITY is assumed to be the default. + * + * An application can define its own scheduling policy by defining + * CONFIGURE_SCHEDULER_USER and CONFIGURE_SCHEDULER_ENTRY_USER to point + * to an initialization routine. Note: CONFIGURE_SCHEDULER_USER is not + * fully supported, since it has no per-thread field. + * + * To add a new scheduler: + */ +#include <rtems/score/scheduler.h> + +#if defined(CONFIGURE_SCHEDULER_USER) && \ + !defined(CONFIGURE_SCHEDULER_ENTRY_USER) + #error "CONFIGURE_ERROR: CONFIGURE_SCHEDULER_USER without CONFIGURE_SCHEDULER_ENTRY_USER" +#endif + +/* enable all RTEMS-provided schedulers */ +#if defined(CONFIGURE_SCHEDULER_ALL) + #define CONFIGURE_SCHEDULER_PRIORITY +#endif + +/* If no scheduler is specified, the priority scheduler is default. */ +#if !defined(CONFIGURE_SCHEDULER_USER) && \ + !defined(CONFIGURE_SCHEDULER_PRIORITY) + #define CONFIGURE_SCHEDULER_PRIORITY + #define CONFIGURE_SCHEDULER_POLICY _Scheduler_PRIORITY +#endif + +/* + * If a user scheduler is specified and no policy is set, + * the user scheduler is the default policy. + */ +#if defined(CONFIGURE_SCHEDULER_USER) && \ + !defined(CONFIGURE_SCHEDULER_POLICY) + #define CONFIGURE_SCHEDULER_POLICY _Scheduler_USER +#endif + +/* + * Check for priority scheduler next, as it is the default policy if there + * is no CONFIGURE_SCHEDULER_POLICY set and no USER scheduler provided. + */ +#if defined(CONFIGURE_SCHEDULER_PRIORITY) + #include <rtems/score/schedulerpriority.h> + #define CONFIGURE_SCHEDULER_ENTRY_PRIORITY { _Scheduler_priority_Initialize } + #if !defined(CONFIGURE_SCHEDULER_POLICY) + #define CONFIGURE_SCHEDULER_POLICY _Scheduler_PRIORITY + #endif + + /** + * define the memory used by the priority scheduler + */ + #define CONFIGURE_MEMORY_SCHEDULER_PRIORITY ( \ + _Configure_From_workspace( \ + ((CONFIGURE_MAXIMUM_PRIORITY+1) * sizeof(Chain_Control)) ) \ + ) + #define CONFIGURE_MEMORY_PER_TASK_SCHEDULER_PRIORITY ( \ + _Configure_From_workspace(sizeof(Scheduler_priority_Per_thread)) ) +#endif + +/* + * Set up the scheduler table. The scheduling code indexes this table to + * invoke the correct scheduling implementation. The scheduler to use is + * determined by the Configuration.scheduler_policy field, which is set + * by CONFIGURE_SCHEDULER_POLICY. If a particular scheduler is not enabled, + * an empty entry is included in its entry in the scheduler table. + */ + + /** + * An empty scheduler entry + */ + #define CONFIGURE_SCHEDULER_NULL { NULL } + +#ifdef CONFIGURE_INIT + /* the table of available schedulers. */ + const Scheduler_Table_t _Scheduler_Table[] = { + #if defined(CONFIGURE_SCHEDULER_USER) && \ + defined(CONFIGURE_SCHEDULER_ENTRY_USER) + CONFIGURE_SCHEDULER_ENTRY_USER, + #else + CONFIGURE_SCHEDULER_NULL, + #endif + #if defined(CONFIGURE_SCHEDULER_PRIORITY) && \ + defined(CONFIGURE_SCHEDULER_ENTRY_PRIORITY) + CONFIGURE_SCHEDULER_ENTRY_PRIORITY, + #else + CONFIGURE_SCHEDULER_NULL, + #endif + }; +#endif + +/** + * Define the memory overhead for the scheduler + */ +#define CONFIGURE_MEMORY_FOR_SCHEDULER ( \ + CONFIGURE_MEMORY_SCHEDULER_PRIORITY \ + ) + +#define CONFIGURE_MEMORY_PER_TASK_FOR_SCHEDULER ( \ + CONFIGURE_MEMORY_PER_TASK_SCHEDULER_PRIORITY \ + ) + +/* * If you said the IDLE task was going to do application initialization * and didn't override the IDLE body, then something is amiss. */ @@ -1607,7 +1717,8 @@ rtems_fs_init_functions_t rtems_fs_init_helper = (_Configure_From_workspace(CONFIGURE_MINIMUM_TASK_STACK_SIZE) + \ CONFIGURE_MEMORY_PER_TASK_FOR_CLASSIC_API + \ CONFIGURE_MEMORY_PER_TASK_FOR_NEWLIB + \ - CONFIGURE_MEMORY_PER_TASK_FOR_POSIX_API)) + \ + CONFIGURE_MEMORY_PER_TASK_FOR_POSIX_API + \ + CONFIGURE_MEMORY_PER_TASK_FOR_SCHEDULER)) + \ _Configure_From_workspace( \ _Configure_Max_Objects(_number_FP_tasks) * CONTEXT_FP_SIZE) + \ _Configure_From_workspace( \ @@ -1705,13 +1816,6 @@ rtems_fs_init_functions_t rtems_fs_init_helper = _Configure_Object_RAM(1, sizeof(API_Mutex_Control)) /** - * This defines the memory used by the thread ready chains. There is - * one chain per priority. - */ -#define CONFIGURE_MEMORY_FOR_THREAD_READY_CHAINS \ - _Configure_From_workspace( \ - ((CONFIGURE_MAXIMUM_PRIORITY+1) * sizeof(Chain_Control)) ) -/** * This defines the amount of memory reserved for the IDLE task * control structures and stack. */ @@ -1724,7 +1828,7 @@ rtems_fs_init_functions_t rtems_fs_init_helper = */ #define CONFIGURE_MEMORY_FOR_SYSTEM_OVERHEAD \ ( CONFIGURE_MEMORY_FOR_IDLE_TASK + /* IDLE and stack */ \ - CONFIGURE_MEMORY_FOR_THREAD_READY_CHAINS + /* Ready chains */ \ + CONFIGURE_MEMORY_FOR_SCHEDULER + /* Scheduler */ \ CONFIGURE_INTERRUPT_VECTOR_TABLE + /* interrupt vectors */ \ CONFIGURE_INTERRUPT_STACK_MEMORY + /* interrupt stack */ \ CONFIGURE_API_MUTEX_MEMORY /* allocation mutex */ \ @@ -2005,6 +2109,7 @@ rtems_fs_init_functions_t rtems_fs_init_helper = CONFIGURE_MAXIMUM_USER_EXTENSIONS, /* maximum dynamic extensions */ CONFIGURE_MICROSECONDS_PER_TICK, /* microseconds per clock tick */ CONFIGURE_TICKS_PER_TIMESLICE, /* ticks per timeslice quantum */ + CONFIGURE_SCHEDULER_POLICY, /* scheduling policy */ CONFIGURE_IDLE_TASK_BODY, /* user's IDLE task */ CONFIGURE_IDLE_TASK_STACK_SIZE, /* IDLE task stack size */ CONFIGURE_INTERRUPT_STACK_SIZE, /* interrupt stack size */ diff --git a/cpukit/sapi/include/rtems/config.h b/cpukit/sapi/include/rtems/config.h index 1f9b56c3e8..541bc9ddff 100644 --- a/cpukit/sapi/include/rtems/config.h +++ b/cpukit/sapi/include/rtems/config.h @@ -118,6 +118,10 @@ typedef struct { */ uint32_t ticks_per_timeslice; + /** This field specifies the scheduling policy to use. + */ + uint32_t scheduler_policy; + /** This element points to the BSP's optional idle task which may override * the default one provided with RTEMS. */ diff --git a/cpukit/sapi/src/exinit.c b/cpukit/sapi/src/exinit.c index 1185b74e4a..2cbddfa1da 100644 --- a/cpukit/sapi/src/exinit.c +++ b/cpukit/sapi/src/exinit.c @@ -42,7 +42,7 @@ #include <rtems/score/mpci.h> #endif #include <rtems/score/priority.h> -#include <rtems/score/prioritybitmap.h> +#include <rtems/score/scheduler.h> #include <rtems/score/thread.h> #include <rtems/score/tod.h> #include <rtems/score/userext.h> @@ -131,6 +131,8 @@ void rtems_initialize_data_structures(void) _Thread_Handler_initialization(); + _Scheduler_Handler_initialization(); + #if defined(RTEMS_MULTIPROCESSING) _Objects_MP_Handler_initialization(); _MPCI_Handler_initialization( RTEMS_TIMEOUT ); diff --git a/cpukit/score/Makefile.am b/cpukit/score/Makefile.am index fd1f2a90e2..6ad13b51e8 100644 --- a/cpukit/score/Makefile.am +++ b/cpukit/score/Makefile.am @@ -26,6 +26,7 @@ include_rtems_score_HEADERS = include/rtems/score/address.h \ include/rtems/score/interr.h include/rtems/score/isr.h \ include/rtems/score/object.h include/rtems/score/percpu.h \ include/rtems/score/priority.h include/rtems/score/prioritybitmap.h \ + include/rtems/score/scheduler.h include/rtems/score/schedulerpriority.h \ include/rtems/score/stack.h include/rtems/score/states.h \ include/rtems/score/sysstate.h include/rtems/score/thread.h \ include/rtems/score/threadq.h include/rtems/score/threadsync.h \ @@ -54,6 +55,7 @@ include_rtems_score_HEADERS += inline/rtems/score/address.inl \ inline/rtems/score/coresem.inl inline/rtems/score/heap.inl \ inline/rtems/score/isr.inl inline/rtems/score/object.inl \ inline/rtems/score/priority.inl inline/rtems/score/prioritybitmap.inl \ + inline/rtems/score/scheduler.inl inline/rtems/score/schedulerpriority.inl \ inline/rtems/score/stack.inl inline/rtems/score/states.inl \ inline/rtems/score/sysstate.inl inline/rtems/score/thread.inl \ inline/rtems/score/threadq.inl inline/rtems/score/tod.inl \ @@ -137,6 +139,19 @@ libscore_a_SOURCES += src/objectallocate.c src/objectclose.c \ src/objectgetinfo.c src/objectgetinfoid.c src/objectapimaximumclass.c \ src/objectnamespaceremove.c +## SCHEDULER_C_FILES +libscore_a_SOURCES += src/scheduler.c + +## SCHEDULERPRIORITY_C_FILES +libscore_a_SOURCES += src/schedulerpriority.c \ + src/schedulerpriorityblock.c \ + src/schedulerprioritythreadschedulerallocate.c \ + src/schedulerprioritythreadschedulerfree.c \ + src/schedulerprioritythreadschedulerupdate.c \ + src/schedulerpriorityschedule.c \ + src/schedulerpriorityunblock.c \ + src/schedulerpriorityyield.c + ## PROTECTED_HEAP_C_FILES libscore_a_SOURCES += src/pheapallocate.c \ src/pheapextend.c src/pheapfree.c src/pheapgetsize.c \ @@ -153,7 +168,7 @@ libscore_a_SOURCES += src/thread.c src/threadchangepriority.c \ src/threadsetstate.c src/threadsettransient.c \ src/threadstackallocate.c src/threadstackfree.c src/threadstart.c \ src/threadstartmultitasking.c src/threadsuspend.c \ - src/threadtickletimeslice.c src/threadyieldprocessor.c \ + src/threadtickletimeslice.c \ src/iterateoverthreads.c src/threadblockingoperationcancel.c ## THREADQ_C_FILES diff --git a/cpukit/score/include/rtems/score/prioritybitmap.h b/cpukit/score/include/rtems/score/prioritybitmap.h index cd712952b2..bba5b428b6 100644 --- a/cpukit/score/include/rtems/score/prioritybitmap.h +++ b/cpukit/score/include/rtems/score/prioritybitmap.h @@ -37,18 +37,17 @@ extern "C" { #include <rtems/score/priority.h> + /* - * TODO: - * These should only be instantiated if using the bit map handler. The - * logical place for this is in confdefs.h when a scheduler that uses the - * bit map handler is configured. + * The Priority_bit_map_Control variables are instantiated only + * if using the bit map handler. */ /** * Each sixteen bit entry in this array is associated with one of * the sixteen entries in the Priority Bit map. */ -SCORE_EXTERN volatile Priority_bit_map_Control _Priority_Major_bit_map; +extern volatile Priority_bit_map_Control _Priority_Major_bit_map; /** Each bit in the Priority Bitmap indicates whether or not there are * threads ready at a particular priority. The mapping of @@ -56,7 +55,7 @@ SCORE_EXTERN volatile Priority_bit_map_Control _Priority_Major_bit_map; * dependent as is the value of each bit used to indicate that * threads are ready at that priority. */ -SCORE_EXTERN Priority_bit_map_Control +extern Priority_bit_map_Control _Priority_Bit_map[16] CPU_STRUCTURE_ALIGNMENT; /* diff --git a/cpukit/score/include/rtems/score/scheduler.h b/cpukit/score/include/rtems/score/scheduler.h new file mode 100644 index 0000000000..b0ac20917c --- /dev/null +++ b/cpukit/score/include/rtems/score/scheduler.h @@ -0,0 +1,156 @@ +/** + * @file rtems/score/scheduler.h + * + * This include file contains all the constants and structures associated + * with 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 +#define _RTEMS_SCORE_SCHEDULER_H + +/** + * @defgroup ScoreScheduler Scheduler Handler + * + * This handler encapsulates functionality related to managing sets of threads + * that are ready for execution. + */ +/**@{*/ + +#ifdef __cplusplus +extern "C" { +#endif + +#include <rtems/score/percpu.h> +#include <rtems/score/chain.h> +#include <rtems/score/priority.h> +#include <rtems/score/prioritybitmap.h> + +/* + * These defines are used to set the scheduler_policy value. The values + * must correspond directly with the order of the fields in the scheduler + * table (Scheduler_Table_t), because the Configuration.scheduler_policy + * field is used to index the scheduler table. + */ +#define _Scheduler_USER (0) +#define _Scheduler_PRIORITY (1) + +typedef struct Scheduler_Control_struct Scheduler_Control; + +/* + * The Scheduler_Table_t type defines the scheduler initialization table, + * which is set up by confdefs.h based on the user's choice of scheduler + * policy. + */ +typedef struct { + void ( *scheduler_init )( Scheduler_Control * ); +} Scheduler_Table_t; + +/* instantiated and initialized in confdefs.h */ +extern const Scheduler_Table_t _Scheduler_Table[]; + +/** + * The following Scheduler_Per_thread_xxx structures are used to + * hold per-thread data used by the scheduler. Thread_Control->scheduler is a + * union of pointers, one for each of the following structures. The + * scheduler->xxx field points to an instantion of one of these structures, + * which is allocated from the workspace during _Thread_Start. + */ + +/** + * Per-thread data related to the _Scheduler_PRIORITY scheduling policy. + */ +typedef struct { + /** This field points to the Ready FIFO for this thread's priority. */ + Chain_Control *ready_chain; + + /** This field contains precalculated priority map indices. */ + Priority_bit_map_Information Priority_map; +} Scheduler_priority_Per_thread; + +/** + * function jump table that holds pointers to the functions that + * implement specific schedulers. + */ +typedef struct { + /** Implements the scheduling decision logic (policy). */ + void ( *schedule ) ( Scheduler_Control * ); + + /** Voluntarily yields the processor per the scheduling policy. */ + void ( *yield ) ( Scheduler_Control * ); + + /** Removes the given thread from scheduling decisions. */ + void ( *block ) ( Scheduler_Control *, Thread_Control * ); + + /** Adds the given thread to scheduling decisions. */ + void ( *unblock ) ( Scheduler_Control *, Thread_Control * ); + + /** allocates the scheduler field of the given thread */ + void * ( *scheduler_allocate ) ( Scheduler_Control *, Thread_Control * ); + + /** frees the scheduler field of the given thread */ + void ( *scheduler_free ) ( Scheduler_Control *, Thread_Control * ); + + /** updates the scheduler field of the given thread -- primarily used + * when changing the thread's priority. */ + void ( *scheduler_update ) ( Scheduler_Control *, Thread_Control * ); +} Scheduler_Operations; + +/** + * This is the structure used to manage the scheduler. + */ +struct Scheduler_Control_struct { + /** + * This union contains the pointer to the data structure used to manage + * the ready set of tasks. The pointer varies based upon the type of + * ready queue required by the scheduler. + */ + union { + /** + * This is the set of lists (an array of Chain_Control) for + * priority scheduling. + */ + Chain_Control *Priority; + + } ready_queues; + + /** The jump table for scheduler-specific functions */ + Scheduler_Operations operations; +}; + +/** + * The _Scheduler holds the structures used to manage the + * scheduler. + * + * @note Can we make this per-cpu? then _Scheduler will be a macro. + */ +SCORE_EXTERN Scheduler_Control _Scheduler; + +/** + * This routine initializes the scheduler to the policy chosen by the user + * through confdefs, or to the priority scheduler with ready chains by + * default. + */ +void _Scheduler_Handler_initialization( void ); + +#ifndef __RTEMS_APPLICATION__ +#include <rtems/score/scheduler.inl> +#endif + +#ifdef __cplusplus +} +#endif + +/**@}*/ + +#endif +/* end of include file */ diff --git a/cpukit/score/include/rtems/score/schedulerpriority.h b/cpukit/score/include/rtems/score/schedulerpriority.h new file mode 100644 index 0000000000..54c999f058 --- /dev/null +++ b/cpukit/score/include/rtems/score/schedulerpriority.h @@ -0,0 +1,117 @@ +/** + * @file rtems/score/schedulerpriority.h + * + * This include file contains all the constants and structures associated + * with the manipulation of threads for the priority-based scheduler. + */ + +/* + * Copryight (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 +#define _RTEMS_SCORE_SCHEDULERPRIORITY_H + +/** + * @addtogroup ScoreScheduler + * + */ +/**@{*/ + +#ifdef __cplusplus +extern "C" { +#endif + +#include <rtems/score/chain.h> +#include <rtems/score/priority.h> +#include <rtems/score/percpu.h> +#include <rtems/score/scheduler.h> +#include <rtems/score/wkspace.h> + +/** + * This routine initializes the priority scheduler. + */ +void _Scheduler_priority_Initialize( + Scheduler_Control *the_scheduler +); + +/** + * This routine removes @a the_thread from the scheduling decision, + * that is, removes it from the ready queue. It performs + * any necessary scheduling operations including the selection of + * a new heir thread. + */ +void _Scheduler_priority_Block( + Scheduler_Control *the_scheduler, + Thread_Control *the_thread +); + +/** + * This kernel routine sets the heir thread to be the next ready thread + * by invoking the_scheduler->ready_queue->operations->first(). + */ +void _Scheduler_priority_Schedule( + Scheduler_Control *the_scheduler +); + +/** + * This routine allocates @a the_thread->scheduler. + */ +void * _Scheduler_priority_Thread_scheduler_allocate( + Scheduler_Control *the_scheduler, + Thread_Control *the_thread +); + +/** + * This routine frees @a the_thread->scheduler. + */ +void _Scheduler_priority_Thread_scheduler_free( + Scheduler_Control *the_scheduler, + Thread_Control *the_thread +); + +/** + * This routine updates @a the_thread->scheduler based on @a the_scheduler + * structures and thread state + */ +void _Scheduler_priority_Thread_scheduler_update( + Scheduler_Control *the_scheduler, + Thread_Control *the_thread +); + +/** + * This routine adds @a the_thread to the scheduling decision, + * that is, adds it to the ready queue and + * updates any appropriate scheduling variables, for example the heir thread. + */ +void _Scheduler_priority_Unblock( + Scheduler_Control *the_scheduler, + Thread_Control *the_thread +); + +/** + * This routine is invoked when a thread wishes to voluntarily + * transfer control of the processor to another thread in the queue. + */ +void _Scheduler_priority_Yield( + Scheduler_Control *the_scheduler +); + +#ifndef __RTEMS_APPLICATION__ +#include <rtems/score/schedulerpriority.inl> +#endif + +#ifdef __cplusplus +} +#endif + +/**@}*/ + +#endif +/* end of include file */ diff --git a/cpukit/score/include/rtems/score/thread.h b/cpukit/score/include/rtems/score/thread.h index 9565458bb8..370d5491a3 100644 --- a/cpukit/score/include/rtems/score/thread.h +++ b/cpukit/score/include/rtems/score/thread.h @@ -70,7 +70,7 @@ extern "C" { #endif #include <rtems/score/object.h> #include <rtems/score/priority.h> -#include <rtems/score/prioritybitmap.h> +#include <rtems/score/scheduler.h> #include <rtems/score/stack.h> #include <rtems/score/states.h> #include <rtems/score/tod.h> @@ -390,10 +390,10 @@ struct Thread_Control_struct { * since it was created. */ Thread_CPU_usage_t cpu_time_used; - /** This field points to the Ready FIFO for this priority. */ - Chain_Control *ready; - /** This field contains precalculated priority map indices. */ - Priority_bit_map_Information Priority_map; + /** This union holds per-thread data for the scheduler and ready queue. */ + union { + Scheduler_priority_Per_thread *priority; + } scheduler; /** This field contains information about the starting state of * this thread. */ @@ -456,12 +456,6 @@ SCORE_EXTERN uint32_t _Thread_Maximum_extensions; SCORE_EXTERN uint32_t _Thread_Ticks_per_timeslice; /** - * The following points to the array of FIFOs used to manage the - * set of ready threads. - */ -SCORE_EXTERN Chain_Control *_Thread_Ready_chain; - -/** * The following points to the thread whose floating point * context is currently loaded. */ @@ -654,13 +648,6 @@ void _Thread_Set_transient( void _Thread_Tickle_timeslice( void ); /** - * This routine is invoked when a thread wishes to voluntarily - * transfer control of the processor to another thread of equal - * or greater priority. - */ -void _Thread_Yield_processor( void ); - -/** * This routine initializes the context of the_thread to its * appropriate starting state. */ 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. diff --git a/cpukit/score/preinstall.am b/cpukit/score/preinstall.am index 9768f8c81d..65f28c4a85 100644 --- a/cpukit/score/preinstall.am +++ b/cpukit/score/preinstall.am @@ -111,6 +111,14 @@ $(PROJECT_INCLUDE)/rtems/score/prioritybitmap.h: include/rtems/score/prioritybit $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/prioritybitmap.h PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/prioritybitmap.h +$(PROJECT_INCLUDE)/rtems/score/scheduler.h: include/rtems/score/scheduler.h $(PROJECT_INCLUDE)/rtems/score/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/scheduler.h +PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/scheduler.h + +$(PROJECT_INCLUDE)/rtems/score/schedulerpriority.h: include/rtems/score/schedulerpriority.h $(PROJECT_INCLUDE)/rtems/score/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/schedulerpriority.h +PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/schedulerpriority.h + $(PROJECT_INCLUDE)/rtems/score/stack.h: include/rtems/score/stack.h $(PROJECT_INCLUDE)/rtems/score/$(dirstamp) $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/stack.h PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/stack.h @@ -245,6 +253,14 @@ $(PROJECT_INCLUDE)/rtems/score/prioritybitmap.inl: inline/rtems/score/prioritybi $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/prioritybitmap.inl PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/prioritybitmap.inl +$(PROJECT_INCLUDE)/rtems/score/scheduler.inl: inline/rtems/score/scheduler.inl $(PROJECT_INCLUDE)/rtems/score/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/scheduler.inl +PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/scheduler.inl + +$(PROJECT_INCLUDE)/rtems/score/schedulerpriority.inl: inline/rtems/score/schedulerpriority.inl $(PROJECT_INCLUDE)/rtems/score/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/schedulerpriority.inl +PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/schedulerpriority.inl + $(PROJECT_INCLUDE)/rtems/score/stack.inl: inline/rtems/score/stack.inl $(PROJECT_INCLUDE)/rtems/score/$(dirstamp) $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/stack.inl PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/stack.inl diff --git a/cpukit/score/src/scheduler.c b/cpukit/score/src/scheduler.c new file mode 100644 index 0000000000..9d7424eef6 --- /dev/null +++ b/cpukit/score/src/scheduler.c @@ -0,0 +1,45 @@ +/* + * Scheduler Handler + * + * 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$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/system.h> +#include <rtems/config.h> +#include <rtems/score/chain.h> +#include <rtems/score/isr.h> +#include <rtems/score/object.h> +#include <rtems/score/scheduler.h> +#include <rtems/score/schedulerpriority.h> +#include <rtems/score/states.h> +#include <rtems/score/thread.h> + +/* + * _Scheduler_Handler_initialization + * + * This routine initializes the scheduler by calling the scheduler_init + * function registered in the Configuration Scheduler Table. + * + * Input parameters: NONE + * + * Output parameters: NONE + */ + +void _Scheduler_Handler_initialization( ) +{ + Scheduler_Control *the_scheduler = &_Scheduler; + + (*(_Scheduler_Table[Configuration.scheduler_policy].scheduler_init))( + the_scheduler + ); +} diff --git a/cpukit/score/src/schedulerpriority.c b/cpukit/score/src/schedulerpriority.c new file mode 100644 index 0000000000..5e7ad61d9a --- /dev/null +++ b/cpukit/score/src/schedulerpriority.c @@ -0,0 +1,66 @@ +/* + * Scheduler Handler + * + * 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$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/system.h> +#include <rtems/config.h> +#include <rtems/score/chain.h> +#include <rtems/score/isr.h> +#include <rtems/score/object.h> +#include <rtems/score/scheduler.h> +#include <rtems/score/schedulerpriority.h> +#include <rtems/score/states.h> +#include <rtems/score/thread.h> + +/* Instantiate any global variables needed by the priority scheduler */ +volatile Priority_bit_map_Control _Priority_Major_bit_map; + +Priority_bit_map_Control _Priority_Bit_map[16] CPU_STRUCTURE_ALIGNMENT; + +/* + * _Scheduler_priority_Initialize + * + * Initializes the scheduler for priority scheduling. + * + * Input parameters: + * the_scheduler - pointer to scheduler control + * + * Output parameters: NONE + */ + +void _Scheduler_priority_Initialize ( + Scheduler_Control *the_scheduler +) +{ + /* the operations table is a jump table to redirect generic scheduler + * function calls to scheduler implementation specific functions. The + * main purpose of scheduler initialization is to set up the jump table + * for the scheduler. Every scheduler implementation provides its own + * scheduler operations table. + */ + the_scheduler->operations.schedule = &_Scheduler_priority_Schedule; + the_scheduler->operations.yield = &_Scheduler_priority_Yield; + the_scheduler->operations.block = &_Scheduler_priority_Block; + the_scheduler->operations.unblock = &_Scheduler_priority_Unblock; + the_scheduler->operations.scheduler_allocate = + &_Scheduler_priority_Thread_scheduler_allocate; + the_scheduler->operations.scheduler_free = + &_Scheduler_priority_Thread_scheduler_free; + the_scheduler->operations.scheduler_update = + &_Scheduler_priority_Thread_scheduler_update; + + _Scheduler_priority_Ready_queue_initialize( the_scheduler ); + _Priority_bit_map_Handler_initialization( ); +} diff --git a/cpukit/score/src/schedulerpriorityblock.c b/cpukit/score/src/schedulerpriorityblock.c new file mode 100644 index 0000000000..cc137e64f5 --- /dev/null +++ b/cpukit/score/src/schedulerpriorityblock.c @@ -0,0 +1,48 @@ +/* + * Scheduler Handler + * + * Copyright (C) 2010 Gedare Bloom. + * + * The license and distribution terms for this file may be + * found in found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/system.h> +#include <rtems/score/context.h> +#include <rtems/score/interr.h> +#include <rtems/score/isr.h> +#include <rtems/score/object.h> +#include <rtems/score/priority.h> +#include <rtems/score/scheduler.h> +#include <rtems/score/schedulerpriority.h> +#include <rtems/score/thread.h> + +/* + * _Scheduler_priority_Block + * + * 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: + */ + +void _Scheduler_priority_Block( + Scheduler_Control *the_scheduler, + Thread_Control *the_thread +) +{ + _Scheduler_priority_Block_body(the_scheduler, the_thread); +} diff --git a/cpukit/score/src/schedulerpriorityschedule.c b/cpukit/score/src/schedulerpriorityschedule.c new file mode 100644 index 0000000000..10c46652ef --- /dev/null +++ b/cpukit/score/src/schedulerpriorityschedule.c @@ -0,0 +1,48 @@ +/* + * Scheduler Handler + * + * Copyright (C) 2010 Gedare Bloom. + * + * The license and distribution terms for this file may be + * found in found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/system.h> +#include <rtems/score/context.h> +#include <rtems/score/interr.h> +#include <rtems/score/isr.h> +#include <rtems/score/object.h> +#include <rtems/score/priority.h> +#include <rtems/score/percpu.h> +#include <rtems/score/scheduler.h> +#include <rtems/score/schedulerpriority.h> +#include <rtems/score/thread.h> + +/* + * _Scheduler_priority_Schedule + * + * 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: + */ + +void _Scheduler_priority_Schedule( + Scheduler_Control *the_scheduler +) +{ + _Scheduler_priority_Schedule_body( the_scheduler ); +} diff --git a/cpukit/score/src/schedulerprioritythreadschedulerallocate.c b/cpukit/score/src/schedulerprioritythreadschedulerallocate.c new file mode 100644 index 0000000000..21595ff778 --- /dev/null +++ b/cpukit/score/src/schedulerprioritythreadschedulerallocate.c @@ -0,0 +1,53 @@ +/* + * Scheduler Handler + * + * 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$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/system.h> +#include <rtems/config.h> +#include <rtems/score/chain.h> +#include <rtems/score/isr.h> +#include <rtems/score/object.h> +#include <rtems/score/scheduler.h> +#include <rtems/score/schedulerpriority.h> +#include <rtems/score/states.h> +#include <rtems/score/thread.h> +#include <rtems/score/wkspace.h> + +/* + * _Scheduler_priority_Thread_scheduler_allocate + * + * Allocates @a the_thread->scheduler + * + * Input parameters: + * the_scheduler - pointer to scheduler control + * the_thread - pointer to thread control block + * + * Output parameters: + * Returns pointer to allocated space. + */ + +void* _Scheduler_priority_Thread_scheduler_allocate ( + Scheduler_Control *the_scheduler, + Thread_Control *the_thread +) +{ + void *sched; + + sched = _Workspace_Allocate( sizeof(Scheduler_priority_Per_thread) ); + + the_thread->scheduler.priority = (Scheduler_priority_Per_thread*) sched; + + return sched; +} diff --git a/cpukit/score/src/schedulerprioritythreadschedulerfree.c b/cpukit/score/src/schedulerprioritythreadschedulerfree.c new file mode 100644 index 0000000000..78226b5fb3 --- /dev/null +++ b/cpukit/score/src/schedulerprioritythreadschedulerfree.c @@ -0,0 +1,46 @@ +/* + * Scheduler Handler + * + * 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$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/system.h> +#include <rtems/config.h> +#include <rtems/score/chain.h> +#include <rtems/score/isr.h> +#include <rtems/score/object.h> +#include <rtems/score/scheduler.h> +#include <rtems/score/schedulerpriority.h> +#include <rtems/score/states.h> +#include <rtems/score/thread.h> +#include <rtems/score/wkspace.h> + +/* + * _Scheduler_priority_Thread_scheduler_free + * + * Frees @a the_thread->scheduler + * + * Input parameters: + * the_scheduler - pointer to scheduler control + * the_thread - pointer to thread control block + * + * Output parameters: NONE + */ + +void _Scheduler_priority_Thread_scheduler_free ( + Scheduler_Control *the_scheduler, + Thread_Control *the_thread +) +{ + _Workspace_Free( the_thread->scheduler.priority ); +} diff --git a/cpukit/score/src/schedulerprioritythreadschedulerupdate.c b/cpukit/score/src/schedulerprioritythreadschedulerupdate.c new file mode 100644 index 0000000000..c4c7e815ce --- /dev/null +++ b/cpukit/score/src/schedulerprioritythreadschedulerupdate.c @@ -0,0 +1,55 @@ +/* + * Scheduler Handler + * + * 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$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/system.h> +#include <rtems/config.h> +#include <rtems/score/chain.h> +#include <rtems/score/isr.h> +#include <rtems/score/object.h> +#include <rtems/score/priority.h> +#include <rtems/score/prioritybitmap.h> +#include <rtems/score/scheduler.h> +#include <rtems/score/schedulerpriority.h> +#include <rtems/score/states.h> +#include <rtems/score/thread.h> + +/* + * _Scheduler_priority_Thread_scheduler_update + * + * Updates @a the_thread->scheduler + * + * Input parameters: + * the_scheduler - pointer to scheduler control + * the_thread - pointer to thread control block + * + * Output parameters: NONE + */ + +void _Scheduler_priority_Thread_scheduler_update ( + Scheduler_Control *the_scheduler, + Thread_Control *the_thread +) +{ + Chain_Control *rq = the_scheduler->ready_queues.Priority; + the_thread->scheduler.priority->ready_chain = &rq[ + the_thread->current_priority + ]; + + _Priority_bit_map_Initialize_information( + &the_thread->scheduler.priority->Priority_map, + the_thread->current_priority + ); +} diff --git a/cpukit/score/src/schedulerpriorityunblock.c b/cpukit/score/src/schedulerpriorityunblock.c new file mode 100644 index 0000000000..9030c0a137 --- /dev/null +++ b/cpukit/score/src/schedulerpriorityunblock.c @@ -0,0 +1,57 @@ +/* + * Scheduler Handler + * + * Copyright (C) 2010 Gedare Bloom. + * + * The license and distribution terms for this file may be + * found in found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/system.h> +#include <rtems/score/apiext.h> +#include <rtems/score/context.h> +#include <rtems/score/interr.h> +#include <rtems/score/isr.h> +#include <rtems/score/object.h> +#include <rtems/score/priority.h> +#include <rtems/score/scheduler.h> +#include <rtems/score/schedulerpriority.h> +#include <rtems/score/states.h> +#include <rtems/score/sysstate.h> +#include <rtems/score/thread.h> +#include <rtems/score/threadq.h> +#include <rtems/score/userext.h> +#include <rtems/score/wkspace.h> + +/* + * _Scheduler_priority_Unblock + * + * 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: + */ + +void _Scheduler_priority_Unblock ( + Scheduler_Control *the_scheduler, + Thread_Control *the_thread +) +{ + _Scheduler_priority_Unblock_body(the_scheduler, the_thread); +} diff --git a/cpukit/score/src/schedulerpriorityyield.c b/cpukit/score/src/schedulerpriorityyield.c new file mode 100644 index 0000000000..1a13a4e318 --- /dev/null +++ b/cpukit/score/src/schedulerpriorityyield.c @@ -0,0 +1,77 @@ +/* + * Scheduler Handler + * + * Copyright (C) 2010 Gedare Bloom. + * + * The license and distribution terms for this file may be + * found in found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/system.h> +#include <rtems/score/apiext.h> +#include <rtems/score/context.h> +#include <rtems/score/interr.h> +#include <rtems/score/isr.h> +#include <rtems/score/object.h> +#include <rtems/score/priority.h> +#include <rtems/score/scheduler.h> +#include <rtems/score/states.h> +#include <rtems/score/sysstate.h> +#include <rtems/score/thread.h> +#include <rtems/score/threadq.h> +#include <rtems/score/userext.h> +#include <rtems/score/wkspace.h> + +/* + * _Scheduler_priority_Yield + * + * This kernel routine will remove the running THREAD from the ready queue + * and place it immediately at the rear of this chain. Reset timeslice + * and yield the processor functions both use this routine, therefore if + * reset is true and this is the only thread on the queue then the + * timeslice counter is reset. The heir THREAD will be updated if the + * running is also the currently the heir. + * + * Input parameters: + * the_scheduler - pointer to scheduler control + * + * Output parameters: NONE + * + * INTERRUPT LATENCY: + * ready chain + * select heir + */ + +void _Scheduler_priority_Yield( + Scheduler_Control *the_scheduler +) +{ + ISR_Level level; + Thread_Control *executing; + Chain_Control *ready; + + executing = _Thread_Executing; + ready = executing->scheduler.priority->ready_chain; + _ISR_Disable( level ); + if ( !_Chain_Has_only_one_node( ready ) ) { + _Chain_Extract_unprotected( &executing->Object.Node ); + _Chain_Append_unprotected( ready, &executing->Object.Node ); + + _ISR_Flash( level ); + + if ( _Thread_Is_heir( executing ) ) + _Thread_Heir = (Thread_Control *) ready->first; + _Thread_Dispatch_necessary = true; + } + else if ( !_Thread_Is_heir( executing ) ) + _Thread_Dispatch_necessary = true; + + _ISR_Enable( level ); +} diff --git a/cpukit/score/src/thread.c b/cpukit/score/src/thread.c index f0891373f6..bf8e8939e7 100644 --- a/cpukit/score/src/thread.c +++ b/cpukit/score/src/thread.c @@ -24,6 +24,7 @@ #include <rtems/score/isr.h> #include <rtems/score/object.h> #include <rtems/score/priority.h> +#include <rtems/score/scheduler.h> #include <rtems/score/states.h> #include <rtems/score/sysstate.h> #include <rtems/score/thread.h> @@ -45,7 +46,6 @@ void _Thread_Handler_initialization(void) { - uint32_t index; uint32_t ticks_per_timeslice; uint32_t maximum_extensions; #if defined(RTEMS_MULTIPROCESSING) @@ -80,13 +80,6 @@ void _Thread_Handler_initialization(void) _Thread_Ticks_per_timeslice = ticks_per_timeslice; - _Thread_Ready_chain = (Chain_Control *) _Workspace_Allocate_or_fatal_error( - (PRIORITY_MAXIMUM + 1) * sizeof(Chain_Control) - ); - - for ( index=0; index <= PRIORITY_MAXIMUM ; index++ ) - _Chain_Initialize_empty( &_Thread_Ready_chain[ index ] ); - #if defined(RTEMS_MULTIPROCESSING) _Thread_MP_Handler_initialization( maximum_proxies ); #endif diff --git a/cpukit/score/src/threadchangepriority.c b/cpukit/score/src/threadchangepriority.c index 58f5eb5fd3..7b46f799c7 100644 --- a/cpukit/score/src/threadchangepriority.c +++ b/cpukit/score/src/threadchangepriority.c @@ -23,6 +23,8 @@ #include <rtems/score/isr.h> #include <rtems/score/object.h> #include <rtems/score/priority.h> +#include <rtems/score/scheduler.h> +#include <rtems/score/schedulerpriority.h> #include <rtems/score/states.h> #include <rtems/score/sysstate.h> #include <rtems/score/thread.h> @@ -117,14 +119,16 @@ void _Thread_Change_priority( * We now know the thread will be in the READY state when we remove * the TRANSIENT state. So we have to place it on the appropriate * Ready Queue with interrupts off. + * + * FIXME: hard-coded for priority scheduling. Might be ok since this + * function is specific to priority scheduling? */ the_thread->current_state = _States_Clear( STATES_TRANSIENT, state ); - _Priority_bit_map_Add( &the_thread->Priority_map ); if ( prepend_it ) - _Chain_Prepend_unprotected( the_thread->ready, &the_thread->Object.Node ); + _Scheduler_priority_Ready_queue_enqueue_first( the_thread ); else - _Chain_Append_unprotected( the_thread->ready, &the_thread->Object.Node ); + _Scheduler_priority_Ready_queue_enqueue( the_thread ); } _ISR_Flash( level ); @@ -133,7 +137,7 @@ void _Thread_Change_priority( * We altered the set of thread priorities. So let's figure out * who is the heir and if we need to switch to them. */ - _Thread_Calculate_heir(); + _Scheduler_Schedule(&_Scheduler); if ( !_Thread_Is_executing_also_the_heir() && _Thread_Executing->is_preemptible ) diff --git a/cpukit/score/src/threadclearstate.c b/cpukit/score/src/threadclearstate.c index c5ab03497a..c3a9083197 100644 --- a/cpukit/score/src/threadclearstate.c +++ b/cpukit/score/src/threadclearstate.c @@ -23,6 +23,7 @@ #include <rtems/score/isr.h> #include <rtems/score/object.h> #include <rtems/score/priority.h> +#include <rtems/score/scheduler.h> #include <rtems/score/states.h> #include <rtems/score/sysstate.h> #include <rtems/score/thread.h> @@ -66,31 +67,7 @@ void _Thread_Clear_state( the_thread->current_state = _States_Clear( state, current_state ); if ( _States_Is_ready( current_state ) ) { - - _Priority_bit_map_Add( &the_thread->Priority_map ); - - _Chain_Append_unprotected(the_thread->ready, &the_thread->Object.Node); - - _ISR_Flash( level ); - - /* - * 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; - } + _Scheduler_Unblock( &_Scheduler, the_thread); } } _ISR_Enable( level ); diff --git a/cpukit/score/src/threadclose.c b/cpukit/score/src/threadclose.c index 51db06f56c..5098f0fbc4 100644 --- a/cpukit/score/src/threadclose.c +++ b/cpukit/score/src/threadclose.c @@ -23,6 +23,7 @@ #include <rtems/score/isr.h> #include <rtems/score/object.h> #include <rtems/score/priority.h> +#include <rtems/score/scheduler.h> #include <rtems/score/states.h> #include <rtems/score/sysstate.h> #include <rtems/score/thread.h> @@ -86,6 +87,11 @@ void _Thread_Close( } /* + * Free the per-thread scheduling information. + */ + _Scheduler_Thread_scheduler_free( &_Scheduler, the_thread ); + + /* * The thread might have been FP. So deal with that. */ #if ( CPU_HARDWARE_FP == TRUE ) || ( CPU_SOFTWARE_FP == TRUE ) diff --git a/cpukit/score/src/threadinitialize.c b/cpukit/score/src/threadinitialize.c index 4afdbcb821..eda6f6bb5a 100644 --- a/cpukit/score/src/threadinitialize.c +++ b/cpukit/score/src/threadinitialize.c @@ -23,6 +23,7 @@ #include <rtems/score/isr.h> #include <rtems/score/object.h> #include <rtems/score/priority.h> +#include <rtems/score/scheduler.h> #include <rtems/score/states.h> #include <rtems/score/sysstate.h> #include <rtems/score/thread.h> @@ -60,6 +61,7 @@ bool _Thread_Initialize( #if ( CPU_HARDWARE_FP == TRUE ) || ( CPU_SOFTWARE_FP == TRUE ) void *fp_area; #endif + void *sched = NULL; void *extensions_area; bool extension_status; int i; @@ -192,6 +194,9 @@ bool _Thread_Initialize( the_thread->resource_count = 0; the_thread->real_priority = priority; the_thread->Start.initial_priority = priority; + sched =_Scheduler_Thread_scheduler_allocate( &_Scheduler, the_thread ); + if ( !sched ) + goto failed; _Thread_Set_priority( the_thread, priority ); /* @@ -235,6 +240,9 @@ failed: (void) _Workspace_Free( fp_area ); #endif + if ( sched ) + (void) _Workspace_Free( sched ); + _Thread_Stack_Free( the_thread ); return false; diff --git a/cpukit/score/src/threadready.c b/cpukit/score/src/threadready.c index 3daa6506bd..f0e006503c 100644 --- a/cpukit/score/src/threadready.c +++ b/cpukit/score/src/threadready.c @@ -23,6 +23,7 @@ #include <rtems/score/isr.h> #include <rtems/score/object.h> #include <rtems/score/priority.h> +#include <rtems/score/scheduler.h> #include <rtems/score/states.h> #include <rtems/score/sysstate.h> #include <rtems/score/thread.h> @@ -55,24 +56,12 @@ void _Thread_Ready( ) { ISR_Level level; - Thread_Control *heir; _ISR_Disable( level ); the_thread->current_state = STATES_READY; - _Priority_bit_map_Add( &the_thread->Priority_map ); - - _Chain_Append_unprotected( the_thread->ready, &the_thread->Object.Node ); - - _ISR_Flash( level ); - - _Thread_Calculate_heir(); - - heir = _Thread_Heir; - - if ( !_Thread_Is_executing( heir ) && _Thread_Executing->is_preemptible ) - _Thread_Dispatch_necessary = true; + _Scheduler_Unblock( &_Scheduler, the_thread ); _ISR_Enable( level ); } diff --git a/cpukit/score/src/threadresume.c b/cpukit/score/src/threadresume.c index c82466d3b3..1997c3c293 100644 --- a/cpukit/score/src/threadresume.c +++ b/cpukit/score/src/threadresume.c @@ -23,6 +23,7 @@ #include <rtems/score/isr.h> #include <rtems/score/object.h> #include <rtems/score/priority.h> +#include <rtems/score/scheduler.h> #include <rtems/score/states.h> #include <rtems/score/sysstate.h> #include <rtems/score/thread.h> @@ -68,19 +69,7 @@ void _Thread_Resume( the_thread->current_state = _States_Clear(STATES_SUSPENDED, current_state); if ( _States_Is_ready( current_state ) ) { - - _Priority_bit_map_Add( &the_thread->Priority_map ); - - _Chain_Append_unprotected(the_thread->ready, &the_thread->Object.Node); - - _ISR_Flash( level ); - - 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; - } + _Scheduler_Unblock( &_Scheduler, the_thread ); } } diff --git a/cpukit/score/src/threadsetpriority.c b/cpukit/score/src/threadsetpriority.c index cfe069d4ae..b55de24b43 100644 --- a/cpukit/score/src/threadsetpriority.c +++ b/cpukit/score/src/threadsetpriority.c @@ -23,6 +23,7 @@ #include <rtems/score/isr.h> #include <rtems/score/object.h> #include <rtems/score/priority.h> +#include <rtems/score/scheduler.h> #include <rtems/score/states.h> #include <rtems/score/sysstate.h> #include <rtems/score/thread.h> @@ -50,10 +51,6 @@ void _Thread_Set_priority( ) { the_thread->current_priority = new_priority; - the_thread->ready = &_Thread_Ready_chain[ new_priority ]; - _Priority_bit_map_Initialize_information( - &the_thread->Priority_map, - new_priority - ); + _Scheduler_Thread_scheduler_update(&_Scheduler, the_thread); } diff --git a/cpukit/score/src/threadsetstate.c b/cpukit/score/src/threadsetstate.c index 2edd3bb70d..73a71b70e2 100644 --- a/cpukit/score/src/threadsetstate.c +++ b/cpukit/score/src/threadsetstate.c @@ -23,6 +23,7 @@ #include <rtems/score/isr.h> #include <rtems/score/object.h> #include <rtems/score/priority.h> +#include <rtems/score/scheduler.h> #include <rtems/score/states.h> #include <rtems/score/sysstate.h> #include <rtems/score/thread.h> @@ -54,9 +55,7 @@ void _Thread_Set_state( ) { ISR_Level level; - Chain_Control *ready; - - ready = the_thread->ready; + _ISR_Disable( level ); if ( !_States_Is_ready( the_thread->current_state ) ) { the_thread->current_state = @@ -67,21 +66,7 @@ void _Thread_Set_state( the_thread->current_state = state; - if ( _Chain_Has_only_one_node( ready ) ) { - - _Chain_Initialize_empty( ready ); - _Priority_bit_map_Remove( &the_thread->Priority_map ); - - } else - _Chain_Extract_unprotected( &the_thread->Object.Node ); - - _ISR_Flash( level ); - - if ( _Thread_Is_heir( the_thread ) ) - _Thread_Calculate_heir(); - - if ( _Thread_Is_executing( the_thread ) ) - _Thread_Dispatch_necessary = true; + _Scheduler_Block( &_Scheduler, the_thread); _ISR_Enable( level ); } diff --git a/cpukit/score/src/threadsettransient.c b/cpukit/score/src/threadsettransient.c index 36f60a6077..ce697f2d02 100644 --- a/cpukit/score/src/threadsettransient.c +++ b/cpukit/score/src/threadsettransient.c @@ -23,6 +23,8 @@ #include <rtems/score/isr.h> #include <rtems/score/object.h> #include <rtems/score/priority.h> +#include <rtems/score/scheduler.h> +#include <rtems/score/schedulerpriority.h> #include <rtems/score/states.h> #include <rtems/score/sysstate.h> #include <rtems/score/thread.h> @@ -54,22 +56,15 @@ void _Thread_Set_transient( { ISR_Level level; uint32_t old_state; - Chain_Control *ready; - - ready = the_thread->ready; + _ISR_Disable( level ); old_state = the_thread->current_state; the_thread->current_state = _States_Set( STATES_TRANSIENT, old_state ); + /* FIXME: need to check which scheduler to use? */ if ( _States_Is_ready( old_state ) ) { - if ( _Chain_Has_only_one_node( ready ) ) { - - _Chain_Initialize_empty( ready ); - _Priority_bit_map_Remove( &the_thread->Priority_map ); - - } else - _Chain_Extract_unprotected( &the_thread->Object.Node ); + _Scheduler_priority_Ready_queue_extract( the_thread); } _ISR_Enable( level ); diff --git a/cpukit/score/src/threadsuspend.c b/cpukit/score/src/threadsuspend.c index 8cb2796691..8b4a631e5f 100644 --- a/cpukit/score/src/threadsuspend.c +++ b/cpukit/score/src/threadsuspend.c @@ -23,6 +23,7 @@ #include <rtems/score/isr.h> #include <rtems/score/object.h> #include <rtems/score/priority.h> +#include <rtems/score/scheduler.h> #include <rtems/score/states.h> #include <rtems/score/sysstate.h> #include <rtems/score/thread.h> @@ -52,9 +53,7 @@ void _Thread_Suspend( ) { ISR_Level level; - Chain_Control *ready; - - ready = the_thread->ready; + _ISR_Disable( level ); if ( !_States_Is_ready( the_thread->current_state ) ) { the_thread->current_state = @@ -65,21 +64,7 @@ void _Thread_Suspend( the_thread->current_state = STATES_SUSPENDED; - if ( _Chain_Has_only_one_node( ready ) ) { - - _Chain_Initialize_empty( ready ); - _Priority_bit_map_Remove( &the_thread->Priority_map ); - - } else - _Chain_Extract_unprotected( &the_thread->Object.Node ); - - _ISR_Flash( level ); - - if ( _Thread_Is_heir( the_thread ) ) - _Thread_Calculate_heir(); - - if ( _Thread_Is_executing( the_thread ) ) - _Thread_Dispatch_necessary = true; + _Scheduler_Block(&_Scheduler, the_thread); _ISR_Enable( level ); } diff --git a/cpukit/score/src/threadtickletimeslice.c b/cpukit/score/src/threadtickletimeslice.c index b05305650a..951339cb42 100644 --- a/cpukit/score/src/threadtickletimeslice.c +++ b/cpukit/score/src/threadtickletimeslice.c @@ -23,6 +23,7 @@ #include <rtems/score/isr.h> #include <rtems/score/object.h> #include <rtems/score/priority.h> +#include <rtems/score/scheduler.h> #include <rtems/score/states.h> #include <rtems/score/sysstate.h> #include <rtems/score/thread.h> @@ -89,7 +90,7 @@ void _Thread_Tickle_timeslice( void ) * currently executing thread is placed at the rear of the * FIFO for this priority and a new heir is selected. */ - _Thread_Yield_processor(); + _Scheduler_Yield( ); executing->cpu_time_budget = _Thread_Ticks_per_timeslice; } break; |