Delete global variables _Priority_Major_bit_map and _Priority_Bit_map. This makes it possible to use multiple priority scheduler instances for example with clustered/partitioned scheduling on SMP. --- cpukit/sapi/include/confdefs.h | 5 +- cpukit/score/Makefile.am | 2 - cpukit/score/include/rtems/score/prioritybitmap.h | 18 +++ .../score/include/rtems/score/prioritybitmapimpl.h | 108 +++++++------------ .../score/include/rtems/score/schedulerpriority.h | 12 ++ .../include/rtems/score/schedulerpriorityimpl.h | 66 ++++++++---- .../include/rtems/score/schedulerprioritysmp.h | 7 +- .../score/include/rtems/score/schedulersimplesmp.h | 2 +- cpukit/score/include/rtems/score/schedulersmp.h | 9 +- .../score/include/rtems/score/schedulersmpimpl.h | 16 ++- cpukit/score/src/prioritybitmap.c | 27 ----- cpukit/score/src/schedulerpriority.c | 10 +- cpukit/score/src/schedulerpriorityblock.c | 6 +- cpukit/score/src/schedulerpriorityenqueue.c | 4 +- cpukit/score/src/schedulerpriorityenqueuefirst.c | 7 +- cpukit/score/src/schedulerpriorityextract.c | 6 +- cpukit/score/src/schedulerprioritysmp.c | 111 ++++++++++++++----- cpukit/score/src/schedulerpriorityunblock.c | 4 +- cpukit/score/src/schedulerpriorityupdate.c | 8 +- cpukit/score/src/schedulersimplesmp.c | 25 ++++- cpukit/score/src/schedulersmpstartidle.c | 40 ------- testsuites/sptests/spsize/size.c | 7 +- testsuites/tmtests/tm26/task1.c | 31 +++--- testsuites/tmtests/tm27/task1.c | 11 +- 24 files changed, 291 insertions(+), 251 deletions(-) delete mode 100644 cpukit/score/src/prioritybitmap.c delete mode 100644 cpukit/score/src/schedulersmpstartidle.c
diff --git a/cpukit/sapi/include/confdefs.h b/cpukit/sapi/include/confdefs.h index d8cf2af..6f69dc4 100644 --- a/cpukit/sapi/include/confdefs.h +++ b/cpukit/sapi/include/confdefs.h @@ -676,7 +676,8 @@ const rtems_libio_helper rtems_fs_init_helper = */ #define CONFIGURE_MEMORY_FOR_SCHEDULER ( \ _Configure_From_workspace( \ - ((CONFIGURE_MAXIMUM_PRIORITY+1) * sizeof(Chain_Control)) ) \ + sizeof(Scheduler_priority_Control) + \ + ((CONFIGURE_MAXIMUM_PRIORITY) * sizeof(Chain_Control)) ) \ ) #define CONFIGURE_MEMORY_PER_TASK_FOR_SCHEDULER ( \ _Configure_From_workspace(sizeof(Scheduler_priority_Per_thread)) ) @@ -695,7 +696,7 @@ const rtems_libio_helper rtems_fs_init_helper = */ #define CONFIGURE_MEMORY_FOR_SCHEDULER ( \ _Configure_From_workspace( \ - sizeof(Scheduler_SMP_Control) + \ + sizeof(Scheduler_priority_SMP_Control) + \ ((CONFIGURE_MAXIMUM_PRIORITY) * sizeof(Chain_Control)) ) \ ) #define CONFIGURE_MEMORY_PER_TASK_FOR_SCHEDULER ( \ diff --git a/cpukit/score/Makefile.am b/cpukit/score/Makefile.am index 852360c..6c9e682 100644 --- a/cpukit/score/Makefile.am +++ b/cpukit/score/Makefile.am @@ -127,7 +127,6 @@ if HAS_SMP libscore_a_SOURCES += src/profilingsmplock.c libscore_a_SOURCES += src/schedulerprioritysmp.c libscore_a_SOURCES += src/schedulersimplesmp.c -libscore_a_SOURCES += src/schedulersmpstartidle.c libscore_a_SOURCES += src/smp.c libscore_a_SOURCES += src/cpuset.c libscore_a_SOURCES += src/cpusetprintsupport.c @@ -191,7 +190,6 @@ libscore_a_SOURCES += src/objectallocate.c src/objectclose.c \ ## SCHEDULER_C_FILES libscore_a_SOURCES += src/log2table.c -libscore_a_SOURCES += src/prioritybitmap.c libscore_a_SOURCES += src/scheduler.c libscore_a_SOURCES += src/schedulerdefaultallocatefree.c libscore_a_SOURCES += src/schedulerdefaultreleasejob.c diff --git a/cpukit/score/include/rtems/score/prioritybitmap.h b/cpukit/score/include/rtems/score/prioritybitmap.h index 2ef78be..f363fe4 100644 --- a/cpukit/score/include/rtems/score/prioritybitmap.h +++ b/cpukit/score/include/rtems/score/prioritybitmap.h @@ -37,6 +37,24 @@ extern "C" { * */ +typedef struct { + /** + * @brief Each sixteen bit entry in this word is associated with one of the + * sixteen entries in the bit map. + */ + Priority_bit_map_Word major_bit_map; + + /** + * @brief Each bit in the bit map indicates whether or not there are threads + * ready at a particular priority. + * + * The mapping of individual priority levels to particular bits is processor + * dependent as is the value of each bit used to indicate that threads are + * ready at that priority. + */ + Priority_bit_map_Word bit_map[ 16 ]; +} Priority_bit_map_Control; + /** * The following record defines the information associated with * each thread to manage its interaction with the priority bit maps. diff --git a/cpukit/score/include/rtems/score/prioritybitmapimpl.h b/cpukit/score/include/rtems/score/prioritybitmapimpl.h index df65fb4..de90ef7 100644 --- a/cpukit/score/include/rtems/score/prioritybitmapimpl.h +++ b/cpukit/score/include/rtems/score/prioritybitmapimpl.h @@ -22,6 +22,8 @@ #include <rtems/score/prioritybitmap.h> #include <rtems/score/priority.h> +#include <string.h> + #ifdef __cplusplus extern "C" { #endif @@ -31,26 +33,6 @@ extern "C" { */ /**@{**/ -/* - * The Priority_bit_map_Word 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. - */ -extern volatile Priority_bit_map_Word _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 - * individual priority levels to particular bits is processor - * dependent as is the value of each bit used to indicate that - * threads are ready at that priority. - */ -extern Priority_bit_map_Word - _Priority_Bit_map[16] CPU_STRUCTURE_ALIGNMENT; - #if ( CPU_USE_GENERIC_BITFIELD_DATA == TRUE ) /** @@ -188,74 +170,67 @@ RTEMS_INLINE_ROUTINE uint32_t _Priority_Bits_index ( #endif -/** - * Priority Queue implemented by bit map - */ - -/** - * This is the minor bit map. - */ -extern Priority_bit_map_Word _Priority_Bit_map[16] CPU_STRUCTURE_ALIGNMENT; +RTEMS_INLINE_ROUTINE void _Priority_bit_map_Initialize( + Priority_bit_map_Control *bit_map +) +{ + memset( bit_map, 0, sizeof( *bit_map ) ); +} /** - * This routine uses the_priority_map to update the priority - * bit maps to indicate that a thread has been readied. + * Priority Queue implemented by bit map */ RTEMS_INLINE_ROUTINE void _Priority_bit_map_Add ( - Priority_bit_map_Information *the_priority_map + Priority_bit_map_Control *bit_map, + Priority_bit_map_Information *bit_map_info ) { - *the_priority_map->minor |= the_priority_map->ready_minor; - _Priority_Major_bit_map |= the_priority_map->ready_major; + *bit_map_info->minor |= bit_map_info->ready_minor; + bit_map->major_bit_map |= bit_map_info->ready_major; } -/** - * This routine uses the_priority_map to update the priority - * bit maps to indicate that a thread has been removed from the - * ready state. - */ - RTEMS_INLINE_ROUTINE void _Priority_bit_map_Remove ( - Priority_bit_map_Information *the_priority_map + Priority_bit_map_Control *bit_map, + Priority_bit_map_Information *bit_map_info ) { - *the_priority_map->minor &= the_priority_map->block_minor; - if ( *the_priority_map->minor == 0 ) - _Priority_Major_bit_map &= the_priority_map->block_major; + *bit_map_info->minor &= bit_map_info->block_minor; + if ( *bit_map_info->minor == 0 ) + bit_map->major_bit_map &= bit_map_info->block_major; } -/** - * This function returns the priority of the highest priority - * ready thread. - */ - -RTEMS_INLINE_ROUTINE Priority_Control _Priority_bit_map_Get_highest( void ) +RTEMS_INLINE_ROUTINE Priority_Control _Priority_bit_map_Get_highest( + const Priority_bit_map_Control *bit_map +) { Priority_bit_map_Word minor; Priority_bit_map_Word major; - _Bitfield_Find_first_bit( _Priority_Major_bit_map, major ); - _Bitfield_Find_first_bit( _Priority_Bit_map[major], minor ); + /* Avoid problems with some inline ASM statements */ + Priority_bit_map_Word tmp; + + tmp = bit_map->major_bit_map; + _Bitfield_Find_first_bit( tmp, major ); + + tmp = bit_map->bit_map[ major ]; + _Bitfield_Find_first_bit( tmp, minor ); return (_Priority_Bits_index( major ) << 4) + _Priority_Bits_index( minor ); } -RTEMS_INLINE_ROUTINE bool _Priority_bit_map_Is_empty( void ) +RTEMS_INLINE_ROUTINE bool _Priority_bit_map_Is_empty( + const Priority_bit_map_Control *bit_map +) { - return _Priority_Major_bit_map == 0; + return bit_map->major_bit_map == 0; } -/** - * This routine initializes the_priority_map so that it - * contains the information necessary to manage a thread - * at new_priority. - */ - RTEMS_INLINE_ROUTINE void _Priority_bit_map_Initialize_information( - Priority_bit_map_Information *the_priority_map, - Priority_Control new_priority + Priority_bit_map_Control *bit_map, + Priority_bit_map_Information *bit_map_info, + Priority_Control new_priority ) { Priority_bit_map_Word major; @@ -265,18 +240,17 @@ RTEMS_INLINE_ROUTINE void _Priority_bit_map_Initialize_information( major = _Priority_Major( new_priority ); minor = _Priority_Minor( new_priority ); - the_priority_map->minor = - &_Priority_Bit_map[ _Priority_Bits_index(major) ]; + bit_map_info->minor = &bit_map->bit_map[ _Priority_Bits_index( major ) ]; mask = _Priority_Mask( major ); - the_priority_map->ready_major = mask; + bit_map_info->ready_major = mask; /* Add _Priority_Mask_invert to non-generic bitfield then change this code. */ - the_priority_map->block_major = (Priority_bit_map_Word)(~((uint32_t)mask)); + bit_map_info->block_major = (Priority_bit_map_Word)(~((uint32_t)mask)); mask = _Priority_Mask( minor ); - the_priority_map->ready_minor = mask; + bit_map_info->ready_minor = mask; /* Add _Priority_Mask_invert to non-generic bitfield then change this code. */ - the_priority_map->block_minor = (Priority_bit_map_Word)(~((uint32_t)mask)); + bit_map_info->block_minor = (Priority_bit_map_Word)(~((uint32_t)mask)); } /** @} */ diff --git a/cpukit/score/include/rtems/score/schedulerpriority.h b/cpukit/score/include/rtems/score/schedulerpriority.h index 605ab39..9128e0b 100644 --- a/cpukit/score/include/rtems/score/schedulerpriority.h +++ b/cpukit/score/include/rtems/score/schedulerpriority.h @@ -56,6 +56,18 @@ extern "C" { _Scheduler_default_Start_idle /* start idle entry point */ \ } +typedef struct { + /** + * @brief Bit map to indicate non-empty ready queues. + */ + Priority_bit_map_Control Bit_map; + + /** + * @brief One ready queue per priority level. + */ + Chain_Control ready[ 1 ]; +} Scheduler_priority_Control; + /** * Per-thread data related to the _Scheduler_PRIORITY scheduling policy. */ diff --git a/cpukit/score/include/rtems/score/schedulerpriorityimpl.h b/cpukit/score/include/rtems/score/schedulerpriorityimpl.h index 7869675..8042285 100644 --- a/cpukit/score/include/rtems/score/schedulerpriorityimpl.h +++ b/cpukit/score/include/rtems/score/schedulerpriorityimpl.h @@ -35,16 +35,16 @@ extern "C" { */ /**@{**/ -RTEMS_INLINE_ROUTINE Chain_Control * -_Scheduler_priority_Get_ready_queues( void ) +RTEMS_INLINE_ROUTINE Scheduler_priority_Control * + _Scheduler_priority_Instance( void ) { - return ( Chain_Control * ) _Scheduler.information; + return _Scheduler.information; } /** * @brief Ready queue initialization. * - * This routine initializes @a the_ready_queue for priority-based scheduling. + * This routine initializes @a ready_queues for priority-based scheduling. */ RTEMS_INLINE_ROUTINE void _Scheduler_priority_Ready_queue_initialize( Chain_Control *ready_queues @@ -68,10 +68,12 @@ _Scheduler_priority_Get_scheduler_info( Thread_Control *thread ) * * This routine puts @a the_thread on to the priority-based ready queue. * - * @param[in] the_thread is a pointer to the thread + * @param[in] the_thread The thread to enqueue. + * @param[in] bit_map The priority bit map of the scheduler instance. */ RTEMS_INLINE_ROUTINE void _Scheduler_priority_Ready_queue_enqueue( - Thread_Control *the_thread + Thread_Control *the_thread, + Priority_bit_map_Control *bit_map ) { Scheduler_priority_Per_thread *sched_info_of_thread = @@ -79,7 +81,7 @@ RTEMS_INLINE_ROUTINE void _Scheduler_priority_Ready_queue_enqueue( Chain_Control *ready_chain = sched_info_of_thread->ready_chain; _Chain_Append_unprotected( ready_chain, &the_thread->Object.Node ); - _Priority_bit_map_Add( &sched_info_of_thread->Priority_map ); + _Priority_bit_map_Add( bit_map, &sched_info_of_thread->Priority_map ); } /** @@ -89,10 +91,12 @@ RTEMS_INLINE_ROUTINE void _Scheduler_priority_Ready_queue_enqueue( * For priority-based ready queues, the thread will be the first thread * at its priority level. * - * @param[in] the_thread is a pointer to the thread. + * @param[in] the_thread The thread to enqueue. + * @param[in] bit_map The priority bit map of the scheduler instance. */ RTEMS_INLINE_ROUTINE void _Scheduler_priority_Ready_queue_enqueue_first( - Thread_Control *the_thread + Thread_Control *the_thread, + Priority_bit_map_Control *bit_map ) { Scheduler_priority_Per_thread *sched_info_of_thread = @@ -100,7 +104,7 @@ RTEMS_INLINE_ROUTINE void _Scheduler_priority_Ready_queue_enqueue_first( Chain_Control *ready_chain = sched_info_of_thread->ready_chain; _Chain_Prepend_unprotected( ready_chain, &the_thread->Object.Node ); - _Priority_bit_map_Add( &sched_info_of_thread->Priority_map ); + _Priority_bit_map_Add( bit_map, &sched_info_of_thread->Priority_map ); } /** @@ -109,10 +113,12 @@ RTEMS_INLINE_ROUTINE void _Scheduler_priority_Ready_queue_enqueue_first( * This routine removes a specific thread from the specified * priority-based ready queue. * - * @param[in] the_thread is a pointer to the thread. + * @param[in] the_thread The thread to extract. + * @param[in] bit_map The priority bit map of the scheduler instance. */ RTEMS_INLINE_ROUTINE void _Scheduler_priority_Ready_queue_extract( - Thread_Control *the_thread + Thread_Control *the_thread, + Priority_bit_map_Control *bit_map ) { Scheduler_priority_Per_thread *sched_info_of_thread = @@ -121,28 +127,39 @@ RTEMS_INLINE_ROUTINE void _Scheduler_priority_Ready_queue_extract( if ( _Chain_Has_only_one_node( ready_chain ) ) { _Chain_Initialize_empty( ready_chain ); - _Priority_bit_map_Remove( &sched_info_of_thread->Priority_map ); + _Priority_bit_map_Remove( bit_map, &sched_info_of_thread->Priority_map ); } else { _Chain_Extract_unprotected( &the_thread->Object.Node ); } } +RTEMS_INLINE_ROUTINE void _Scheduler_priority_Extract_body( + Thread_Control *the_thread +) +{ + Scheduler_priority_Control *scheduler = _Scheduler_priority_Instance(); + + _Scheduler_priority_Ready_queue_extract( the_thread, &scheduler->Bit_map ); +} + /** * @brief Return a pointer to the first thread. * - * This routines returns a pointer to the first thread on @a the_ready_queue. + * This routines returns a pointer to the first thread on @a ready_queues. * - * @param[in] the_ready_queue - pointer to thread queue + * @param[in] bit_map The priority bit map of the scheduler instance. + * @param[in] ready_queues The ready queues of the scheduler instance. * * @return This method returns the first thread or NULL */ RTEMS_INLINE_ROUTINE Thread_Control *_Scheduler_priority_Ready_queue_first( - Chain_Control *the_ready_queue + Priority_bit_map_Control *bit_map, + Chain_Control *ready_queues ) { - Priority_Control index = _Priority_bit_map_Get_highest(); + Priority_Control index = _Priority_bit_map_Get_highest( bit_map ); - return (Thread_Control *) _Chain_First( &the_ready_queue[ index ] ); + return (Thread_Control *) _Chain_First( &ready_queues[ index ] ); } /** @@ -178,8 +195,11 @@ RTEMS_INLINE_ROUTINE void _Scheduler_priority_Schedule_body( bool force_dispatch ) { - Chain_Control *ready_queues = _Scheduler_priority_Get_ready_queues(); - Thread_Control *heir = _Scheduler_priority_Ready_queue_first( ready_queues ); + Scheduler_priority_Control *scheduler = _Scheduler_priority_Instance(); + Thread_Control *heir = _Scheduler_priority_Ready_queue_first( + &scheduler->Bit_map, + &scheduler->ready[ 0 ] + ); ( void ) thread; @@ -187,8 +207,9 @@ RTEMS_INLINE_ROUTINE void _Scheduler_priority_Schedule_body( } RTEMS_INLINE_ROUTINE void _Scheduler_priority_Update_body( - Thread_Control *thread, - Chain_Control *ready_queues + Thread_Control *thread, + Priority_bit_map_Control *bit_map, + Chain_Control *ready_queues ) { Scheduler_priority_Per_thread *sched_info_of_thread = @@ -198,6 +219,7 @@ RTEMS_INLINE_ROUTINE void _Scheduler_priority_Update_body( &ready_queues[ thread->current_priority ]; _Priority_bit_map_Initialize_information( + bit_map, &sched_info_of_thread->Priority_map, thread->current_priority ); diff --git a/cpukit/score/include/rtems/score/schedulerprioritysmp.h b/cpukit/score/include/rtems/score/schedulerprioritysmp.h index b0e5fad..f30b706 100644 --- a/cpukit/score/include/rtems/score/schedulerprioritysmp.h +++ b/cpukit/score/include/rtems/score/schedulerprioritysmp.h @@ -66,7 +66,7 @@ extern "C" { _Scheduler_priority_Priority_compare, \ _Scheduler_default_Release_job, \ _Scheduler_default_Tick, \ - _Scheduler_SMP_Start_idle \ + _Scheduler_priority_SMP_Start_idle \ } void _Scheduler_priority_SMP_Initialize( void ); @@ -85,6 +85,11 @@ void _Scheduler_priority_SMP_Extract( Thread_Control *thread ); void _Scheduler_priority_SMP_Yield( Thread_Control *thread ); +void _Scheduler_priority_SMP_Start_idle( + Thread_Control *thread, + Per_CPU_Control *cpu +); + /** @} */ #ifdef __cplusplus diff --git a/cpukit/score/include/rtems/score/schedulersimplesmp.h b/cpukit/score/include/rtems/score/schedulersimplesmp.h index 1a69358..cf3c261 100644 --- a/cpukit/score/include/rtems/score/schedulersimplesmp.h +++ b/cpukit/score/include/rtems/score/schedulersimplesmp.h @@ -68,7 +68,7 @@ extern "C" { _Scheduler_priority_Priority_compare, \ _Scheduler_default_Release_job, \ _Scheduler_default_Tick, \ - _Scheduler_SMP_Start_idle \ + _Scheduler_simple_smp_Start_idle \ } void _Scheduler_simple_smp_Initialize( void ); diff --git a/cpukit/score/include/rtems/score/schedulersmp.h b/cpukit/score/include/rtems/score/schedulersmp.h index 7107e0e..c7c9b14 100644 --- a/cpukit/score/include/rtems/score/schedulersmp.h +++ b/cpukit/score/include/rtems/score/schedulersmp.h @@ -25,6 +25,7 @@ #include <rtems/score/chain.h> #include <rtems/score/percpu.h> +#include <rtems/score/prioritybitmap.h> #include <rtems/score/thread.h> #ifdef __cplusplus @@ -44,10 +45,10 @@ typedef struct { Chain_Control ready[ 1 ]; } Scheduler_SMP_Control; -void _Scheduler_SMP_Start_idle( - Thread_Control *thread, - Per_CPU_Control *cpu -); +typedef struct { + Priority_bit_map_Control Bit_map; + Scheduler_SMP_Control Base; +} Scheduler_priority_SMP_Control; /** @} */ diff --git a/cpukit/score/include/rtems/score/schedulersmpimpl.h b/cpukit/score/include/rtems/score/schedulersmpimpl.h index d977b3f..1009b24 100644 --- a/cpukit/score/include/rtems/score/schedulersmpimpl.h +++ b/cpukit/score/include/rtems/score/schedulersmpimpl.h @@ -57,11 +57,6 @@ typedef void ( *Scheduler_SMP_Move )( Thread_Control *thread_to_move ); -static inline Scheduler_SMP_Control *_Scheduler_SMP_Instance( void ) -{ - return _Scheduler.information; -} - static inline void _Scheduler_SMP_Allocate_processor( Thread_Control *scheduled, Thread_Control *victim @@ -262,6 +257,17 @@ static inline void _Scheduler_SMP_Insert_scheduled_fifo( ); } +static inline void _Scheduler_SMP_Start_idle( + Scheduler_SMP_Control *self, + Thread_Control *thread, + Per_CPU_Control *cpu +) +{ + thread->is_scheduled = true; + _Thread_Set_CPU( thread, cpu ); + _Chain_Append_unprotected( &self->scheduled, &thread->Object.Node ); +} + /** @} */ #ifdef __cplusplus diff --git a/cpukit/score/src/prioritybitmap.c b/cpukit/score/src/prioritybitmap.c deleted file mode 100644 index d05ede1..0000000 --- a/cpukit/score/src/prioritybitmap.c +++ /dev/null @@ -1,27 +0,0 @@ -/* - * @file - * - * @brief Priority Bit Map Implementation - * - * @ingroup ScorePriorityBitmap - */ - -/* - * Copyright (C) 2010 Gedare Bloom. - * Copyright (C) 2011 On-Line Applications Research Corporation (OAR). - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. - */ - -#if HAVE_CONFIG_H -#include "config.h" -#endif - -#include <rtems/score/prioritybitmapimpl.h> - -Priority_bit_map_Word _Priority_Bit_map[16] CPU_STRUCTURE_ALIGNMENT; - -/* Instantiate any global variables needed by the priority scheduler */ -volatile Priority_bit_map_Word _Priority_Major_bit_map; diff --git a/cpukit/score/src/schedulerpriority.c b/cpukit/score/src/schedulerpriority.c index f393f4f..95d4609 100644 --- a/cpukit/score/src/schedulerpriority.c +++ b/cpukit/score/src/schedulerpriority.c @@ -23,12 +23,12 @@ void _Scheduler_priority_Initialize(void) { - /* allocate ready queue structures */ - Chain_Control *ready_queues = _Workspace_Allocate_or_fatal_error( - ((size_t) PRIORITY_MAXIMUM + 1) * sizeof(Chain_Control) + Scheduler_priority_Control *self = _Workspace_Allocate_or_fatal_error( + sizeof( *self ) + PRIORITY_MAXIMUM * sizeof( Chain_Control ) ); - _Scheduler_priority_Ready_queue_initialize( ready_queues ); + _Priority_bit_map_Initialize( &self->Bit_map ); + _Scheduler_priority_Ready_queue_initialize( &self->ready[ 0 ] ); - _Scheduler.information = ready_queues; + _Scheduler.information = self; } diff --git a/cpukit/score/src/schedulerpriorityblock.c b/cpukit/score/src/schedulerpriorityblock.c index 7d24d17..259d6f0 100644 --- a/cpukit/score/src/schedulerpriorityblock.c +++ b/cpukit/score/src/schedulerpriorityblock.c @@ -22,12 +22,10 @@ #include <rtems/score/schedulerpriorityimpl.h> -void _Scheduler_priority_Block( - Thread_Control *the_thread -) +void _Scheduler_priority_Block( Thread_Control *the_thread ) { _Scheduler_Generic_block( - _Scheduler_priority_Ready_queue_extract, + _Scheduler_priority_Extract_body, _Scheduler_priority_Schedule_body, the_thread ); diff --git a/cpukit/score/src/schedulerpriorityenqueue.c b/cpukit/score/src/schedulerpriorityenqueue.c index ff1c69d..c40416f 100644 --- a/cpukit/score/src/schedulerpriorityenqueue.c +++ b/cpukit/score/src/schedulerpriorityenqueue.c @@ -24,5 +24,7 @@ void _Scheduler_priority_Enqueue( Thread_Control *the_thread ) { - _Scheduler_priority_Ready_queue_enqueue( the_thread ); + Scheduler_priority_Control *scheduler = _Scheduler_priority_Instance(); + + _Scheduler_priority_Ready_queue_enqueue( the_thread, &scheduler->Bit_map ); } diff --git a/cpukit/score/src/schedulerpriorityenqueuefirst.c b/cpukit/score/src/schedulerpriorityenqueuefirst.c index b9065cc..8de06fa 100644 --- a/cpukit/score/src/schedulerpriorityenqueuefirst.c +++ b/cpukit/score/src/schedulerpriorityenqueuefirst.c @@ -24,6 +24,11 @@ void _Scheduler_priority_Enqueue_first( Thread_Control *the_thread ) { - _Scheduler_priority_Ready_queue_enqueue_first( the_thread ); + Scheduler_priority_Control *scheduler = _Scheduler_priority_Instance(); + + _Scheduler_priority_Ready_queue_enqueue_first( + the_thread, + &scheduler->Bit_map + ); } diff --git a/cpukit/score/src/schedulerpriorityextract.c b/cpukit/score/src/schedulerpriorityextract.c index 7e45527..e5888dc 100644 --- a/cpukit/score/src/schedulerpriorityextract.c +++ b/cpukit/score/src/schedulerpriorityextract.c @@ -21,9 +21,7 @@ #include <rtems/score/schedulerpriorityimpl.h> -void _Scheduler_priority_Extract( - Thread_Control *the_thread -) +void _Scheduler_priority_Extract( Thread_Control *the_thread ) { - _Scheduler_priority_Ready_queue_extract( the_thread ); + _Scheduler_priority_Extract_body( the_thread ); } diff --git a/cpukit/score/src/schedulerprioritysmp.c b/cpukit/score/src/schedulerprioritysmp.c index dedd270..7ed4446 100644 --- a/cpukit/score/src/schedulerprioritysmp.c +++ b/cpukit/score/src/schedulerprioritysmp.c @@ -29,80 +29,123 @@ #include <rtems/score/schedulersmpimpl.h> #include <rtems/score/wkspace.h> +static Scheduler_priority_SMP_Control *_Scheduler_priority_SMP_Instance( void ) +{ + return _Scheduler.information; +} + +static Scheduler_priority_SMP_Control *_Scheduler_priority_SMP_Base_to_self( + Scheduler_SMP_Control *base +) +{ + return (Scheduler_priority_SMP_Control *) + ( (char *) base - offsetof( Scheduler_priority_SMP_Control, Base ) ); +} + void _Scheduler_priority_SMP_Initialize( void ) { - Scheduler_SMP_Control *self = _Workspace_Allocate_or_fatal_error( + Scheduler_priority_SMP_Control *self = _Workspace_Allocate_or_fatal_error( sizeof( *self ) + PRIORITY_MAXIMUM * sizeof( Chain_Control ) ); - _Chain_Initialize_empty( &self->scheduled ); - _Scheduler_priority_Ready_queue_initialize( &self->ready[ 0 ] ); + _Priority_bit_map_Initialize( &self->Bit_map ); + _Chain_Initialize_empty( &self->Base.scheduled ); + _Scheduler_priority_Ready_queue_initialize( &self->Base.ready[ 0 ] ); _Scheduler.information = self; } void _Scheduler_priority_SMP_Update( Thread_Control *thread ) { - Scheduler_SMP_Control *self = _Scheduler_SMP_Instance(); + Scheduler_priority_SMP_Control *self = _Scheduler_priority_SMP_Instance(); - _Scheduler_priority_Update_body( thread, &self->ready[ 0 ] ); + _Scheduler_priority_Update_body( + thread, + &self->Bit_map, + &self->Base.ready[ 0 ] + ); } static Thread_Control *_Scheduler_priority_SMP_Get_highest_ready( - Scheduler_SMP_Control *self + Scheduler_SMP_Control *base ) { + Scheduler_priority_SMP_Control *self = + _Scheduler_priority_SMP_Base_to_self( base ); Thread_Control *highest_ready = NULL; - if ( !_Priority_bit_map_Is_empty() ) { - highest_ready = _Scheduler_priority_Ready_queue_first( &self->ready[ 0 ] ); + if ( !_Priority_bit_map_Is_empty( &self->Bit_map ) ) { + highest_ready = _Scheduler_priority_Ready_queue_first( + &self->Bit_map, + &self->Base.ready[ 0 ] + ); } return highest_ready; } static void _Scheduler_priority_SMP_Move_from_scheduled_to_ready( - Scheduler_SMP_Control *self, + Scheduler_SMP_Control *base, Thread_Control *scheduled_to_ready ) { + Scheduler_priority_SMP_Control *self = + _Scheduler_priority_SMP_Base_to_self( base ); + _Chain_Extract_unprotected( &scheduled_to_ready->Object.Node ); - _Scheduler_priority_Ready_queue_enqueue_first( scheduled_to_ready ); + _Scheduler_priority_Ready_queue_enqueue_first( + scheduled_to_ready, + &self->Bit_map + ); } static void _Scheduler_priority_SMP_Move_from_ready_to_scheduled( - Scheduler_SMP_Control *self, + Scheduler_SMP_Control *base, Thread_Control *ready_to_scheduled ) { - _Scheduler_priority_Ready_queue_extract( ready_to_scheduled ); + Scheduler_priority_SMP_Control *self = + _Scheduler_priority_SMP_Base_to_self( base ); + + _Scheduler_priority_Ready_queue_extract( + ready_to_scheduled, + &self->Bit_map + ); _Scheduler_simple_Insert_priority_fifo( - &self->scheduled, + &self->Base.scheduled, ready_to_scheduled ); } static void _Scheduler_priority_SMP_Insert_ready_lifo( - Scheduler_SMP_Control *self, + Scheduler_SMP_Control *base, Thread_Control *thread ) { - _Scheduler_priority_Ready_queue_enqueue( thread ); + Scheduler_priority_SMP_Control *self = + _Scheduler_priority_SMP_Base_to_self( base ); + + _Scheduler_priority_Ready_queue_enqueue( thread, &self->Bit_map ); } static void _Scheduler_priority_SMP_Insert_ready_fifo( - Scheduler_SMP_Control *self, + Scheduler_SMP_Control *base, Thread_Control *thread ) { - _Scheduler_priority_Ready_queue_enqueue_first( thread ); + Scheduler_priority_SMP_Control *self = + _Scheduler_priority_SMP_Base_to_self( base ); + + _Scheduler_priority_Ready_queue_enqueue_first( thread, &self->Bit_map ); } static void _Scheduler_priority_SMP_Do_extract( - Scheduler_SMP_Control *self, + Scheduler_SMP_Control *base, Thread_Control *thread ) { + Scheduler_priority_SMP_Control *self = + _Scheduler_priority_SMP_Base_to_self( base ); bool is_scheduled = thread->is_scheduled; ( void ) self; @@ -113,16 +156,16 @@ static void _Scheduler_priority_SMP_Do_extract( if ( is_scheduled ) { _Chain_Extract_unprotected( &thread->Object.Node ); } else { - _Scheduler_priority_Ready_queue_extract( thread ); + _Scheduler_priority_Ready_queue_extract( thread, &self->Bit_map ); } } void _Scheduler_priority_SMP_Block( Thread_Control *thread ) { - Scheduler_SMP_Control *self = _Scheduler_SMP_Instance(); + Scheduler_priority_SMP_Control *self = _Scheduler_priority_SMP_Instance(); _Scheduler_SMP_Block( - self, + &self->Base, thread, _Scheduler_priority_SMP_Do_extract, _Scheduler_priority_SMP_Get_highest_ready, @@ -152,10 +195,10 @@ static void _Scheduler_priority_SMP_Enqueue_ordered( void _Scheduler_priority_SMP_Enqueue_lifo( Thread_Control *thread ) { - Scheduler_SMP_Control *self = _Scheduler_SMP_Instance(); + Scheduler_priority_SMP_Control *self = _Scheduler_priority_SMP_Instance(); _Scheduler_priority_SMP_Enqueue_ordered( - self, + &self->Base, thread, _Scheduler_simple_Insert_priority_lifo_order, _Scheduler_priority_SMP_Insert_ready_lifo, @@ -165,10 +208,10 @@ void _Scheduler_priority_SMP_Enqueue_lifo( Thread_Control *thread ) void _Scheduler_priority_SMP_Enqueue_fifo( Thread_Control *thread ) { - Scheduler_SMP_Control *self = _Scheduler_SMP_Instance(); + Scheduler_priority_SMP_Control *self = _Scheduler_priority_SMP_Instance(); _Scheduler_priority_SMP_Enqueue_ordered( - self, + &self->Base, thread, _Scheduler_simple_Insert_priority_fifo_order, _Scheduler_priority_SMP_Insert_ready_fifo, @@ -178,10 +221,10 @@ void _Scheduler_priority_SMP_Enqueue_fifo( Thread_Control *thread ) void _Scheduler_priority_SMP_Extract( Thread_Control *thread ) { - Scheduler_SMP_Control *self = _Scheduler_SMP_Instance(); + Scheduler_priority_SMP_Control *self = _Scheduler_priority_SMP_Instance(); _Scheduler_SMP_Extract( - self, + &self->Base, thread, _Scheduler_priority_SMP_Do_extract ); @@ -201,12 +244,22 @@ void _Scheduler_priority_SMP_Yield( Thread_Control *thread ) void _Scheduler_priority_SMP_Schedule( Thread_Control *thread ) { - Scheduler_SMP_Control *self = _Scheduler_SMP_Instance(); + Scheduler_priority_SMP_Control *self = _Scheduler_priority_SMP_Instance(); _Scheduler_SMP_Schedule( - self, + &self->Base, thread, _Scheduler_priority_SMP_Get_highest_ready, _Scheduler_priority_SMP_Move_from_ready_to_scheduled ); } + +void _Scheduler_priority_SMP_Start_idle( + Thread_Control *thread, + Per_CPU_Control *cpu +) +{ + Scheduler_priority_SMP_Control *self = _Scheduler_priority_SMP_Instance(); + + _Scheduler_SMP_Start_idle( &self->Base, thread, cpu ); +} diff --git a/cpukit/score/src/schedulerpriorityunblock.c b/cpukit/score/src/schedulerpriorityunblock.c index ad26820..f69c1e2 100644 --- a/cpukit/score/src/schedulerpriorityunblock.c +++ b/cpukit/score/src/schedulerpriorityunblock.c @@ -26,7 +26,9 @@ void _Scheduler_priority_Unblock ( Thread_Control *the_thread ) { - _Scheduler_priority_Ready_queue_enqueue(the_thread); + Scheduler_priority_Control *scheduler = _Scheduler_priority_Instance(); + + _Scheduler_priority_Ready_queue_enqueue( the_thread, &scheduler->Bit_map ); /* TODO: flash critical section? */ diff --git a/cpukit/score/src/schedulerpriorityupdate.c b/cpukit/score/src/schedulerpriorityupdate.c index 8ebaac7..b3b898f 100644 --- a/cpukit/score/src/schedulerpriorityupdate.c +++ b/cpukit/score/src/schedulerpriorityupdate.c @@ -25,7 +25,11 @@ void _Scheduler_priority_Update( Thread_Control *the_thread ) { - Chain_Control *ready_queues = _Scheduler_priority_Get_ready_queues(); + Scheduler_priority_Control *scheduler = _Scheduler_priority_Instance(); - _Scheduler_priority_Update_body( the_thread, ready_queues ); + _Scheduler_priority_Update_body( + the_thread, + &scheduler->Bit_map, + &scheduler->ready[ 0 ] + ); } diff --git a/cpukit/score/src/schedulersimplesmp.c b/cpukit/score/src/schedulersimplesmp.c index f4a20c1..08e2b2d 100644 --- a/cpukit/score/src/schedulersimplesmp.c +++ b/cpukit/score/src/schedulersimplesmp.c @@ -22,6 +22,11 @@ #include <rtems/score/schedulersmpimpl.h> #include <rtems/score/wkspace.h> +static Scheduler_SMP_Control *_Scheduler_simple_SMP_Instance( void ) +{ + return _Scheduler.information; +} + void _Scheduler_simple_smp_Initialize( void ) { Scheduler_SMP_Control *self = @@ -110,7 +115,7 @@ static void _Scheduler_simple_smp_Do_extract( void _Scheduler_simple_smp_Block( Thread_Control *thread ) { - Scheduler_SMP_Control *self = _Scheduler_SMP_Instance(); + Scheduler_SMP_Control *self = _Scheduler_simple_SMP_Instance(); _Scheduler_SMP_Block( self, @@ -143,7 +148,7 @@ static void _Scheduler_simple_smp_Enqueue_ordered( void _Scheduler_simple_smp_Enqueue_priority_lifo( Thread_Control *thread ) { - Scheduler_SMP_Control *self = _Scheduler_SMP_Instance(); + Scheduler_SMP_Control *self = _Scheduler_simple_SMP_Instance(); _Scheduler_simple_smp_Enqueue_ordered( self, @@ -156,7 +161,7 @@ void _Scheduler_simple_smp_Enqueue_priority_lifo( Thread_Control *thread ) void _Scheduler_simple_smp_Enqueue_priority_fifo( Thread_Control *thread ) { - Scheduler_SMP_Control *self = _Scheduler_SMP_Instance(); + Scheduler_SMP_Control *self = _Scheduler_simple_SMP_Instance(); _Scheduler_simple_smp_Enqueue_ordered( self, @@ -169,7 +174,7 @@ void _Scheduler_simple_smp_Enqueue_priority_fifo( Thread_Control *thread ) void _Scheduler_simple_smp_Extract( Thread_Control *thread ) { - Scheduler_SMP_Control *self = _Scheduler_SMP_Instance(); + Scheduler_SMP_Control *self = _Scheduler_simple_SMP_Instance(); _Scheduler_SMP_Extract( self, @@ -192,7 +197,7 @@ void _Scheduler_simple_smp_Yield( Thread_Control *thread ) void _Scheduler_simple_smp_Schedule( Thread_Control *thread ) { - Scheduler_SMP_Control *self = _Scheduler_SMP_Instance(); + Scheduler_SMP_Control *self = _Scheduler_simple_SMP_Instance(); _Scheduler_SMP_Schedule( self, @@ -201,3 +206,13 @@ void _Scheduler_simple_smp_Schedule( Thread_Control *thread ) _Scheduler_simple_smp_Move_from_ready_to_scheduled ); } + +void _Scheduler_simple_smp_Start_idle( + Thread_Control *thread, + Per_CPU_Control *cpu +) +{ + Scheduler_SMP_Control *self = _Scheduler_simple_SMP_Instance(); + + _Scheduler_SMP_Start_idle( self, thread, cpu ); +} diff --git a/cpukit/score/src/schedulersmpstartidle.c b/cpukit/score/src/schedulersmpstartidle.c deleted file mode 100644 index 75d1c8f..0000000 --- a/cpukit/score/src/schedulersmpstartidle.c +++ /dev/null @@ -1,40 +0,0 @@ -/** - * @file - * - * @brief SMP Scheduler Start Idle Operation - * - * @ingroup ScoreSchedulerSMP - */ - -/* - * Copyright (c) 2013 embedded brains GmbH. All rights reserved. - * - * embedded brains GmbH - * Dornierstr. 4 - * 82178 Puchheim - * Germany - * <rt...@embedded-brains.de> - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. - */ - -#if HAVE_CONFIG_H - #include "config.h" -#endif - -#include <rtems/score/schedulersmpimpl.h> -#include <rtems/score/chainimpl.h> - -void _Scheduler_SMP_Start_idle( - Thread_Control *thread, - Per_CPU_Control *cpu -) -{ - Scheduler_SMP_Control *self = _Scheduler_SMP_Instance(); - - thread->is_scheduled = true; - _Thread_Set_CPU( thread, cpu ); - _Chain_Append_unprotected( &self->scheduled, &thread->Object.Node ); -} diff --git a/testsuites/sptests/spsize/size.c b/testsuites/sptests/spsize/size.c index 3dff3d3..f24bc9b 100644 --- a/testsuites/sptests/spsize/size.c +++ b/testsuites/sptests/spsize/size.c @@ -85,9 +85,7 @@ void print_formula(void); #include <rtems/score/schedulerpriority.h> /* Priority scheduling uninitialized (globals) consumption */ -#define SCHEDULER_OVHD ((sizeof _Scheduler) + \ - (sizeof _Priority_Major_bit_map) + \ - (sizeof _Priority_Bit_map)) +#define SCHEDULER_OVHD (sizeof _Scheduler) /* Priority scheduling per-thread consumption. Gets * included in the PER_TASK consumption. @@ -100,7 +98,8 @@ void print_formula(void); * including _Scheduler in SCHEDULER_OVHD. */ #define SCHEDULER_WKSP_SIZE \ - ((RTEMS_MAXIMUM_PRIORITY + 1) * sizeof(Chain_Control )) + (sizeof(Scheduler_priority_Control) + \ + RTEMS_MAXIMUM_PRIORITY * sizeof(Chain_Control )) /****** END OF MEMORY USAGE OF DEFAULT PRIORITY SCHEDULER ******/ #define PER_TASK \ diff --git a/testsuites/tmtests/tm26/task1.c b/testsuites/tmtests/tm26/task1.c index f6cdddf..416403d 100644 --- a/testsuites/tmtests/tm26/task1.c +++ b/testsuites/tmtests/tm26/task1.c @@ -19,6 +19,7 @@ #include <tmacros.h> #include <timesys.h> +#include <rtems/score/schedulerpriorityimpl.h> #include <rtems/rtems/semimpl.h> #if defined( RTEMS_SMP ) && defined( RTEMS_DEBUG ) @@ -370,7 +371,7 @@ rtems_task Middle_task( rtems_task_argument argument ) { - Chain_Control *ready_queues; + Scheduler_priority_Control *scheduler = _Scheduler_priority_Instance(); thread_dispatch_no_fp_time = benchmark_timer_read(); @@ -378,9 +379,8 @@ rtems_task Middle_task( Middle_tcb = _Thread_Get_executing(); - ready_queues = (Chain_Control *) _Scheduler.information; set_thread_executing( - (Thread_Control *) _Chain_First(&ready_queues[LOW_PRIORITY]) + (Thread_Control *) _Chain_First(&scheduler->ready[LOW_PRIORITY]) ); /* do not force context switch */ @@ -403,10 +403,8 @@ rtems_task Low_task( rtems_task_argument argument ) { - Thread_Control *executing; - Chain_Control *ready_queues; - - ready_queues = (Chain_Control *) _Scheduler.information; + Scheduler_priority_Control *scheduler = _Scheduler_priority_Instance(); + Thread_Control *executing; context_switch_no_fp_time = benchmark_timer_read(); @@ -424,7 +422,7 @@ rtems_task Low_task( context_switch_another_task_time = benchmark_timer_read(); set_thread_executing( - (Thread_Control *) _Chain_First(&ready_queues[FP1_PRIORITY]) + (Thread_Control *) _Chain_First(&scheduler->ready[FP1_PRIORITY]) ); /* do not force context switch */ @@ -447,17 +445,16 @@ rtems_task Floating_point_task_1( rtems_task_argument argument ) { - Chain_Control *ready_queues; - Thread_Control *executing; + Scheduler_priority_Control *scheduler = _Scheduler_priority_Instance(); + Thread_Control *executing; FP_DECLARE; context_switch_restore_1st_fp_time = benchmark_timer_read(); executing = _Thread_Get_executing(); - ready_queues = (Chain_Control *) _Scheduler.information; set_thread_executing( - (Thread_Control *) _Chain_First(&ready_queues[FP2_PRIORITY]) + (Thread_Control *) _Chain_First(&scheduler->ready[FP2_PRIORITY]) ); /* do not force context switch */ @@ -483,9 +480,8 @@ rtems_task Floating_point_task_1( executing = _Thread_Get_executing(); - ready_queues = (Chain_Control *) _Scheduler.information; set_thread_executing( - (Thread_Control *) _Chain_First(&ready_queues[FP2_PRIORITY]) + (Thread_Control *) _Chain_First(&scheduler->ready[FP2_PRIORITY]) ); benchmark_timer_initialize(); @@ -504,17 +500,16 @@ rtems_task Floating_point_task_2( rtems_task_argument argument ) { - Chain_Control *ready_queues; - Thread_Control *executing; + Scheduler_priority_Control *scheduler = _Scheduler_priority_Instance(); + Thread_Control *executing; FP_DECLARE; context_switch_save_restore_idle_time = benchmark_timer_read(); executing = _Thread_Get_executing(); - ready_queues = (Chain_Control *) _Scheduler.information; set_thread_executing( - (Thread_Control *) _Chain_First(&ready_queues[FP1_PRIORITY]) + (Thread_Control *) _Chain_First(&scheduler->ready[FP1_PRIORITY]) ); FP_LOAD( 1.0 ); diff --git a/testsuites/tmtests/tm27/task1.c b/testsuites/tmtests/tm27/task1.c index 0062a73..13c3858 100644 --- a/testsuites/tmtests/tm27/task1.c +++ b/testsuites/tmtests/tm27/task1.c @@ -20,6 +20,7 @@ #define CONFIGURE_INIT #include "system.h" +#include <rtems/score/schedulerpriorityimpl.h> #include <bsp.h> #define _RTEMS_TMTEST27 @@ -101,10 +102,10 @@ rtems_task Task_1( rtems_task_argument argument ) { + Scheduler_priority_Control *scheduler = _Scheduler_priority_Instance(); #if defined(RTEMS_SMP) rtems_interrupt_level level; #endif - Chain_Control *ready_queues; Install_tm27_vector( Isr_handler ); @@ -185,9 +186,8 @@ rtems_task Task_1( _ISR_Disable_without_giant(level); #endif - ready_queues = (Chain_Control *) _Scheduler.information; _Thread_Executing = - (Thread_Control *) _Chain_First(&ready_queues[LOW_PRIORITY]); + (Thread_Control *) _Chain_First(&scheduler->ready[LOW_PRIORITY]); _Thread_Dispatch_necessary = 1; @@ -219,10 +219,10 @@ rtems_task Task_2( rtems_task_argument argument ) { + Scheduler_priority_Control *scheduler = _Scheduler_priority_Instance(); #if defined(RTEMS_SMP) rtems_interrupt_level level; #endif - Chain_Control *ready_queues; #if (MUST_WAIT_FOR_INTERRUPT == 1) while ( Interrupt_occurred == 0 ); @@ -255,9 +255,8 @@ rtems_task Task_2( rtems_interrupt_disable(level); #endif - ready_queues = (Chain_Control *) _Scheduler.information; _Thread_Executing = - (Thread_Control *) _Chain_First(&ready_queues[LOW_PRIORITY]); + (Thread_Control *) _Chain_First(&scheduler->ready[LOW_PRIORITY]); _Thread_Dispatch_necessary = 1; -- 1.7.7 _______________________________________________ rtems-devel mailing list rtems-devel@rtems.org http://www.rtems.org/mailman/listinfo/rtems-devel