From f3d9f2288e957caabaa1a312096cb72f8e748807 Mon Sep 17 00:00:00 2001 From: Sebastian Huber Date: Mon, 26 Jun 2017 10:35:45 +0200 Subject: score: Add SMP EDF scheduler Update #3056. --- cpukit/sapi/include/confdefs.h | 24 + cpukit/sapi/include/rtems/scheduler.h | 20 +- cpukit/score/Makefile.am | 2 + cpukit/score/include/rtems/score/scheduleredfsmp.h | 137 ++++++ cpukit/score/preinstall.am | 4 + cpukit/score/src/scheduleredfchangepriority.c | 16 - cpukit/score/src/scheduleredfreleasejob.c | 16 + cpukit/score/src/scheduleredfsmp.c | 499 +++++++++++++++++++++ testsuites/smptests/Makefile.am | 1 + testsuites/smptests/configure.ac | 1 + testsuites/smptests/smpscheduler03/test.c | 5 + testsuites/smptests/smpscheduler07/Makefile.am | 19 + testsuites/smptests/smpscheduler07/init.c | 51 +++ .../smptests/smpscheduler07/smpscheduler07.doc | 11 + .../smptests/smpscheduler07/smpscheduler07.scn | 2 + 15 files changed, 791 insertions(+), 17 deletions(-) create mode 100644 cpukit/score/include/rtems/score/scheduleredfsmp.h create mode 100644 cpukit/score/src/scheduleredfsmp.c create mode 100644 testsuites/smptests/smpscheduler07/Makefile.am create mode 100644 testsuites/smptests/smpscheduler07/init.c create mode 100644 testsuites/smptests/smpscheduler07/smpscheduler07.doc create mode 100644 testsuites/smptests/smpscheduler07/smpscheduler07.scn diff --git a/cpukit/sapi/include/confdefs.h b/cpukit/sapi/include/confdefs.h index 604539b5e8..77b80d1cce 100755 --- a/cpukit/sapi/include/confdefs.h +++ b/cpukit/sapi/include/confdefs.h @@ -780,6 +780,7 @@ extern rtems_initialization_tasks_table Initialization_tasks[]; * - CONFIGURE_SCHEDULER_SIMPLE - Light-weight Priority Scheduler * - CONFIGURE_SCHEDULER_SIMPLE_SMP - Simple SMP Priority Scheduler * - CONFIGURE_SCHEDULER_EDF - EDF Scheduler + * - CONFIGURE_SCHEDULER_EDF_SMP - EDF SMP Scheduler * - CONFIGURE_SCHEDULER_CBS - CBS Scheduler * - CONFIGURE_SCHEDULER_USER - user provided scheduler * @@ -805,6 +806,7 @@ extern rtems_initialization_tasks_table Initialization_tasks[]; !defined(CONFIGURE_SCHEDULER_SIMPLE) && \ !defined(CONFIGURE_SCHEDULER_SIMPLE_SMP) && \ !defined(CONFIGURE_SCHEDULER_EDF) && \ + !defined(CONFIGURE_SCHEDULER_EDF_SMP) && \ !defined(CONFIGURE_SCHEDULER_CBS) #if defined(RTEMS_SMP) && CONFIGURE_MAXIMUM_PROCESSORS > 1 /** @@ -979,6 +981,25 @@ extern rtems_initialization_tasks_table Initialization_tasks[]; #endif #endif +/* + * If the EDF SMP Scheduler is selected, then configure for it. + */ +#if defined(CONFIGURE_SCHEDULER_EDF_SMP) + #if !defined(CONFIGURE_SCHEDULER_NAME) + /** Configure the name of the scheduler instance */ + #define CONFIGURE_SCHEDULER_NAME rtems_build_name('M', 'E', 'D', 'F') + #endif + + #if !defined(CONFIGURE_SCHEDULER_CONTROLS) + /** Configure the context needed by the scheduler instance */ + #define CONFIGURE_SCHEDULER_CONTEXT RTEMS_SCHEDULER_CONTEXT_EDF_SMP(dflt) + + /** Configure the controls for this scheduler instance */ + #define CONFIGURE_SCHEDULER_CONTROLS \ + RTEMS_SCHEDULER_CONTROL_EDF_SMP(dflt, CONFIGURE_SCHEDULER_NAME) + #endif +#endif + /* * If the CBS Scheduler is selected, then configure for it. */ @@ -3151,6 +3172,9 @@ extern rtems_initialization_tasks_table Initialization_tasks[]; #ifdef CONFIGURE_SCHEDULER_EDF Scheduler_EDF_Node EDF; #endif + #ifdef CONFIGURE_SCHEDULER_EDF_SMP + Scheduler_EDF_SMP_Node EDF_SMP; + #endif #ifdef CONFIGURE_SCHEDULER_PRIORITY Scheduler_priority_Node Priority; #endif diff --git a/cpukit/sapi/include/rtems/scheduler.h b/cpukit/sapi/include/rtems/scheduler.h index 0b20aab55e..fae0db4913 100644 --- a/cpukit/sapi/include/rtems/scheduler.h +++ b/cpukit/sapi/include/rtems/scheduler.h @@ -5,7 +5,7 @@ */ /* - * Copyright (c) 2014, 2016 embedded brains GmbH. All rights reserved. + * Copyright (c) 2014, 2017 embedded brains GmbH. All rights reserved. * * embedded brains GmbH * Dornierstr. 4 @@ -93,6 +93,24 @@ } #endif +#ifdef CONFIGURE_SCHEDULER_EDF_SMP + #include + + #define RTEMS_SCHEDULER_CONTEXT_EDF_SMP_NAME( name ) \ + RTEMS_SCHEDULER_CONTEXT_NAME( EDF_SMP_ ## name ) + + #define RTEMS_SCHEDULER_CONTEXT_EDF_SMP( name ) \ + static Scheduler_EDF_SMP_Context RTEMS_SCHEDULER_CONTEXT_EDF_SMP_NAME( name ) + + #define RTEMS_SCHEDULER_CONTROL_EDF_SMP( name, obj_name ) \ + { \ + &RTEMS_SCHEDULER_CONTEXT_EDF_SMP_NAME( name ).Base.Base, \ + SCHEDULER_EDF_SMP_ENTRY_POINTS, \ + SCHEDULER_EDF_MAXIMUM_PRIORITY, \ + ( obj_name ) \ + } +#endif + #ifdef CONFIGURE_SCHEDULER_PRIORITY #include diff --git a/cpukit/score/Makefile.am b/cpukit/score/Makefile.am index a3de792fdf..46b441737f 100644 --- a/cpukit/score/Makefile.am +++ b/cpukit/score/Makefile.am @@ -126,6 +126,7 @@ include_rtems_score_HEADERS += include/rtems/score/threadmp.h endif if HAS_SMP +include_rtems_score_HEADERS += include/rtems/score/scheduleredfsmp.h include_rtems_score_HEADERS += include/rtems/score/schedulerprioritysmpimpl.h include_rtems_score_HEADERS += include/rtems/score/schedulerpriorityaffinitysmp.h include_rtems_score_HEADERS += include/rtems/score/schedulersimplesmp.h @@ -149,6 +150,7 @@ endif if HAS_SMP libscore_a_SOURCES += src/percpustatewait.c libscore_a_SOURCES += src/profilingsmplock.c +libscore_a_SOURCES += src/scheduleredfsmp.c libscore_a_SOURCES += src/schedulerpriorityaffinitysmp.c libscore_a_SOURCES += src/schedulerprioritysmp.c libscore_a_SOURCES += src/schedulersimplesmp.c diff --git a/cpukit/score/include/rtems/score/scheduleredfsmp.h b/cpukit/score/include/rtems/score/scheduleredfsmp.h new file mode 100644 index 0000000000..8f6e85777a --- /dev/null +++ b/cpukit/score/include/rtems/score/scheduleredfsmp.h @@ -0,0 +1,137 @@ +/** + * @file + * + * @brief EDF SMP Scheduler API + * + * @ingroup ScoreSchedulerSMPEDF + */ + +/* + * Copyright (c) 2017 embedded brains GmbH. + * + * 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. + */ + +#ifndef _RTEMS_SCORE_SCHEDULEREDFSMP_H +#define _RTEMS_SCORE_SCHEDULEREDFSMP_H + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @defgroup ScoreSchedulerSMPEDF EDF Priority SMP Scheduler + * + * @ingroup ScoreSchedulerSMP + * + * @{ + */ + +typedef struct { + Scheduler_SMP_Context Base; + RBTree_Control Ready; +} Scheduler_EDF_SMP_Context; + +typedef struct { + Scheduler_SMP_Node Base; +} Scheduler_EDF_SMP_Node; + +#define SCHEDULER_EDF_SMP_ENTRY_POINTS \ + { \ + _Scheduler_EDF_SMP_Initialize, \ + _Scheduler_default_Schedule, \ + _Scheduler_EDF_SMP_Yield, \ + _Scheduler_EDF_SMP_Block, \ + _Scheduler_EDF_SMP_Unblock, \ + _Scheduler_EDF_SMP_Update_priority, \ + _Scheduler_EDF_Map_priority, \ + _Scheduler_EDF_Unmap_priority, \ + _Scheduler_EDF_SMP_Ask_for_help, \ + _Scheduler_EDF_SMP_Reconsider_help_request, \ + _Scheduler_EDF_SMP_Withdraw_node, \ + _Scheduler_EDF_SMP_Add_processor, \ + _Scheduler_EDF_SMP_Remove_processor, \ + _Scheduler_EDF_SMP_Node_initialize, \ + _Scheduler_default_Node_destroy, \ + _Scheduler_EDF_Release_job, \ + _Scheduler_EDF_Cancel_job, \ + _Scheduler_default_Tick, \ + _Scheduler_SMP_Start_idle \ + SCHEDULER_OPERATION_DEFAULT_GET_SET_AFFINITY \ + } + +void _Scheduler_EDF_SMP_Initialize( const Scheduler_Control *scheduler ); + +void _Scheduler_EDF_SMP_Node_initialize( + const Scheduler_Control *scheduler, + Scheduler_Node *node, + Thread_Control *the_thread, + Priority_Control priority +); + +void _Scheduler_EDF_SMP_Block( + const Scheduler_Control *scheduler, + Thread_Control *thread, + Scheduler_Node *node +); + +void _Scheduler_EDF_SMP_Unblock( + const Scheduler_Control *scheduler, + Thread_Control *thread, + Scheduler_Node *node +); + +void _Scheduler_EDF_SMP_Update_priority( + const Scheduler_Control *scheduler, + Thread_Control *the_thread, + Scheduler_Node *node +); + +bool _Scheduler_EDF_SMP_Ask_for_help( + const Scheduler_Control *scheduler, + Thread_Control *the_thread, + Scheduler_Node *node +); + +void _Scheduler_EDF_SMP_Reconsider_help_request( + const Scheduler_Control *scheduler, + Thread_Control *the_thread, + Scheduler_Node *node +); + +void _Scheduler_EDF_SMP_Withdraw_node( + const Scheduler_Control *scheduler, + Thread_Control *the_thread, + Scheduler_Node *node, + Thread_Scheduler_state next_state +); + +void _Scheduler_EDF_SMP_Add_processor( + const Scheduler_Control *scheduler, + Thread_Control *idle +); + +Thread_Control *_Scheduler_EDF_SMP_Remove_processor( + const Scheduler_Control *scheduler, + struct Per_CPU_Control *cpu +); + +void _Scheduler_EDF_SMP_Yield( + const Scheduler_Control *scheduler, + Thread_Control *thread, + Scheduler_Node *node +); + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif /* _RTEMS_SCORE_SCHEDULEREDFSMP_H */ diff --git a/cpukit/score/preinstall.am b/cpukit/score/preinstall.am index 4d468e5dde..da231541b0 100644 --- a/cpukit/score/preinstall.am +++ b/cpukit/score/preinstall.am @@ -439,6 +439,10 @@ $(PROJECT_INCLUDE)/rtems/score/threadmp.h: include/rtems/score/threadmp.h $(PROJ PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/threadmp.h endif if HAS_SMP +$(PROJECT_INCLUDE)/rtems/score/scheduleredfsmp.h: include/rtems/score/scheduleredfsmp.h $(PROJECT_INCLUDE)/rtems/score/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/scheduleredfsmp.h +PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/scheduleredfsmp.h + $(PROJECT_INCLUDE)/rtems/score/schedulerprioritysmpimpl.h: include/rtems/score/schedulerprioritysmpimpl.h $(PROJECT_INCLUDE)/rtems/score/$(dirstamp) $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/schedulerprioritysmpimpl.h PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/schedulerprioritysmpimpl.h diff --git a/cpukit/score/src/scheduleredfchangepriority.c b/cpukit/score/src/scheduleredfchangepriority.c index 0b70bce012..23382973cc 100644 --- a/cpukit/score/src/scheduleredfchangepriority.c +++ b/cpukit/score/src/scheduleredfchangepriority.c @@ -20,22 +20,6 @@ #include -Priority_Control _Scheduler_EDF_Map_priority( - const Scheduler_Control *scheduler, - Priority_Control priority -) -{ - return SCHEDULER_EDF_PRIO_MSB | priority; -} - -Priority_Control _Scheduler_EDF_Unmap_priority( - const Scheduler_Control *scheduler, - Priority_Control priority -) -{ - return priority & ~SCHEDULER_EDF_PRIO_MSB; -} - void _Scheduler_EDF_Update_priority( const Scheduler_Control *scheduler, Thread_Control *the_thread, diff --git a/cpukit/score/src/scheduleredfreleasejob.c b/cpukit/score/src/scheduleredfreleasejob.c index c19d9b9d24..068a0db7a3 100644 --- a/cpukit/score/src/scheduleredfreleasejob.c +++ b/cpukit/score/src/scheduleredfreleasejob.c @@ -20,6 +20,22 @@ #include +Priority_Control _Scheduler_EDF_Map_priority( + const Scheduler_Control *scheduler, + Priority_Control priority +) +{ + return SCHEDULER_EDF_PRIO_MSB | priority; +} + +Priority_Control _Scheduler_EDF_Unmap_priority( + const Scheduler_Control *scheduler, + Priority_Control priority +) +{ + return priority & ~SCHEDULER_EDF_PRIO_MSB; +} + void _Scheduler_EDF_Release_job( const Scheduler_Control *scheduler, Thread_Control *the_thread, diff --git a/cpukit/score/src/scheduleredfsmp.c b/cpukit/score/src/scheduleredfsmp.c new file mode 100644 index 0000000000..270f9a44e9 --- /dev/null +++ b/cpukit/score/src/scheduleredfsmp.c @@ -0,0 +1,499 @@ +/** + * @file + * + * @brief EDF SMP Scheduler Implementation + * + * @ingroup ScoreSchedulerSMPEDF + */ + +/* + * Copyright (c) 2017 embedded brains GmbH. + * + * 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 +#include + +static Scheduler_EDF_SMP_Context * +_Scheduler_EDF_SMP_Get_context( const Scheduler_Control *scheduler ) +{ + return (Scheduler_EDF_SMP_Context *) _Scheduler_Get_context( scheduler ); +} + +static Scheduler_EDF_SMP_Context * +_Scheduler_EDF_SMP_Get_self( Scheduler_Context *context ) +{ + return (Scheduler_EDF_SMP_Context *) context; +} + +static inline Scheduler_EDF_SMP_Node * +_Scheduler_EDF_SMP_Node_downcast( Scheduler_Node *node ) +{ + return (Scheduler_EDF_SMP_Node *) node; +} + +static inline bool _Scheduler_EDF_SMP_Less( + const void *left, + const RBTree_Node *right +) +{ + const Priority_Control *the_left; + const Scheduler_SMP_Node *the_right; + Priority_Control prio_left; + Priority_Control prio_right; + + the_left = left; + the_right = RTEMS_CONTAINER_OF( right, Scheduler_SMP_Node, Base.Node.RBTree ); + + prio_left = *the_left; + prio_right = the_right->priority; + + return prio_left < prio_right; +} + +static inline bool _Scheduler_EDF_SMP_Less_or_equal( + const void *left, + const RBTree_Node *right +) +{ + const Priority_Control *the_left; + const Scheduler_SMP_Node *the_right; + Priority_Control prio_left; + Priority_Control prio_right; + + the_left = left; + the_right = RTEMS_CONTAINER_OF( right, Scheduler_SMP_Node, Base.Node.RBTree ); + + prio_left = *the_left; + prio_right = the_right->priority; + + return prio_left <= prio_right; +} + +void _Scheduler_EDF_SMP_Initialize( const Scheduler_Control *scheduler ) +{ + Scheduler_EDF_SMP_Context *self = + _Scheduler_EDF_SMP_Get_context( scheduler ); + + _Scheduler_SMP_Initialize( &self->Base ); + _RBTree_Initialize_empty( &self->Ready ); +} + +void _Scheduler_EDF_SMP_Node_initialize( + const Scheduler_Control *scheduler, + Scheduler_Node *node, + Thread_Control *the_thread, + Priority_Control priority +) +{ + Scheduler_SMP_Node *smp_node; + + smp_node = _Scheduler_SMP_Node_downcast( node ); + _Scheduler_SMP_Node_initialize( scheduler, smp_node, the_thread, priority ); +} + +static void _Scheduler_EDF_SMP_Do_update( + Scheduler_Context *context, + Scheduler_Node *node, + Priority_Control new_priority +) +{ + Scheduler_SMP_Node *smp_node; + + (void) context; + + smp_node = _Scheduler_SMP_Node_downcast( node ); + _Scheduler_SMP_Node_update_priority( smp_node, new_priority ); +} + +static bool _Scheduler_EDF_SMP_Has_ready( Scheduler_Context *context ) +{ + Scheduler_EDF_SMP_Context *self = + _Scheduler_EDF_SMP_Get_self( context ); + + return !_RBTree_Is_empty( &self->Ready ); +} + +static Scheduler_Node *_Scheduler_EDF_SMP_Get_highest_ready( + Scheduler_Context *context, + Scheduler_Node *node +) +{ + Scheduler_EDF_SMP_Context *self = + _Scheduler_EDF_SMP_Get_self( context ); + Scheduler_Node *first = (Scheduler_Node *) _RBTree_Minimum( &self->Ready ); + + (void) node; + + _Assert( &first->Node != NULL ); + + return first; +} + +static void _Scheduler_EDF_SMP_Move_from_scheduled_to_ready( + Scheduler_Context *context, + Scheduler_Node *scheduled_to_ready +) +{ + Scheduler_EDF_SMP_Context *self = + _Scheduler_EDF_SMP_Get_self( context ); + Scheduler_EDF_SMP_Node *node = + _Scheduler_EDF_SMP_Node_downcast( scheduled_to_ready ); + + _Chain_Extract_unprotected( &node->Base.Base.Node.Chain ); + _RBTree_Initialize_node( &node->Base.Base.Node.RBTree ); + _RBTree_Insert_inline( + &self->Ready, + &node->Base.Base.Node.RBTree, + &node->Base.priority, + _Scheduler_EDF_SMP_Less + ); +} + +static void _Scheduler_EDF_SMP_Move_from_ready_to_scheduled( + Scheduler_Context *context, + Scheduler_Node *ready_to_scheduled +) +{ + Scheduler_EDF_SMP_Context *self = + _Scheduler_EDF_SMP_Get_self( context ); + Scheduler_EDF_SMP_Node *node = + _Scheduler_EDF_SMP_Node_downcast( ready_to_scheduled ); + + _RBTree_Extract( &self->Ready, &node->Base.Base.Node.RBTree ); + _Chain_Initialize_node( &node->Base.Base.Node.Chain ); + _Chain_Insert_ordered_unprotected( + &self->Base.Scheduled, + &node->Base.Base.Node.Chain, + _Scheduler_SMP_Insert_priority_fifo_order + ); +} + +static void _Scheduler_EDF_SMP_Insert_ready_lifo( + Scheduler_Context *context, + Scheduler_Node *node_to_insert +) +{ + Scheduler_EDF_SMP_Context *self = + _Scheduler_EDF_SMP_Get_self( context ); + Scheduler_EDF_SMP_Node *node = + _Scheduler_EDF_SMP_Node_downcast( node_to_insert ); + + _RBTree_Initialize_node( &node->Base.Base.Node.RBTree ); + _RBTree_Insert_inline( + &self->Ready, + &node->Base.Base.Node.RBTree, + &node->Base.priority, + _Scheduler_EDF_SMP_Less_or_equal + ); +} + +static void _Scheduler_EDF_SMP_Insert_ready_fifo( + Scheduler_Context *context, + Scheduler_Node *node_to_insert +) +{ + Scheduler_EDF_SMP_Context *self = + _Scheduler_EDF_SMP_Get_self( context ); + Scheduler_EDF_SMP_Node *node = + _Scheduler_EDF_SMP_Node_downcast( node_to_insert ); + + _RBTree_Initialize_node( &node->Base.Base.Node.RBTree ); + _RBTree_Insert_inline( + &self->Ready, + &node->Base.Base.Node.RBTree, + &node->Base.priority, + _Scheduler_EDF_SMP_Less + ); +} + +static void _Scheduler_EDF_SMP_Extract_from_ready( + Scheduler_Context *context, + Scheduler_Node *node_to_extract +) +{ + Scheduler_EDF_SMP_Context *self = + _Scheduler_EDF_SMP_Get_self( context ); + Scheduler_EDF_SMP_Node *node = + _Scheduler_EDF_SMP_Node_downcast( node_to_extract ); + + _RBTree_Extract( &self->Ready, &node->Base.Base.Node.RBTree ); + _Chain_Initialize_node( &node->Base.Base.Node.Chain ); +} + +void _Scheduler_EDF_SMP_Block( + const Scheduler_Control *scheduler, + Thread_Control *thread, + Scheduler_Node *node +) +{ + Scheduler_Context *context = _Scheduler_Get_context( scheduler ); + + _Scheduler_SMP_Block( + context, + thread, + node, + _Scheduler_EDF_SMP_Extract_from_ready, + _Scheduler_EDF_SMP_Get_highest_ready, + _Scheduler_EDF_SMP_Move_from_ready_to_scheduled, + _Scheduler_SMP_Allocate_processor_lazy + ); +} + +static bool _Scheduler_EDF_SMP_Enqueue_ordered( + Scheduler_Context *context, + Scheduler_Node *node, + Chain_Node_order order, + Scheduler_SMP_Insert insert_ready, + Scheduler_SMP_Insert insert_scheduled +) +{ + return _Scheduler_SMP_Enqueue_ordered( + context, + node, + order, + insert_ready, + insert_scheduled, + _Scheduler_EDF_SMP_Move_from_scheduled_to_ready, + _Scheduler_SMP_Get_lowest_scheduled, + _Scheduler_SMP_Allocate_processor_lazy + ); +} + +static bool _Scheduler_EDF_SMP_Enqueue_lifo( + Scheduler_Context *context, + Scheduler_Node *node +) +{ + return _Scheduler_EDF_SMP_Enqueue_ordered( + context, + node, + _Scheduler_SMP_Insert_priority_lifo_order, + _Scheduler_EDF_SMP_Insert_ready_lifo, + _Scheduler_SMP_Insert_scheduled_lifo + ); +} + +static bool _Scheduler_EDF_SMP_Enqueue_fifo( + Scheduler_Context *context, + Scheduler_Node *node +) +{ + return _Scheduler_EDF_SMP_Enqueue_ordered( + context, + node, + _Scheduler_SMP_Insert_priority_fifo_order, + _Scheduler_EDF_SMP_Insert_ready_fifo, + _Scheduler_SMP_Insert_scheduled_fifo + ); +} + +static bool _Scheduler_EDF_SMP_Enqueue_scheduled_ordered( + Scheduler_Context *context, + Scheduler_Node *node, + Chain_Node_order order, + Scheduler_SMP_Insert insert_ready, + Scheduler_SMP_Insert insert_scheduled +) +{ + return _Scheduler_SMP_Enqueue_scheduled_ordered( + context, + node, + order, + _Scheduler_EDF_SMP_Extract_from_ready, + _Scheduler_EDF_SMP_Get_highest_ready, + insert_ready, + insert_scheduled, + _Scheduler_EDF_SMP_Move_from_ready_to_scheduled, + _Scheduler_SMP_Allocate_processor_lazy + ); +} + +static bool _Scheduler_EDF_SMP_Enqueue_scheduled_lifo( + Scheduler_Context *context, + Scheduler_Node *node +) +{ + return _Scheduler_EDF_SMP_Enqueue_scheduled_ordered( + context, + node, + _Scheduler_SMP_Insert_priority_lifo_order, + _Scheduler_EDF_SMP_Insert_ready_lifo, + _Scheduler_SMP_Insert_scheduled_lifo + ); +} + +static bool _Scheduler_EDF_SMP_Enqueue_scheduled_fifo( + Scheduler_Context *context, + Scheduler_Node *node +) +{ + return _Scheduler_EDF_SMP_Enqueue_scheduled_ordered( + context, + node, + _Scheduler_SMP_Insert_priority_fifo_order, + _Scheduler_EDF_SMP_Insert_ready_fifo, + _Scheduler_SMP_Insert_scheduled_fifo + ); +} + +void _Scheduler_EDF_SMP_Unblock( + const Scheduler_Control *scheduler, + Thread_Control *thread, + Scheduler_Node *node +) +{ + Scheduler_Context *context = _Scheduler_Get_context( scheduler ); + + _Scheduler_SMP_Unblock( + context, + thread, + node, + _Scheduler_EDF_SMP_Do_update, + _Scheduler_EDF_SMP_Enqueue_fifo + ); +} + +static bool _Scheduler_EDF_SMP_Do_ask_for_help( + Scheduler_Context *context, + Thread_Control *the_thread, + Scheduler_Node *node +) +{ + return _Scheduler_SMP_Ask_for_help( + context, + the_thread, + node, + _Scheduler_SMP_Insert_priority_lifo_order, + _Scheduler_EDF_SMP_Insert_ready_lifo, + _Scheduler_SMP_Insert_scheduled_lifo, + _Scheduler_EDF_SMP_Move_from_scheduled_to_ready, + _Scheduler_SMP_Get_lowest_scheduled, + _Scheduler_SMP_Allocate_processor_lazy + ); +} + +void _Scheduler_EDF_SMP_Update_priority( + const Scheduler_Control *scheduler, + Thread_Control *thread, + Scheduler_Node *node +) +{ + Scheduler_Context *context = _Scheduler_Get_context( scheduler ); + + _Scheduler_SMP_Update_priority( + context, + thread, + node, + _Scheduler_EDF_SMP_Extract_from_ready, + _Scheduler_EDF_SMP_Do_update, + _Scheduler_EDF_SMP_Enqueue_fifo, + _Scheduler_EDF_SMP_Enqueue_lifo, + _Scheduler_EDF_SMP_Enqueue_scheduled_fifo, + _Scheduler_EDF_SMP_Enqueue_scheduled_lifo, + _Scheduler_EDF_SMP_Do_ask_for_help + ); +} + +bool _Scheduler_EDF_SMP_Ask_for_help( + const Scheduler_Control *scheduler, + Thread_Control *the_thread, + Scheduler_Node *node +) +{ + Scheduler_Context *context = _Scheduler_Get_context( scheduler ); + + return _Scheduler_EDF_SMP_Do_ask_for_help( context, the_thread, node ); +} + +void _Scheduler_EDF_SMP_Reconsider_help_request( + const Scheduler_Control *scheduler, + Thread_Control *the_thread, + Scheduler_Node *node +) +{ + Scheduler_Context *context = _Scheduler_Get_context( scheduler ); + + _Scheduler_SMP_Reconsider_help_request( + context, + the_thread, + node, + _Scheduler_EDF_SMP_Extract_from_ready + ); +} + +void _Scheduler_EDF_SMP_Withdraw_node( + const Scheduler_Control *scheduler, + Thread_Control *the_thread, + Scheduler_Node *node, + Thread_Scheduler_state next_state +) +{ + Scheduler_Context *context = _Scheduler_Get_context( scheduler ); + + _Scheduler_SMP_Withdraw_node( + context, + the_thread, + node, + next_state, + _Scheduler_EDF_SMP_Extract_from_ready, + _Scheduler_EDF_SMP_Get_highest_ready, + _Scheduler_EDF_SMP_Move_from_ready_to_scheduled, + _Scheduler_SMP_Allocate_processor_lazy + ); +} + +void _Scheduler_EDF_SMP_Add_processor( + const Scheduler_Control *scheduler, + Thread_Control *idle +) +{ + Scheduler_Context *context = _Scheduler_Get_context( scheduler ); + + _Scheduler_SMP_Add_processor( + context, + idle, + _Scheduler_EDF_SMP_Has_ready, + _Scheduler_EDF_SMP_Enqueue_scheduled_fifo + ); +} + +Thread_Control *_Scheduler_EDF_SMP_Remove_processor( + const Scheduler_Control *scheduler, + Per_CPU_Control *cpu +) +{ + Scheduler_Context *context = _Scheduler_Get_context( scheduler ); + + return _Scheduler_SMP_Remove_processor( + context, + cpu, + _Scheduler_EDF_SMP_Extract_from_ready, + _Scheduler_EDF_SMP_Enqueue_fifo + ); +} + +void _Scheduler_EDF_SMP_Yield( + const Scheduler_Control *scheduler, + Thread_Control *thread, + Scheduler_Node *node +) +{ + Scheduler_Context *context = _Scheduler_Get_context( scheduler ); + + _Scheduler_SMP_Yield( + context, + thread, + node, + _Scheduler_EDF_SMP_Extract_from_ready, + _Scheduler_EDF_SMP_Enqueue_fifo, + _Scheduler_EDF_SMP_Enqueue_scheduled_fifo + ); +} diff --git a/testsuites/smptests/Makefile.am b/testsuites/smptests/Makefile.am index 3df76c1d67..6c1bd1294f 100644 --- a/testsuites/smptests/Makefile.am +++ b/testsuites/smptests/Makefile.am @@ -42,6 +42,7 @@ _SUBDIRS += smpscheduler03 _SUBDIRS += smpscheduler04 _SUBDIRS += smpscheduler05 _SUBDIRS += smpscheduler06 +_SUBDIRS += smpscheduler07 _SUBDIRS += smpsignal01 _SUBDIRS += smpstrongapa01 _SUBDIRS += smpswitchextension01 diff --git a/testsuites/smptests/configure.ac b/testsuites/smptests/configure.ac index 54a75f777d..59b27ef397 100644 --- a/testsuites/smptests/configure.ac +++ b/testsuites/smptests/configure.ac @@ -97,6 +97,7 @@ smpscheduler03/Makefile smpscheduler04/Makefile smpscheduler05/Makefile smpscheduler06/Makefile +smpscheduler07/Makefile smpsignal01/Makefile smpstrongapa01/Makefile smpswitchextension01/Makefile diff --git a/testsuites/smptests/smpscheduler03/test.c b/testsuites/smptests/smpscheduler03/test.c index 32bd67cdc2..3f6b9e3fd8 100644 --- a/testsuites/smptests/smpscheduler03/test.c +++ b/testsuites/smptests/smpscheduler03/test.c @@ -37,6 +37,11 @@ static void apply_priority( Thread_queue_Context *queue_context ) { + const Scheduler_Control *scheduler; + + scheduler = _Thread_Scheduler_get_home(thread); + new_priority = _Scheduler_Map_priority(scheduler, new_priority); + _Thread_queue_Context_initialize(queue_context); _Thread_queue_Context_clear_priority_updates(queue_context); _Thread_Wait_acquire(thread, queue_context); diff --git a/testsuites/smptests/smpscheduler07/Makefile.am b/testsuites/smptests/smpscheduler07/Makefile.am new file mode 100644 index 0000000000..f981544628 --- /dev/null +++ b/testsuites/smptests/smpscheduler07/Makefile.am @@ -0,0 +1,19 @@ +rtems_tests_PROGRAMS = smpscheduler07 +smpscheduler07_SOURCES = init.c ../smpscheduler03/test.c + +dist_rtems_tests_DATA = smpscheduler07.scn smpscheduler07.doc + +include $(RTEMS_ROOT)/make/custom/@RTEMS_BSP@.cfg +include $(top_srcdir)/../automake/compile.am +include $(top_srcdir)/../automake/leaf.am + +AM_CPPFLAGS += -I$(top_srcdir)/../support/include + +LINK_OBJS = $(smpscheduler07_OBJECTS) +LINK_LIBS = $(smpscheduler07_LDLIBS) + +smpscheduler07$(EXEEXT): $(smpscheduler07_OBJECTS) $(smpscheduler07_DEPENDENCIES) + @rm -f smpscheduler07$(EXEEXT) + $(make-exe) + +include $(top_srcdir)/../automake/local.am diff --git a/testsuites/smptests/smpscheduler07/init.c b/testsuites/smptests/smpscheduler07/init.c new file mode 100644 index 0000000000..cbffe89012 --- /dev/null +++ b/testsuites/smptests/smpscheduler07/init.c @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2017 embedded brains GmbH. All rights reserved. + * + * embedded brains GmbH + * Dornierstr. 4 + * 82178 Puchheim + * Germany + * + * + * 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. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include + +void Init(rtems_task_argument arg); + +const char rtems_test_name[] = "SMPSCHEDULER 7"; + +#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER +#define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER + +#define CONFIGURE_MAXIMUM_PROCESSORS 1 + +#define CONFIGURE_SCHEDULER_EDF_SMP + +#include + +RTEMS_SCHEDULER_CONTEXT_EDF_SMP(a); + +#define CONFIGURE_SCHEDULER_CONTROLS \ + RTEMS_SCHEDULER_CONTROL_EDF_SMP( a, rtems_build_name('T', 'E', 'S', 'T')) + +#define CONFIGURE_SMP_SCHEDULER_ASSIGNMENTS \ + RTEMS_SCHEDULER_ASSIGN(0, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_MANDATORY) + +#define CONFIGURE_MAXIMUM_TASKS 3 + +#define CONFIGURE_INITIAL_EXTENSIONS RTEMS_TEST_INITIAL_EXTENSION + +#define CONFIGURE_RTEMS_INIT_TASKS_TABLE + +#define CONFIGURE_INIT + +#include diff --git a/testsuites/smptests/smpscheduler07/smpscheduler07.doc b/testsuites/smptests/smpscheduler07/smpscheduler07.doc new file mode 100644 index 0000000000..80f7a2474d --- /dev/null +++ b/testsuites/smptests/smpscheduler07/smpscheduler07.doc @@ -0,0 +1,11 @@ +This file describes the directives and concepts tested by this test set. + +test set name: smpscheduler07 + +directives: + + - Scheduler operations. + +concepts: + + - Ensure that the scheduler operations basically work. diff --git a/testsuites/smptests/smpscheduler07/smpscheduler07.scn b/testsuites/smptests/smpscheduler07/smpscheduler07.scn new file mode 100644 index 0000000000..73db66938b --- /dev/null +++ b/testsuites/smptests/smpscheduler07/smpscheduler07.scn @@ -0,0 +1,2 @@ +*** BEGIN OF TEST SMPSCHEDULER 7 *** +*** END OF TEST SMPSCHEDULER 7 *** -- cgit v1.2.3