From: JoelPinto <jo...@isep.ipp.pt> --- cpukit/Makefile.am | 2 +- cpukit/include/rtems/cbs.h | 24 +-- cpukit/include/rtems/qreslib.h | 22 +- cpukit/include/rtems/score/schedulercbs.h | 242 +++++++--------------- cpukit/include/rtems/score/schedulercbsimpl.h | 218 +++++++++++++++++-- cpukit/include/rtems/score/statesimpl.h | 81 ++++++-- cpukit/score/src/schedulercbs.c | 29 +-- cpukit/score/src/schedulercbsattachthread.c | 16 +- cpukit/score/src/schedulercbsblock.c | 60 ++++++ cpukit/score/src/schedulercbscreateserver.c | 12 +- cpukit/score/src/schedulercbsdestroyserver.c | 17 +- cpukit/score/src/schedulercbsdetachthread.c | 56 +++-- cpukit/score/src/schedulercbsgetapprovedbudget.c | 7 +- cpukit/score/src/schedulercbsgetexecutiontime.c | 60 ------ cpukit/score/src/schedulercbsgetparameters.c | 7 +- cpukit/score/src/schedulercbsgetremainingbudget.c | 16 +- cpukit/score/src/schedulercbsgetserverid.c | 25 ++- cpukit/score/src/schedulercbsnodeinit.c | 2 +- cpukit/score/src/schedulercbsreleasejob.c | 30 ++- cpukit/score/src/schedulercbssetparameters.c | 5 +- cpukit/score/src/schedulercbsunblock.c | 42 +--- testsuites/sptests/Makefile.am | 23 +- testsuites/sptests/configure.ac | 2 + testsuites/sptests/spcbssched02/init.c | 70 ++----- testsuites/sptests/spcbssched02/task_periodic.c | 38 +--- testsuites/sptests/spcbssched03/system.h | 1 + testsuites/sptests/spcbssched03/tasks_periodic.c | 20 +- testsuites/sptests/spcbssched04/hard_tasks.c | 74 +++++++ testsuites/sptests/spcbssched04/init.c | 114 ++++++++++ testsuites/sptests/spcbssched04/soft_tasks.c | 85 ++++++++ testsuites/sptests/spcbssched04/spcbssched04.doc | 20 ++ testsuites/sptests/spcbssched04/spcbssched04.scn | 79 +++++++ testsuites/sptests/spcbssched04/system.h | 80 +++++++ testsuites/sptests/spcbssched05/init.c | 102 +++++++++ testsuites/sptests/spcbssched05/soft_tasks.c | 79 +++++++ testsuites/sptests/spcbssched05/spcbssched05.doc | 20 ++ testsuites/sptests/spcbssched05/spcbssched05.scn | 82 ++++++++ testsuites/sptests/spcbssched05/system.h | 75 +++++++ testsuites/sptests/spqreslib/init.c | 29 +-- testsuites/sptests/spqreslib/task_periodic.c | 28 +-- 40 files changed, 1397 insertions(+), 597 deletions(-) create mode 100644 cpukit/score/src/schedulercbsblock.c delete mode 100644 cpukit/score/src/schedulercbsgetexecutiontime.c create mode 100644 testsuites/sptests/spcbssched04/hard_tasks.c create mode 100644 testsuites/sptests/spcbssched04/init.c create mode 100644 testsuites/sptests/spcbssched04/soft_tasks.c create mode 100644 testsuites/sptests/spcbssched04/spcbssched04.doc create mode 100644 testsuites/sptests/spcbssched04/spcbssched04.scn create mode 100644 testsuites/sptests/spcbssched04/system.h create mode 100644 testsuites/sptests/spcbssched05/init.c create mode 100644 testsuites/sptests/spcbssched05/soft_tasks.c create mode 100644 testsuites/sptests/spcbssched05/spcbssched05.doc create mode 100644 testsuites/sptests/spcbssched05/spcbssched05.scn create mode 100644 testsuites/sptests/spcbssched05/system.h
diff --git a/cpukit/Makefile.am b/cpukit/Makefile.am index b431581..60142e8 100644 --- a/cpukit/Makefile.am +++ b/cpukit/Makefile.am @@ -907,13 +907,13 @@ librtemscpu_a_SOURCES += score/src/schedulercbscreateserver.c librtemscpu_a_SOURCES += score/src/schedulercbsdestroyserver.c librtemscpu_a_SOURCES += score/src/schedulercbsdetachthread.c librtemscpu_a_SOURCES += score/src/schedulercbsgetapprovedbudget.c -librtemscpu_a_SOURCES += score/src/schedulercbsgetexecutiontime.c librtemscpu_a_SOURCES += score/src/schedulercbsgetparameters.c librtemscpu_a_SOURCES += score/src/schedulercbsgetremainingbudget.c librtemscpu_a_SOURCES += score/src/schedulercbsgetserverid.c librtemscpu_a_SOURCES += score/src/schedulercbssetparameters.c librtemscpu_a_SOURCES += score/src/schedulercbsreleasejob.c librtemscpu_a_SOURCES += score/src/schedulercbsunblock.c +librtemscpu_a_SOURCES += score/src/schedulercbsblock.c librtemscpu_a_SOURCES += score/src/pheapallocate.c librtemscpu_a_SOURCES += score/src/pheapextend.c librtemscpu_a_SOURCES += score/src/pheapfree.c diff --git a/cpukit/include/rtems/cbs.h b/cpukit/include/rtems/cbs.h index a42061d..cd49cef 100644 --- a/cpukit/include/rtems/cbs.h +++ b/cpukit/include/rtems/cbs.h @@ -46,8 +46,7 @@ extern "C" { #define RTEMS_CBS_ERROR_EMPTY SCHEDULER_CBS_ERROR_EMPTY #define RTEMS_CBS_ERROR_NOSERVER SCHEDULER_CBS_ERROR_NOSERVER -/** Callback function invoked when a budget overrun of a task occurs. */ -typedef Scheduler_CBS_Budget_overrun rtems_cbs_budget_overrun; + /** Server id. */ typedef Scheduler_CBS_Server_id rtems_cbs_server_id; @@ -88,13 +87,11 @@ RTEMS_INLINE_ROUTINE int rtems_cbs_cleanup ( void ) */ RTEMS_INLINE_ROUTINE int rtems_cbs_create_server ( rtems_cbs_parameters *params, - rtems_cbs_budget_overrun budget_overrun_callback, rtems_cbs_server_id *server_id ) { return _Scheduler_CBS_Create_server( params, - budget_overrun_callback, server_id ); } @@ -122,11 +119,10 @@ RTEMS_INLINE_ROUTINE int rtems_cbs_attach_thread ( * @return status code. */ RTEMS_INLINE_ROUTINE int rtems_cbs_detach_thread ( - rtems_cbs_server_id server_id, rtems_id task_id ) { - return _Scheduler_CBS_Detach_thread( server_id, task_id ); + return _Scheduler_CBS_Detach_thread( task_id ); } /** @@ -190,22 +186,6 @@ RTEMS_INLINE_ROUTINE int rtems_cbs_set_parameters ( } /** - * @brief Get the CBS get execution time. - * - * Retrieve time info relative to the current server. - * - * @return status code. - */ -RTEMS_INLINE_ROUTINE int rtems_cbs_get_execution_time ( - rtems_cbs_server_id server_id, - time_t *exec_time, - time_t *abs_time -) -{ - return _Scheduler_CBS_Get_execution_time( server_id, exec_time, abs_time ); -} - -/** * @brief Get the remaining CBS budget. * * Retrieve remaining budget for the current server instance. diff --git a/cpukit/include/rtems/qreslib.h b/cpukit/include/rtems/qreslib.h index 88d9aba..18ca488 100644 --- a/cpukit/include/rtems/qreslib.h +++ b/cpukit/include/rtems/qreslib.h @@ -110,7 +110,6 @@ RTEMS_INLINE_ROUTINE qos_rv qres_create_server ( { return _Scheduler_CBS_Create_server( (Scheduler_CBS_Parameters *) params, - NULL, server_id ); } @@ -144,7 +143,7 @@ RTEMS_INLINE_ROUTINE qos_rv qres_detach_thread ( tid_t task_id ) { - return _Scheduler_CBS_Detach_thread( server_id, task_id ); + return _Scheduler_CBS_Detach_thread( task_id ); } /** @@ -196,7 +195,7 @@ RTEMS_INLINE_ROUTINE qos_rv qres_get_params ( ); } -/** +/** server_id, * @brief qres set params * * Change QoS scheduling parameters. @@ -214,21 +213,6 @@ RTEMS_INLINE_ROUTINE qos_rv qres_set_params ( ); } -/** - * @brief qres get execution time - * - * Retrieve time info relative to the current server. - * - * @return status code. - */ -RTEMS_INLINE_ROUTINE qos_rv qres_get_exec_time ( - qres_sid_t server_id, - qres_time_t *exec_time, - qres_atime_t *abs_time -) -{ - return _Scheduler_CBS_Get_execution_time( server_id, exec_time, abs_time ); -} /** * @brief qres get current budget @@ -241,7 +225,7 @@ RTEMS_INLINE_ROUTINE qos_rv qres_get_curr_budget ( qres_sid_t server_id, qres_time_t *current_budget ) -{ +{ return _Scheduler_CBS_Get_remaining_budget( server_id, current_budget ); } diff --git a/cpukit/include/rtems/score/schedulercbs.h b/cpukit/include/rtems/score/schedulercbs.h index ee4af2f..cc063c7 100644 --- a/cpukit/include/rtems/score/schedulercbs.h +++ b/cpukit/include/rtems/score/schedulercbs.h @@ -1,17 +1,18 @@ /** - * @file + * @file * - * @ingroup RTEMSScoreSchedulerCBS + * @brief Thread manipulation for the CBS scheduler * - * @brief Thread manipulation for the CBS scheduler - * - * This include file contains all the constants and structures associated - * with the manipulation of threads for the CBS scheduler. + * This include file contains all the constants and structures associated + * with the manipulation of threads for the CBS scheduler. */ /* + * * Copryight (c) 2011 Petr Benes. * Copyright (C) 2011 On-Line Applications Research Corporation (OAR). + * + * Copyright (C) 2019 Joel Pinto, Research Centre in Real-Time & Embedded Computing Systems (CISTER). * * The license and distribution terms for this file may be * found in the file LICENSE in this distribution or at @@ -25,7 +26,7 @@ #include <rtems/score/priority.h> #include <rtems/score/scheduler.h> #include <rtems/score/rbtree.h> -#include <rtems/score/scheduleredf.h> +#include <rtems/score/scheduleredfimpl.h> #include <rtems/rtems/signal.h> #include <rtems/rtems/timer.h> #include <rtems/score/thread.h> @@ -35,14 +36,11 @@ extern "C" { #endif /** - * @defgroup RTEMSScoreSchedulerCBS CBS Scheduler - * - * @ingroup RTEMSScoreScheduler + * @defgroup RTEMSScoreSchedulerCBS CBS Scheduler * - * @brief CBS Scheduler. - * - * @{ + * @ingroup RTEMSScoreScheduler */ +/**@{*/ #define SCHEDULER_CBS_MAXIMUM_PRIORITY SCHEDULER_EDF_MAXIMUM_PRIORITY @@ -57,7 +55,7 @@ extern "C" { _Scheduler_EDF_Initialize, /* initialize entry point */ \ _Scheduler_EDF_Schedule, /* schedule entry point */ \ _Scheduler_EDF_Yield, /* yield entry point */ \ - _Scheduler_EDF_Block, /* block entry point */ \ + _Scheduler_CBS_Block, /* block entry point */ \ _Scheduler_CBS_Unblock, /* unblock entry point */ \ _Scheduler_EDF_Update_priority, /* update priority entry point */ \ _Scheduler_EDF_Map_priority, /* map priority entry point */ \ @@ -94,10 +92,6 @@ extern const uint32_t _Scheduler_CBS_Maximum_servers; /** Server id. */ typedef uint32_t Scheduler_CBS_Server_id; -/** Callback function invoked when a budget overrun of a task occurs. */ -typedef void (*Scheduler_CBS_Budget_overrun)( - Scheduler_CBS_Server_id server_id -); /** * This structure handles server parameters. @@ -114,16 +108,20 @@ typedef struct { */ typedef struct { /** - * Task id. - * - * @note: The current implementation of CBS handles only one task per server. + * Current served task */ - rtems_id task_id; + rtems_id current_thread; /** Server paramenters. */ Scheduler_CBS_Parameters parameters; - /** Callback function invoked when a budget overrun occurs. */ - Scheduler_CBS_Budget_overrun cbs_budget_overrun; - + /* Absolute deadline of the server. */ + Priority_Node priority; + /** Remaining reserved capacity. */ + int32_t remaining_budget; + /** + * Server's RB-Tree + * Job's are enqueued and ordered by their deadline ( deadline given by the RM Manager). + */ + RBTree_Control tree; /** * @brief Indicates if this CBS server is initialized. * @@ -139,9 +137,14 @@ typedef struct { /** EDF scheduler specific data of a task. */ Scheduler_EDF_Node Base; /** CBS server specific data of a task. */ - Scheduler_CBS_Server *cbs_server; + Scheduler_CBS_Server *server; Priority_Node *deadline_node; + + RBTree_Node thread_cbs_node; + /** thread deadline given by RM Manager. */ + uint64_t rms_dead; + } Scheduler_CBS_Node; @@ -151,28 +154,18 @@ typedef struct { */ extern Scheduler_CBS_Server _Scheduler_CBS_Server_list[]; -/** - * @brief Unblocks a thread. - * - * @param scheduler The scheduler control. - * @param the_thread The thread to unblock. - * @param node The scheduler node. - */ void _Scheduler_CBS_Unblock( const Scheduler_Control *scheduler, Thread_Control *the_thread, Scheduler_Node *node ); -/** - * @brief Releases a job. - * - * @param scheduler The scheduler for the operation. - * @param the_thread The corresponding thread. - * @param priority_node The priority node for the operation. - * @param deadline The deadline for the job. - * @param queue_context The thread queue context. - */ +void _Scheduler_CBS_Block( + const Scheduler_Control *scheduler, + Thread_Control *the_thread, + Scheduler_Node *the_node +); + void _Scheduler_CBS_Release_job( const Scheduler_Control *scheduler, Thread_Control *the_thread, @@ -181,14 +174,6 @@ void _Scheduler_CBS_Release_job( Thread_queue_Context *queue_context ); -/** - * @brief Cancels a job. - * - * @param scheduler The scheduler for the operation. - * @param the_thread The corresponding thread. - * @param priority_node The priority node for the operation. - * @param queue_context The thread queue context. - */ void _Scheduler_CBS_Cancel_job( const Scheduler_Control *scheduler, Thread_Control *the_thread, @@ -197,27 +182,20 @@ void _Scheduler_CBS_Cancel_job( ); /** - * @brief _Scheduler_CBS_Initialize + * @brief _Scheduler_CBS_Initialize * - * Initializes the CBS library. + * Initializes the CBS library. * - * @return SCHEDULER_CBS_OK This method always returns this status. + * @retval status code. */ int _Scheduler_CBS_Initialize(void); /** - * @brief Attaches a task to an already existing server. - * - * Attach a task to an already existing server. + * @brief Attach a task to an already existing server. * - * @param server_id The id of the existing server. - * @param task_id The id of the task to attach. + * Attach a task to an already existing server. * - * @retval SCHEDULER_CBS_OK The operation was successful. - * @retval SCHEDULER_CBS_ERROR_INVALID_PARAMETER The server id is so big - * or there is no thread for this task id. - * @retval SCHEDULER_CBS_ERROR_NOSERVER The server is not yet initialized. - * @retval SCHEDULER_CBS_ERROR_FULL The server already has a task. + * @retval status code. */ int _Scheduler_CBS_Attach_thread ( Scheduler_CBS_Server_id server_id, @@ -225,81 +203,57 @@ int _Scheduler_CBS_Attach_thread ( ); /** - * @brief Detaches from the CBS Server. + * @brief Detach from the CBS Server. * - * Detach from the CBS Server. + * Detach from the CBS Server. * - * @param server_id The id of the existing server. - * @param task_id The id of the task to attach. - * - * @retval SCHEDULER_CBS_OK The operation was successful. - * @retval SCHEDULER_CBS_ERROR_INVALID_PARAMETER The server id is to big, - * or the task with this id is not attached to this server or there is - * no thread with this task. - * @retval SCHEDULER_CBS_ERROR_NOSERVER The server is not yet initialized. + * @retval status code. */ int _Scheduler_CBS_Detach_thread ( - Scheduler_CBS_Server_id server_id, rtems_id task_id ); /** - * @brief Cleans up resources associated to the CBS Library. + * @brief Cleanup resources associated to the CBS Library. * - * Cleanup resources associated to the CBS Library. + * Cleanup resources associated to the CBS Library. * - * @return This method always returns SCHEDULER_CBS_OK. + * @retval status code. */ int _Scheduler_CBS_Cleanup (void); /** - * @brief Creates a new server with specified parameters. + * @brief Create a new server with specified parameters. * - * Create a new server with specified parameters. + * Create a new server with specified parameters. * - * @param params The parameters for the server. - * @param budget_overrun_callback The budget overrun for the new server. - * @param[out] server_id In the case of success, this parameter contains the - * id of the newly created server. - * - * @retval SCHEDULER_CBS_OK The operation succeeded. - * @retval SCHEDULER_CBS_ERROR_INVALID_PARAMETER The given parameters are invalid. - * @retval SCHEDULER_CBS_ERROR_FULL The maximum number of servers was already - * created, a new server cannot be created. + * @retval status code. */ int _Scheduler_CBS_Create_server ( Scheduler_CBS_Parameters *params, - Scheduler_CBS_Budget_overrun budget_overrun_callback, rtems_id *server_id ); /** - * @brief Detaches all tasks from a server and destroys it. + * @brief Detach all tasks from a server and destroy it. * - * Detach all tasks from a server and destroy it. + * Detach all tasks from a server and destroy it. * - * @param server_id The id of the server to destroy. + * @param[in] server_id is the ID of the server * - * @retval SCHEDULER_CBS_OK The operation was successful. - * @retval SCHEDULER_CBS_ERROR_INVALID_PARAMETER The server id is too big. - * @retval SCHEDULER_CBS_ERROR_NOSERVER There is no initialized server with this id. + * @retval status code. */ int _Scheduler_CBS_Destroy_server ( Scheduler_CBS_Server_id server_id ); /** - * @brief Retrieves the approved budget. - * - * Retrieve the budget that has been approved for the subsequent - * server instances. + * @brief Retrieve the approved budget. * - * @param server_id The id of the server instance of which the budget is wanted. - * @param[out] approved_budget Contains the approved budget after a successful method call. + * Retrieve the budget that has been approved for the subsequent + * server instances. * - * @retval SCHEDULER_CBS_OK The operation was successful. - * @retval SCHEDULER_CBS_ERROR_INVALID_PARAMETER The server id is too big. - * @retval SCHEDULER_CBS_ERROR_NOSERVER There is no initialized server with this id. + * @retval status code. */ int _Scheduler_CBS_Get_approved_budget ( Scheduler_CBS_Server_id server_id, @@ -307,52 +261,25 @@ int _Scheduler_CBS_Get_approved_budget ( ); /** - * @brief Retrieves remaining budget for the current server instance. - * - * Retrieve remaining budget for the current server instance. + * @brief Retrieve remaining budget for the current server instance. * - * @param server_id The id of the server instance of which the remaining budget is wanted. - * @param[out] remaining_budget Contains the remaining budget after a successful method call. + * Retrieve remaining budget for the current server instance. * - * @retval SCHEDULER_CBS_OK The operation was successful. - * @retval SCHEDULER_CBS_ERROR_INVALID_PARAMETER The server id is too big. - * @retval SCHEDULER_CBS_ERROR_NOSERVER There is no initialized server with this id. + * @retval status code. */ int _Scheduler_CBS_Get_remaining_budget ( Scheduler_CBS_Server_id server_id, time_t *remaining_budget ); -/** - * @brief Gets relative time info. - * - * Retrieve time info relative to @a server_id. The server status code is returned. - * - * @param server_id is the server to get the status code from. - * @param[out] exec_time Contains the execution time after a successful method call. - * @param abs_time Not apparently used. - * - * @retval SCHEDULER_CBS_OK The operation was successful. - * @retval SCHEDULER_CBS_ERROR_INVALID_PARAMETER The server id is too big. - * @retval SCHEDULER_CBS_ERROR_NOSERVER There is no initialized server with this id. - */ -int _Scheduler_CBS_Get_execution_time ( - Scheduler_CBS_Server_id server_id, - time_t *exec_time, - time_t *abs_time -); + /** - * @brief Retrieves CBS scheduling parameters. - * - * Retrieve CBS scheduling parameters. + * @brief Retrieve CBS scheduling parameters. * - * @param server_id The id of the server to get the scheduling parameters from. - * @param[out] params Will contain the scheduling parameters after successful method call. + * Retrieve CBS scheduling parameters. * - * @retval SCHEDULER_CBS_OK The operation was successful. - * @retval SCHEDULER_CBS_ERROR_INVALID_PARAMETER The server id is too big. - * @retval SCHEDULER_CBS_ERROR_NOSERVER There is no initialized server with this id. + * @retval status code. */ int _Scheduler_CBS_Get_parameters ( Scheduler_CBS_Server_id server_id, @@ -360,15 +287,12 @@ int _Scheduler_CBS_Get_parameters ( ); /** - * @brief Gets a thread server id. + * @brief Get a thread server id. * - * Get a thread server id, or SCHEDULER_CBS_ERROR_NOT_FOUND if it is not - * attached to any server. + * Get a thread server id, or SCHEDULER_CBS_ERROR_NOT_FOUND if it is not + * attached to any server. * - * @param task_id The id of the task to get the corresponding server. - * @param[out] server_id Will contain the server id after successful method call. - * @retval SCHEDULER_CBS_OK The operation was successful - * @retval SCHEDULER_CBS_ERROR_NOSERVER There is no server with this task attached. + * @retval status code. */ int _Scheduler_CBS_Get_server_id ( rtems_id task_id, @@ -376,17 +300,14 @@ int _Scheduler_CBS_Get_server_id ( ); /** - * @brief Sets parameters for CBS scheduling. + * @brief Set parameters for CBS scheduling. * - * Change CBS scheduling parameters. + * Change CBS scheduling parameters. * - * @param server_id The id of the server. - * @param parameters The parameters to set. + * @param[in] server_id is the ID of the server. + * @param[in] parameters are the parameters to set. * - * @retval SCHEDULER_CBS_OK The operation was successful. - * @retval SCHEDULER_CBS_ERROR_INVALID_PARAMETER The server id is too big or the - * given parameters are invalid. - * @retval SCHEDULER_CBS_ERROR_NOSERVER There is no server with this id. + * @retval status code. */ int _Scheduler_CBS_Set_parameters ( Scheduler_CBS_Server_id server_id, @@ -394,23 +315,16 @@ int _Scheduler_CBS_Set_parameters ( ); /** - * @brief Invoked when a limited time quantum is exceeded. + * @brief Invoked when a limited time quantum is exceeded. * - * This routine is invoked when a limited time quantum is exceeded. - * - * @param the_thread The thread that exceeded a limited time quantum. + * This routine is invoked when a limited time quantum is exceeded. */ void _Scheduler_CBS_Budget_callout( Thread_Control *the_thread ); /** - * @brief Initializes a CBS specific scheduler node of @a the_thread. - * - * @param scheduler The scheduler control for the operation. - * @param[out] node The scheduler node to initalize. - * @param the_thread The thread to initialize a scheduler node for. - * @param priority The priority for the node. + * @brief Initializes a CBS specific scheduler node of @a the_thread. */ void _Scheduler_CBS_Node_initialize( const Scheduler_Control *scheduler, @@ -423,7 +337,7 @@ void _Scheduler_CBS_Node_initialize( } #endif -/** @} */ +/**@}*/ #endif /* end of include file */ diff --git a/cpukit/include/rtems/score/schedulercbsimpl.h b/cpukit/include/rtems/score/schedulercbsimpl.h index 7985adb..a3708fc 100644 --- a/cpukit/include/rtems/score/schedulercbsimpl.h +++ b/cpukit/include/rtems/score/schedulercbsimpl.h @@ -14,6 +14,8 @@ * 82178 Puchheim * Germany * <rt...@embedded-brains.de> + * + * Copyright (C) 2019 Joel Pinto, Research Centre in Real-Time & Embedded Computing Systems (CISTER). * * The license and distribution terms for this file may be * found in the file LICENSE in this distribution or at @@ -24,8 +26,7 @@ #define _RTEMS_SCORE_SCHEDULERCBSIMPL_H #include <rtems/score/schedulercbs.h> -#include <rtems/score/schedulerimpl.h> - +#include <inttypes.h> #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ @@ -36,13 +37,6 @@ extern "C" { * @{ */ -/** - * @brief Gets the CBS node of the thread. - * - * @param the_thread The thread to get the CBS node of. - * - * @return Pointer to the scheduler node of @a the_thread. - */ RTEMS_INLINE_ROUTINE Scheduler_CBS_Node *_Scheduler_CBS_Thread_get_node( Thread_Control *the_thread ) @@ -50,13 +44,6 @@ RTEMS_INLINE_ROUTINE Scheduler_CBS_Node *_Scheduler_CBS_Thread_get_node( return (Scheduler_CBS_Node *) _Thread_Scheduler_get_home_node( the_thread ); } -/** - * @brief Casts the scheduler node to a scheduler CBS node. - * - * @param node The node to be casted to a scheduler CBS node. - * - * @return CBS Node pointer to @a node. - */ RTEMS_INLINE_ROUTINE Scheduler_CBS_Node *_Scheduler_CBS_Node_downcast( Scheduler_Node *node ) @@ -64,6 +51,205 @@ RTEMS_INLINE_ROUTINE Scheduler_CBS_Node *_Scheduler_CBS_Node_downcast( return (Scheduler_CBS_Node *) node; } + +RTEMS_INLINE_ROUTINE Thread_Control *_Scheduler_CBS_Node_get_owner +( + Scheduler_CBS_Node *node +) +{ + return _Scheduler_Node_get_owner(&node->Base.Base); +} + + +RTEMS_INLINE_ROUTINE Scheduler_CBS_Node *_Scheduler_CBS_Node_Retrieve( + const RBTree_Node *cbs_tree_node +) +{ + return RTEMS_CONTAINER_OF( cbs_tree_node, Scheduler_CBS_Node, thread_cbs_node ); +} + +RTEMS_INLINE_ROUTINE bool _Scheduler_CBS_less( + const void *left, + const RBTree_Node *right +) +{ + const Scheduler_CBS_Node *node; + const Priority_Control *the_left; + + the_left = left; + node = _Scheduler_CBS_Node_Retrieve( right ); + + return *the_left<=node->rms_dead; +} + +RTEMS_INLINE_ROUTINE void _Scheduler_CBS_Dequeue_Thread_Node( + RBTree_Control *tree, + RBTree_Node *node +) +{ + _RBTree_Extract( tree, node ); +} + +RTEMS_INLINE_ROUTINE void _Scheduler_CBS_Enqueue_Thread_Node( + RBTree_Control *tree, + RBTree_Node *node, + const uint64_t priority +) +{ + _RBTree_Insert_inline( tree, node, &priority, _Scheduler_CBS_less ); +} + +RTEMS_INLINE_ROUTINE bool _Scheduler_CBS_Node_equal( + Scheduler_CBS_Node *the_node, + RBTree_Node *node +) +{ + Scheduler_CBS_Node *cbs_node; + Thread_Control *the_thread, *cpm_thread; + + cbs_node = _Scheduler_CBS_Node_Retrieve( node ); + + the_thread = _Scheduler_CBS_Node_get_owner( the_node ); + cpm_thread = _Scheduler_CBS_Node_get_owner( cbs_node ); + + return _Objects_Are_ids_equal( the_thread->Object.id, cpm_thread->Object.id ); +} + + +RTEMS_INLINE_ROUTINE void _Scheduler_CBS_RBNode_search( + RBTree_Control *the_tree, + Scheduler_CBS_Node *the_node, + void ( *found )( RBTree_Control *, RBTree_Node *) +) +{ + RBTree_Node * const *node; + const RBTree_Control *tree; + uint64_t key; + + tree = the_tree; + key = the_node->rms_dead; + node = _RBTree_Root_const_reference( tree ); + while( *node != NULL ) + { + if( _Scheduler_CBS_Node_equal( the_node, *node ) ) { + ( *found )( the_tree, &the_node->thread_cbs_node ); + break; + } else if( _Scheduler_CBS_less( &key, *node ) ) { + node = _RBTree_Left_reference( *node ); + } else { + node = _RBTree_Right_reference( *node ); + } + } +} + + +RTEMS_INLINE_ROUTINE void _Scheduler_CBS_Update_Deadline( + Priority_Control *old_deadline, + const uint32_t period +) +{ + Priority_Control priority; + Per_CPU_Control *cpu_self; + + cpu_self = _Per_CPU_Get(); + + priority = *old_deadline + period; + (priority > cpu_self->Watchdog.ticks)? (*old_deadline = priority) : (*old_deadline = cpu_self->Watchdog.ticks + period); +} + +RTEMS_INLINE_ROUTINE void _Scheduler_CBS_Tranquilize_wait( + Thread_Control *the_thread +) +{ + the_thread->current_state = _States_Clear( STATES_WAITING_FOR_SERVER, the_thread->current_state ); +} + +RTEMS_INLINE_ROUTINE void _Scheduler_CBS_Schedule_Server( + const Scheduler_Control *scheduler, + Thread_Control *the_thread, + Scheduler_CBS_Node *cbs_node, + bool release +) +{ + Scheduler_Node *node; + Thread_queue_Context context; + + if( _States_Is_Waiting_For_Server( the_thread->current_state ) ) + _Scheduler_CBS_Tranquilize_wait( the_thread ); + + cbs_node->server->current_thread = the_thread->Object.id; + node = _Thread_Scheduler_get_home_node( the_thread ); + + int32_t cond1 = cbs_node->server->remaining_budget * cbs_node->server->parameters.deadline; + int32_t cond2 = (cbs_node->server->priority.priority - _Watchdog_Ticks_since_boot)*cbs_node->server->parameters.budget; + + if( cond1 > cond2 || cbs_node->server->remaining_budget <= 0 ) { + _Scheduler_CBS_Update_Deadline( &cbs_node->server->priority.priority, cbs_node->server->parameters.deadline ); + cbs_node->server->remaining_budget = cbs_node->server->parameters.budget; + } + + the_thread->cpu_time_budget = cbs_node->server->remaining_budget; + + _Priority_Node_set_priority( cbs_node->deadline_node, SCHEDULER_PRIORITY_MAP( cbs_node->server->priority.priority ) ); + _Thread_queue_Context_clear_priority_updates( &context ); + + if( _Priority_Node_is_active( cbs_node->deadline_node ) ) { + _Thread_Priority_changed( + the_thread, + cbs_node->deadline_node, + false, + &context + ); + } else { + _Thread_Priority_add( the_thread, cbs_node->deadline_node, &context ); + } + + if( release ) { + _Scheduler_EDF_Update_priority( scheduler, the_thread, node ); + } else { + _Scheduler_EDF_Unblock(scheduler, the_thread, node); + } + +} + +RTEMS_INLINE_ROUTINE void _Scheduler_CBS_Update_Heir ( + const Scheduler_Control *scheduler, + Thread_Control *the_thread +) +{ + _Thread_Set_state( the_thread, STATES_WAITING_FOR_SERVER ); +} + + +RTEMS_INLINE_ROUTINE void _Scheduler_CBS_Schedule( + const Scheduler_Control *scheduler, + Scheduler_CBS_Server *server, + bool release +) +{ + Scheduler_CBS_Node *minimum_node_cbs; + RBTree_Node *minimum_node; + Thread_Control *heir_thread, *the_thread; + ISR_lock_Context lock_context; + + minimum_node = _RBTree_Minimum( &server->tree ); + + if( minimum_node == NULL ) + return; + + minimum_node_cbs = _Scheduler_CBS_Node_Retrieve( minimum_node ); + heir_thread = _Scheduler_CBS_Node_get_owner( minimum_node_cbs ); + + if( server->current_thread != heir_thread->Object.id ) { + if( server->current_thread != -1 ) { + the_thread = _Thread_Get( server->current_thread, &lock_context ); + _ISR_lock_ISR_enable( &lock_context ); + _Scheduler_CBS_Update_Heir( scheduler, the_thread ); + } else { + _Scheduler_CBS_Schedule_Server( scheduler, heir_thread, minimum_node_cbs, release ); + } + } +} /** @} */ #ifdef __cplusplus diff --git a/cpukit/include/rtems/score/statesimpl.h b/cpukit/include/rtems/score/statesimpl.h index 49d4395..97772e8 100644 --- a/cpukit/include/rtems/score/statesimpl.h +++ b/cpukit/include/rtems/score/statesimpl.h @@ -101,6 +101,9 @@ extern "C" { /** This macro corresponds to a task those life is changing. */ #define STATES_LIFE_IS_CHANGING 0x00020000 +/** This macro corresponds to a thread that sufferred from a preemption in server context */ +#define STATES_WAITING_FOR_SERVER 0x00040000 + /** This macro corresponds to a task being held by the debugger. */ #define STATES_DEBUGGER 0x08000000 @@ -236,15 +239,28 @@ RTEMS_INLINE_ROUTINE bool _States_Is_suspended ( } /** - * @brief Checks if WAITING_FOR_TIME state is set. - * + * This function returns true if the ZOMBIE state is set in + * the_state, and false otherwise. + * + * @param[in] the_states is the task state set to test + * + * @return This method returns true if the desired state condition is set + */ +RTEMS_INLINE_ROUTINE bool _States_Is_zombie ( + States_Control the_states +) +{ + return (the_states & STATES_ZOMBIE); +} + + +/** * This function returns true if the WAITING_FOR_TIME state is set in - * @a the_states, and false otherwise. + * the_states, and false otherwise. * - * @param the_states The task state set to test. + * @param[in] the_states is the task state set to test * - * @retval true WAITING_FOR_TIME state is set in @a the_states. - * @retval false WAITING_FOR_TIME state is not set in @a the_states. + * @return This method returns true if the desired state condition is set. */ RTEMS_INLINE_ROUTINE bool _States_Is_waiting_for_rpc_reply ( States_Control the_states @@ -272,43 +288,64 @@ RTEMS_INLINE_ROUTINE bool _States_Is_waiting_for_join_at_exit( } /** - * @brief Checks if the state is set to be interruptible. - * * This function returns true if the task's state is set in * way that allows it to be interrupted by a signal. * - * @param the_states The task state set to test. + * @param[in] the_states is the task state set to test * - * @retval true @a the_states is interruptible. - * @retval false @a the_states is not interruptible. + * @return This method returns true if the desired state condition is set. */ RTEMS_INLINE_ROUTINE bool _States_Is_interruptible_by_signal ( States_Control the_states ) { - return (the_states & STATES_INTERRUPTIBLE_BY_SIGNAL); - + return (the_states & STATES_INTERRUPTIBLE_BY_SIGNAL); } - /** - * @brief Checks if the state is blocked waiting on a local resource. - * * This function returns true if one of the states which indicates * that a task is blocked waiting for a local resource is set in * the_states, and false otherwise. * - * @param the_states The task state set to test. + * @param[in] the_states is the task state set to test * - * @retval true The state indicates that the task is blocked waiting on a local - * resource. - * @retval false The state indicates that the task is not blocked waiting on a - * local resource. + * @return This method returns true if the desired state condition is set. */ + RTEMS_INLINE_ROUTINE bool _States_Is_locally_blocked ( States_Control the_states ) { - return (the_states & STATES_LOCALLY_BLOCKED); + return (the_states & STATES_LOCALLY_BLOCKED); +} + +/** + * This function returns true if STATES_WAITING_FOR_PERIOD is set in the thread + * current states, and false otherwise. + * + * @param[in] the_states is the tasj state set to test + * + * @return This method returns true if the desired state condition is set. + */ +RTEMS_INLINE_ROUTINE bool _States_Is_Waiting_For_period ( + States_Control the_states +) +{ + return (the_states & STATES_WAITING_FOR_PERIOD); +} + +/** + * This function returns true if STATES_WAITING_FOR_SERVER is set in the thread + * current states, and false otherwise. + * + * @param[in] the_states is the tasj state set to test + * + * @return This method returns true if the desired state condition is set. + */ +RTEMS_INLINE_ROUTINE bool _States_Is_Waiting_For_Server ( + States_Control the_states +) +{ + return ( the_states & STATES_WAITING_FOR_SERVER ); } /** @} */ diff --git a/cpukit/score/src/schedulercbs.c b/cpukit/score/src/schedulercbs.c index d4001d8..3878352 100644 --- a/cpukit/score/src/schedulercbs.c +++ b/cpukit/score/src/schedulercbs.c @@ -8,6 +8,8 @@ /* * Copyright (C) 2011 Petr Benes. * Copyright (C) 2011 On-Line Applications Research Corporation (OAR). + * + * Copyright (C) 2019 Joel Pinto, Research Centre in Real-Time & Embedded Computing Systems (CISTER). * * The license and distribution terms for this file may be * found in the file LICENSE in this distribution or at @@ -24,30 +26,11 @@ void _Scheduler_CBS_Budget_callout( Thread_Control *the_thread ) { - Scheduler_CBS_Node *node; - Scheduler_CBS_Server_id server_id; - Thread_queue_Context queue_context; + Scheduler_CBS_Node *the_node; + + the_node = _Scheduler_CBS_Thread_get_node( the_thread ); - node = _Scheduler_CBS_Thread_get_node( the_thread ); - - /* Put violating task to background until the end of period. */ - _Thread_queue_Context_clear_priority_updates( &queue_context ); - _Scheduler_CBS_Cancel_job( - NULL, - the_thread, - node->deadline_node, - &queue_context - ); - _Thread_Priority_update( &queue_context ); - - /* Invoke callback function if any. */ - if ( node->cbs_server->cbs_budget_overrun ) { - _Scheduler_CBS_Get_server_id( - node->cbs_server->task_id, - &server_id - ); - node->cbs_server->cbs_budget_overrun( server_id ); - } + _Thread_Set_state( the_thread, STATES_WAITING_FOR_SERVER ); } int _Scheduler_CBS_Initialize(void) diff --git a/cpukit/score/src/schedulercbsattachthread.c b/cpukit/score/src/schedulercbsattachthread.c index 4193882..dbe0923 100644 --- a/cpukit/score/src/schedulercbsattachthread.c +++ b/cpukit/score/src/schedulercbsattachthread.c @@ -6,8 +6,11 @@ */ /* + * * Copyright (C) 2011 Petr Benes. * Copyright (C) 2011 On-Line Applications Research Corporation (OAR). + * + * Copyright (C) 2019 Joel Pinto, , Research Centre in Real-Time & Embedded Computing Systems (CISTER). * * The license and distribution terms for this file may be * found in the file LICENSE in this distribution or at @@ -19,7 +22,6 @@ #endif #include <rtems/score/schedulercbsimpl.h> -#include <rtems/score/threadimpl.h> int _Scheduler_CBS_Attach_thread ( Scheduler_CBS_Server_id server_id, @@ -41,10 +43,6 @@ int _Scheduler_CBS_Attach_thread ( return SCHEDULER_CBS_ERROR_NOSERVER; } - if ( server->task_id != -1 ) { - return SCHEDULER_CBS_ERROR_FULL; - } - the_thread = _Thread_Get( task_id, &lock_context ); if ( the_thread == NULL ) { @@ -53,15 +51,13 @@ int _Scheduler_CBS_Attach_thread ( node = _Scheduler_CBS_Thread_get_node( the_thread ); - if ( node->cbs_server != NULL ) { + if ( node->server != NULL ) { _ISR_lock_ISR_enable( &lock_context ); return SCHEDULER_CBS_ERROR_FULL; } - node->cbs_server = server; - - server->task_id = task_id; - + node->server = server; + the_thread->budget_callout = _Scheduler_CBS_Budget_callout; the_thread->budget_algorithm = THREAD_CPU_BUDGET_ALGORITHM_CALLOUT; the_thread->is_preemptible = true; diff --git a/cpukit/score/src/schedulercbsblock.c b/cpukit/score/src/schedulercbsblock.c new file mode 100644 index 0000000..f50e426 --- /dev/null +++ b/cpukit/score/src/schedulercbsblock.c @@ -0,0 +1,60 @@ +/** + * + * @file + * + * @ Removes the Thread from the Ready Queue + * + * @ingroup ScoreScheduler + */ + + /* + * Copyright (C) 2019 Joel Pinto, Research Centre in Real-Time & Embedded Computing Systems (CISTER). + * + * 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/schedulercbsimpl.h> + +void _Scheduler_CBS_Block ( + const Scheduler_Control *scheduler, + Thread_Control *the_thread, + Scheduler_Node *node +) +{ + Scheduler_CBS_Node *the_node; + Scheduler_CBS_Server *server; + + the_node = _Scheduler_CBS_Node_downcast( node ); + server = NULL; + + if( the_node->server != NULL ) { + + + if( _Objects_Are_ids_equal( the_node->server->current_thread, the_thread->Object.id ) ) { + the_node->server->remaining_budget = the_thread->cpu_time_budget; + the_node->server->current_thread = -1; + server = the_node->server; + } + + if( !_States_Is_Waiting_For_Server( the_thread->current_state ) ) { + _Scheduler_CBS_RBNode_search( &the_node->server->tree, the_node, _Scheduler_CBS_Dequeue_Thread_Node ); + if( _States_Is_zombie( the_thread->current_state ) ) + the_node->server = NULL; + } + } + _Scheduler_EDF_Block( + scheduler, + the_thread, + node + ); + + if( server != NULL && ( _States_Is_zombie( the_thread->current_state ) || _States_Is_Waiting_For_period( the_thread->current_state ) || _States_Is_Waiting_For_Server( the_thread->current_state ) ) ) + _Scheduler_CBS_Schedule( scheduler, server, false ); + +} \ No newline at end of file diff --git a/cpukit/score/src/schedulercbscreateserver.c b/cpukit/score/src/schedulercbscreateserver.c index 15262cf..07457df 100644 --- a/cpukit/score/src/schedulercbscreateserver.c +++ b/cpukit/score/src/schedulercbscreateserver.c @@ -8,22 +8,23 @@ /* * Copyright (C) 2011 Petr Benes. * Copyright (C) 2011 On-Line Applications Research Corporation (OAR). + * + * Copyright (C) 2019 Joel Pinto, Research Centre in Real-Time & Embedded Computing Systems (CISTER). * * 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/schedulercbs.h> -#include <rtems/score/scheduleredfimpl.h> int _Scheduler_CBS_Create_server ( Scheduler_CBS_Parameters *params, - Scheduler_CBS_Budget_overrun budget_overrun_callback, rtems_id *server_id ) { @@ -47,8 +48,11 @@ int _Scheduler_CBS_Create_server ( *server_id = i; the_server = &_Scheduler_CBS_Server_list[*server_id]; the_server->parameters = *params; - the_server->task_id = -1; - the_server->cbs_budget_overrun = budget_overrun_callback; + the_server->current_thread = -1; + the_server->remaining_budget = the_server->parameters.budget; the_server->initialized = true; + + _RBTree_Initialize_empty( &the_server->tree ); + return SCHEDULER_CBS_OK; } diff --git a/cpukit/score/src/schedulercbsdestroyserver.c b/cpukit/score/src/schedulercbsdestroyserver.c index 5121e3a..240645e 100644 --- a/cpukit/score/src/schedulercbsdestroyserver.c +++ b/cpukit/score/src/schedulercbsdestroyserver.c @@ -9,6 +9,8 @@ /* * Copyright (C) 2011 Petr Benes. * Copyright (C) 2011 On-Line Applications Research Corporation (OAR). + * + * Copyright (C) 2019 Joel Pinto, Research Centre in Real-Time & Embedded Computing Systems (CISTER). * * The license and distribution terms for this file may be * found in the file LICENSE in this distribution or at @@ -19,25 +21,24 @@ #include "config.h" #endif -#include <rtems/score/schedulercbs.h> +#include <rtems/score/schedulercbsimpl.h> #include <rtems/score/wkspace.h> + int _Scheduler_CBS_Destroy_server ( Scheduler_CBS_Server_id server_id ) { - int ret = SCHEDULER_CBS_OK; - rtems_id tid; + Scheduler_CBS_Server *the_server; if ( server_id >= _Scheduler_CBS_Maximum_servers ) return SCHEDULER_CBS_ERROR_INVALID_PARAMETER; if ( !_Scheduler_CBS_Server_list[server_id].initialized ) return SCHEDULER_CBS_ERROR_NOSERVER; + + the_server = &_Scheduler_CBS_Server_list[ server_id ]; + the_server->initialized = false; - if ( (tid = _Scheduler_CBS_Server_list[server_id].task_id) != -1 ) - ret = _Scheduler_CBS_Detach_thread ( server_id, tid ); - - _Scheduler_CBS_Server_list[server_id].initialized = false; - return ret; + return SCHEDULER_CBS_OK; } diff --git a/cpukit/score/src/schedulercbsdetachthread.c b/cpukit/score/src/schedulercbsdetachthread.c index c840c8b..db5a42a 100644 --- a/cpukit/score/src/schedulercbsdetachthread.c +++ b/cpukit/score/src/schedulercbsdetachthread.c @@ -9,58 +9,54 @@ /* * Copyright (C) 2011 Petr Benes. * Copyright (C) 2011 On-Line Applications Research Corporation (OAR). + * + * Copyright (C) 2019 Joel Pinto, Research Centre in Real-Time & Embedded Computing Systems (CISTER). * * 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/schedulercbsimpl.h> -#include <rtems/score/threadimpl.h> int _Scheduler_CBS_Detach_thread ( - Scheduler_CBS_Server_id server_id, rtems_id task_id ) { - Scheduler_CBS_Server *server; - ISR_lock_Context lock_context; + Thread_Close_context context; Thread_Control *the_thread; - Scheduler_CBS_Node *node; + Scheduler_CBS_Node *the_node; + + the_thread = _Thread_Get( task_id, &context.Base.Lock_context.Lock_context ); - if ( server_id >= _Scheduler_CBS_Maximum_servers ) { + if( the_thread == NULL ) return SCHEDULER_CBS_ERROR_INVALID_PARAMETER; - } + + _ISR_lock_ISR_enable( &context.Base.Lock_context.Lock_context ); - server = &_Scheduler_CBS_Server_list[ server_id ]; + the_node = _Scheduler_CBS_Thread_get_node( the_thread ); - if ( !server->initialized ) { + if( the_node->server == NULL ) return SCHEDULER_CBS_ERROR_NOSERVER; - } - if ( server->task_id != task_id ) { - return SCHEDULER_CBS_ERROR_INVALID_PARAMETER; + if( the_thread == _Thread_Executing ) { + Per_CPU_Control *cpu_self; + + cpu_self = _Thread_queue_Dispatch_disable( &context.Base ); + + _Thread_Exit( + the_thread, + THREAD_LIFE_TERMINATING | THREAD_LIFE_DETACHED, + NULL + ); + _Thread_Dispatch_enable( cpu_self ); + } else { + _Scheduler_CBS_RBNode_search( &the_node->server->tree, the_node, _Scheduler_CBS_Dequeue_Thread_Node ); + the_node->server = NULL; + _Thread_Close( the_thread, _Thread_Executing, &context ); } - - the_thread = _Thread_Get( task_id, &lock_context ); - - if ( the_thread == NULL ) { - return SCHEDULER_CBS_ERROR_INVALID_PARAMETER; - } - - node = _Scheduler_CBS_Thread_get_node( the_thread ); - node->cbs_server = NULL; - - server->task_id = -1; - - the_thread->budget_algorithm = the_thread->Start.budget_algorithm; - the_thread->budget_callout = the_thread->Start.budget_callout; - the_thread->is_preemptible = the_thread->Start.is_preemptible; - - _ISR_lock_ISR_enable( &lock_context ); return SCHEDULER_CBS_OK; } diff --git a/cpukit/score/src/schedulercbsgetapprovedbudget.c b/cpukit/score/src/schedulercbsgetapprovedbudget.c index e72ef3b..cf221f8 100644 --- a/cpukit/score/src/schedulercbsgetapprovedbudget.c +++ b/cpukit/score/src/schedulercbsgetapprovedbudget.c @@ -8,6 +8,8 @@ /* * Copyright (C) 2011 Petr Benes. * Copyright (C) 2011 On-Line Applications Research Corporation (OAR). + * + * Copyright (C) 2019 Joel Pinto, Research Centre in Real-Time & Embedded Computing Systems (CISTER). * * The license and distribution terms for this file may be * found in the file LICENSE in this distribution or at @@ -19,8 +21,7 @@ #endif #include <rtems/config.h> -#include <rtems/score/scheduler.h> -#include <rtems/score/schedulercbs.h> +#include <rtems/score/schedulercbsimpl.h> int _Scheduler_CBS_Get_approved_budget ( Scheduler_CBS_Server_id server_id, @@ -29,9 +30,11 @@ int _Scheduler_CBS_Get_approved_budget ( { if ( server_id >= _Scheduler_CBS_Maximum_servers ) return SCHEDULER_CBS_ERROR_INVALID_PARAMETER; + if ( !_Scheduler_CBS_Server_list[server_id].initialized ) return SCHEDULER_CBS_ERROR_NOSERVER; *approved_budget = _Scheduler_CBS_Server_list[server_id].parameters.budget; + return SCHEDULER_CBS_OK; } diff --git a/cpukit/score/src/schedulercbsgetexecutiontime.c b/cpukit/score/src/schedulercbsgetexecutiontime.c deleted file mode 100644 index b18ce9a..0000000 --- a/cpukit/score/src/schedulercbsgetexecutiontime.c +++ /dev/null @@ -1,60 +0,0 @@ -/** - * @file - * - * @brief Get Thread Execution Info - * - * @ingroup RTEMSScoreScheduler - */ - -/* - * Copyright (C) 2011 Petr Benes. - * 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/schedulercbs.h> -#include <rtems/score/threadimpl.h> - -int _Scheduler_CBS_Get_execution_time ( - Scheduler_CBS_Server_id server_id, - time_t *exec_time, - time_t *abs_time -) -{ - Scheduler_CBS_Server *server; - ISR_lock_Context lock_context; - Thread_Control *the_thread; - - if ( server_id >= _Scheduler_CBS_Maximum_servers ) { - return SCHEDULER_CBS_ERROR_INVALID_PARAMETER; - } - - server = &_Scheduler_CBS_Server_list[ server_id ]; - - if ( !server->initialized ) { - return SCHEDULER_CBS_ERROR_NOSERVER; - } - - if ( server->task_id == -1 ) { - *exec_time = 0; - return SCHEDULER_CBS_OK; - } - - the_thread = _Thread_Get( server->task_id, &lock_context ); - - if ( the_thread != NULL ) { - *exec_time = server->parameters.budget - the_thread->cpu_time_budget; - _ISR_lock_ISR_enable( &lock_context ); - } else { - *exec_time = server->parameters.budget; - } - - return SCHEDULER_CBS_OK; -} diff --git a/cpukit/score/src/schedulercbsgetparameters.c b/cpukit/score/src/schedulercbsgetparameters.c index 1abe5d9..3c895a1 100644 --- a/cpukit/score/src/schedulercbsgetparameters.c +++ b/cpukit/score/src/schedulercbsgetparameters.c @@ -8,6 +8,8 @@ /* * Copyright (C) 2011 Petr Benes. * Copyright (C) 2011 On-Line Applications Research Corporation (OAR). + * + * Copyright (C) 2019 Joel Pinto, Research Centre in Real-Time & Embedded Computing Systems (CISTER). * * The license and distribution terms for this file may be * found in the file LICENSE in this distribution or at @@ -19,19 +21,20 @@ #endif #include <rtems/config.h> -#include <rtems/score/scheduler.h> -#include <rtems/score/schedulercbs.h> +#include <rtems/score/schedulercbsimpl.h> int _Scheduler_CBS_Get_parameters ( Scheduler_CBS_Server_id server_id, Scheduler_CBS_Parameters *params ) { + if ( server_id >= _Scheduler_CBS_Maximum_servers ) return SCHEDULER_CBS_ERROR_INVALID_PARAMETER; if ( !_Scheduler_CBS_Server_list[server_id].initialized ) return SCHEDULER_CBS_ERROR_NOSERVER; *params = _Scheduler_CBS_Server_list[server_id].parameters; + return SCHEDULER_CBS_OK; } diff --git a/cpukit/score/src/schedulercbsgetremainingbudget.c b/cpukit/score/src/schedulercbsgetremainingbudget.c index d556f33..c4f88c6 100644 --- a/cpukit/score/src/schedulercbsgetremainingbudget.c +++ b/cpukit/score/src/schedulercbsgetremainingbudget.c @@ -8,18 +8,18 @@ /* * Copyright (C) 2011 Petr Benes. * Copyright (C) 2011 On-Line Applications Research Corporation (OAR). + * + * Copyright (C) 2019 Joel Pinto, Research Centre in Real-Time & Embedded Computing Systems (CISTER). * * 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/schedulercbs.h> -#include <rtems/score/threadimpl.h> +#include <rtems/score/schedulercbsimpl.h> int _Scheduler_CBS_Get_remaining_budget ( Scheduler_CBS_Server_id server_id, @@ -29,7 +29,7 @@ int _Scheduler_CBS_Get_remaining_budget ( Scheduler_CBS_Server *server; ISR_lock_Context lock_context; Thread_Control *the_thread; - + if ( server_id >= _Scheduler_CBS_Maximum_servers ) { return SCHEDULER_CBS_ERROR_INVALID_PARAMETER; } @@ -40,18 +40,18 @@ int _Scheduler_CBS_Get_remaining_budget ( return SCHEDULER_CBS_ERROR_NOSERVER; } - if ( server->task_id == -1 ) { - *remaining_budget = server->parameters.budget; + if( server->current_thread == -1 ) { + *remaining_budget = server->remaining_budget; return SCHEDULER_CBS_OK; } - the_thread = _Thread_Get( server->task_id, &lock_context ); + the_thread = _Thread_Get( server->current_thread, &lock_context ); if ( the_thread != NULL ) { *remaining_budget = the_thread->cpu_time_budget; _ISR_lock_ISR_enable( &lock_context ); } else { - *remaining_budget = 0; + *remaining_budget = server->remaining_budget; } return SCHEDULER_CBS_OK; diff --git a/cpukit/score/src/schedulercbsgetserverid.c b/cpukit/score/src/schedulercbsgetserverid.c index 276c08f..6ec29e2 100644 --- a/cpukit/score/src/schedulercbsgetserverid.c +++ b/cpukit/score/src/schedulercbsgetserverid.c @@ -8,29 +8,44 @@ /* * Copyright (C) 2011 Petr Benes. * Copyright (C) 2011 On-Line Applications Research Corporation (OAR). + * + * Copyright (C) 2019 Joel Pinto, Research Centre in Real-Time & Embedded Computing Systems (CISTER). * * 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/config.h> -#include <rtems/score/scheduler.h> -#include <rtems/score/schedulercbs.h> +#include <rtems/score/schedulercbsimpl.h> int _Scheduler_CBS_Get_server_id ( rtems_id task_id, Scheduler_CBS_Server_id *server_id ) { + const Scheduler_CBS_Node *node; + ISR_lock_Context lock_context; + Thread_Control *the_thread; + + + the_thread = _Thread_Get( task_id, &lock_context ); + + if( the_thread == NULL ) + return SCHEDULER_CBS_ERROR_NOT_FOUND; + + _ISR_lock_ISR_enable( &lock_context ); + + node = _Scheduler_CBS_Thread_get_node( the_thread ); + if(node->server == NULL) + return SCHEDULER_CBS_ERROR_NOSERVER; + unsigned int i; for ( i = 0; i<_Scheduler_CBS_Maximum_servers; i++ ) { - if ( _Scheduler_CBS_Server_list[i].initialized && - _Scheduler_CBS_Server_list[i].task_id == task_id ) { + if ( &_Scheduler_CBS_Server_list[i] == node->server ) { *server_id = i; return SCHEDULER_CBS_OK; } diff --git a/cpukit/score/src/schedulercbsnodeinit.c b/cpukit/score/src/schedulercbsnodeinit.c index 08f63a1..8a16fb4 100644 --- a/cpukit/score/src/schedulercbsnodeinit.c +++ b/cpukit/score/src/schedulercbsnodeinit.c @@ -32,6 +32,6 @@ void _Scheduler_CBS_Node_initialize( _Scheduler_EDF_Node_initialize( scheduler, node, the_thread, priority ); the_node = _Scheduler_CBS_Node_downcast( node ); - the_node->cbs_server = NULL; + the_node->server = NULL; the_node->deadline_node = NULL; } diff --git a/cpukit/score/src/schedulercbsreleasejob.c b/cpukit/score/src/schedulercbsreleasejob.c index 3ac07eb..80143d6 100644 --- a/cpukit/score/src/schedulercbsreleasejob.c +++ b/cpukit/score/src/schedulercbsreleasejob.c @@ -9,6 +9,8 @@ /* * Copyright (C) 2011 Petr Benes. * Copyright (C) 2011 On-Line Applications Research Corporation (OAR). + * + * Copyright (C) 2019 Joel Pinto, Research Centre in Real-Time & Embedded Computing Systems (CISTER). * * The license and distribution terms for this file may be * found in the file LICENSE in this distribution or at @@ -29,19 +31,25 @@ void _Scheduler_CBS_Release_job( Thread_queue_Context *queue_context ) { - Scheduler_CBS_Node *node; - Scheduler_CBS_Server *serv_info; + Scheduler_CBS_Node *the_node; + + the_node = _Scheduler_CBS_Thread_get_node( the_thread ); + the_node->deadline_node = priority_node; - node = _Scheduler_CBS_Thread_get_node( the_thread ); - serv_info = node->cbs_server; - - /* Budget replenishment for the next job. */ - if ( serv_info != NULL ) { - the_thread->cpu_time_budget = serv_info->parameters.budget; + if( the_node->server != NULL ) { + + the_node->rms_dead = deadline; + + if( _States_Is_ready( the_thread->current_state ) ) { + _Thread_Wait_acquire_critical( the_thread, queue_context ); + _Scheduler_CBS_RBNode_search( &the_node->server->tree, the_node, _Scheduler_CBS_Dequeue_Thread_Node ); + _Scheduler_CBS_Enqueue_Thread_Node( &the_node->server->tree, &the_node->thread_cbs_node, the_node->rms_dead ); + _Scheduler_CBS_Schedule( scheduler, the_node->server, true ); + _Thread_Wait_release_critical( the_thread, queue_context ); + } + return; } - - node->deadline_node = priority_node; - + _Scheduler_EDF_Release_job( scheduler, the_thread, diff --git a/cpukit/score/src/schedulercbssetparameters.c b/cpukit/score/src/schedulercbssetparameters.c index 0b8b664..edf6b4f 100644 --- a/cpukit/score/src/schedulercbssetparameters.c +++ b/cpukit/score/src/schedulercbssetparameters.c @@ -9,6 +9,8 @@ /* * Copyright (C) 2011 Petr Benes. * Copyright (C) 2011 On-Line Applications Research Corporation (OAR). + * + * Copyright (C) 2019 Joel Pinto, Research Centre in Real-Time & Embedded Computing Systems (CISTER). * * The license and distribution terms for this file may be * found in the file LICENSE in this distribution or at @@ -19,8 +21,7 @@ #include "config.h" #endif -#include <rtems/score/schedulercbs.h> -#include <rtems/score/scheduleredfimpl.h> +#include <rtems/score/schedulercbsimpl.h> int _Scheduler_CBS_Set_parameters ( Scheduler_CBS_Server_id server_id, diff --git a/cpukit/score/src/schedulercbsunblock.c b/cpukit/score/src/schedulercbsunblock.c index 4d751f9..9119543 100644 --- a/cpukit/score/src/schedulercbsunblock.c +++ b/cpukit/score/src/schedulercbsunblock.c @@ -9,6 +9,8 @@ /* * Copyright (C) 2011 Petr Benes. * Copyright (C) 2011 On-Line Applications Research Corporation (OAR). + * + * Copyright (C) 2019 Joel Pinto, Research Centre in Real-Time & Embedded Computing Systems (CISTER). * * The license and distribution terms for this file may be * found in the file LICENSE in this distribution or at @@ -20,9 +22,6 @@ #endif #include <rtems/score/schedulercbsimpl.h> -#include <rtems/score/scheduleredfimpl.h> -#include <rtems/score/schedulerimpl.h> -#include <rtems/score/threadimpl.h> #include <rtems/score/watchdogimpl.h> void _Scheduler_CBS_Unblock( @@ -32,39 +31,14 @@ void _Scheduler_CBS_Unblock( ) { Scheduler_CBS_Node *the_node; - Scheduler_CBS_Server *serv_info; - Priority_Control priority; - + the_node = _Scheduler_CBS_Node_downcast( node ); - serv_info = the_node->cbs_server; - priority = _Scheduler_Node_get_priority( &the_node->Base.Base ); - priority = SCHEDULER_PRIORITY_PURIFY( priority ); - - /* - * Late unblock rule for deadline-driven tasks. The remaining time to - * deadline must be sufficient to serve the remaining computation time - * without increased utilization of this task. It might cause a deadline - * miss of another task. - */ - if ( serv_info != NULL && ( priority & SCHEDULER_EDF_PRIO_MSB ) == 0 ) { - time_t deadline = serv_info->parameters.deadline; - time_t budget = serv_info->parameters.budget; - uint32_t deadline_left = the_thread->cpu_time_budget; - Priority_Control budget_left = priority - _Watchdog_Ticks_since_boot; - if ( deadline * budget_left > budget * deadline_left ) { - Thread_queue_Context queue_context; - - /* Put late unblocked task to background until the end of period. */ - _Thread_queue_Context_clear_priority_updates( &queue_context ); - _Scheduler_CBS_Cancel_job( - scheduler, - the_thread, - the_node->deadline_node, - &queue_context - ); - } + if( the_node->server != NULL && the_node->rms_dead != 0 ) { + _Scheduler_CBS_RBNode_search( &the_node->server->tree, the_node, _Scheduler_CBS_Dequeue_Thread_Node ); + _Scheduler_CBS_Enqueue_Thread_Node( &the_node->server->tree, &the_node->thread_cbs_node, the_node->rms_dead ); + _Scheduler_CBS_Schedule( scheduler, the_node->server, false ); + return; } - _Scheduler_EDF_Unblock( scheduler, the_thread, &the_node->Base.Base ); } diff --git a/testsuites/sptests/Makefile.am b/testsuites/sptests/Makefile.am index eae5630..962c6fd 100644 --- a/testsuites/sptests/Makefile.am +++ b/testsuites/sptests/Makefile.am @@ -14,6 +14,7 @@ sp_libs = support_includes = -I$(top_srcdir)/../support/include + if TEST_sp01 sp_tests += sp01 sp_screens += sp01/sp01.scn @@ -54,7 +55,7 @@ sp_screens += sp05/sp05.scn sp_docs += sp05/sp05.doc sp05_SOURCES = sp05/init.c sp05/task1.c sp05/task2.c sp05/task3.c \ sp05/system.h -sp05_CPPFLAGS = $(AM_CPPFLAGS) $(TEST_FLAGS_sp05) $(support_includes) +sp05_CPPFLAGS = $(AM_CPPFLAGS) $(TEST_FLAGS40020_sp05) $(support_includes) endif if TEST_sp06 @@ -680,6 +681,26 @@ spcbssched03_CPPFLAGS = $(AM_CPPFLAGS) $(TEST_FLAGS_spcbssched03) \ $(support_includes) endif +if TEST_spcbssched04 +sp_tests += spcbssched04 +sp_screens += spcbssched04/spcbssched04.scn +sp_docs += spcbssched04/spcbssched04.doc +spcbssched04_SOURCES = spcbssched04/init.c \ + spcbssched04/system.h spcbssched04/hard_tasks.c spcbssched04/soft_tasks.c +spcbssched04_CPPFLAGS = $(AM_CPPFLAGS) $(TEST_FLAGS_spcbssched04) \ + $(support_includes) +endif + +if TEST_spcbssched05 +sp_tests += spcbssched05 +sp_screens += spcbssched05/spcbssched05.scn +sp_docs += spcbssched05/spcbssched05.doc +spcbssched05_SOURCES = spcbssched05/init.c \ + spcbssched05/system.h spcbssched05/soft_tasks.c +spcbssched05_CPPFLAGS = $(AM_CPPFLAGS) $(TEST_FLAGS_spcbssched05) \ + $(support_includes) +endif + if TEST_spchain sp_tests += spchain sp_screens += spchain/spchain.scn diff --git a/testsuites/sptests/configure.ac b/testsuites/sptests/configure.ac index 3222196..98b5868 100644 --- a/testsuites/sptests/configure.ac +++ b/testsuites/sptests/configure.ac @@ -114,6 +114,8 @@ RTEMS_TEST_CHECK([spcache01]) RTEMS_TEST_CHECK([spcbssched01]) RTEMS_TEST_CHECK([spcbssched02]) RTEMS_TEST_CHECK([spcbssched03]) +RTEMS_TEST_CHECK([spcbssched04]) +RTEMS_TEST_CHECK([spcbssched05]) RTEMS_TEST_CHECK([spchain]) RTEMS_TEST_CHECK([spclock_err01]) RTEMS_TEST_CHECK([spclock_err02]) diff --git a/testsuites/sptests/spcbssched02/init.c b/testsuites/sptests/spcbssched02/init.c index acaf7a7..78b025d 100644 --- a/testsuites/sptests/spcbssched02/init.c +++ b/testsuites/sptests/spcbssched02/init.c @@ -87,58 +87,45 @@ rtems_task Init( printf( "ERROR: DESTROY SERVER PASSED UNEXPECTEDLY\n" ); if ( rtems_cbs_destroy_server( 0 ) != SCHEDULER_CBS_ERROR_NOSERVER ) printf( "ERROR: DESTROY SERVER PASSED UNEXPECTEDLY\n" ); - if ( rtems_cbs_create_server( ¶ms1, NULL, &server_id ) != + if ( rtems_cbs_create_server( ¶ms1, &server_id ) != SCHEDULER_CBS_ERROR_INVALID_PARAMETER ) printf( "ERROR: CREATE SERVER PASSED UNEXPECTEDLY\n" ); - if ( rtems_cbs_create_server( ¶ms3, NULL, &server_id ) != + if ( rtems_cbs_create_server( ¶ms3, &server_id ) != SCHEDULER_CBS_ERROR_INVALID_PARAMETER ) printf( "ERROR: CREATE SERVER PASSED UNEXPECTEDLY\n" ); - if ( rtems_cbs_create_server( ¶ms, NULL, &server_id2 ) ) + if ( rtems_cbs_create_server( ¶ms, &server_id2 ) ) printf( "ERROR: CREATE SERVER FAILED\n" ); - if ( rtems_cbs_create_server( ¶ms, NULL, &server_id ) ) + if ( rtems_cbs_create_server( ¶ms, &server_id ) ) printf( "ERROR: CREATE SERVER FAILED\n" ); - if ( rtems_cbs_create_server( ¶ms, NULL, &server_id ) ) - printf( "ERROR: CREATE SERVER FAILED\n" ); - if ( rtems_cbs_create_server( ¶ms, NULL, &server_id ) != - SCHEDULER_CBS_ERROR_FULL ) - printf( "ERROR: CREATE SERVER PASSED UNEXPECTEDLY\n" ); /* Error checks for Attach thread and Detach thread */ printf( "Init: Attach thread\n" ); if ( rtems_cbs_attach_thread( -5, RTEMS_SELF ) != SCHEDULER_CBS_ERROR_INVALID_PARAMETER ) - printf( "ERROR: ATTACH THREAD PASSED UNEXPECTEDLY\n" ); + printf( "ERROR: ATTACH THREAD PASSED UNEXPECTEDLY 1\n" ); if ( rtems_cbs_attach_thread( 5, RTEMS_SELF ) != SCHEDULER_CBS_ERROR_INVALID_PARAMETER ) - printf( "ERROR: ATTACH THREAD PASSED UNEXPECTEDLY\n" ); + printf( "ERROR: ATTACH THREAD PASSED UNEXPECTEDLY 2 \n" ); if ( rtems_cbs_attach_thread( server_id, 1234 ) != SCHEDULER_CBS_ERROR_INVALID_PARAMETER ) - printf( "ERROR: ATTACH THREAD PASSED UNEXPECTEDLY\n" ); - if ( rtems_cbs_attach_thread( server_id, RTEMS_SELF ) ) - printf( "ERROR: ATTACH THREAD FAILED\n" ); - if ( rtems_cbs_attach_thread( server_id, RTEMS_SELF ) != - SCHEDULER_CBS_ERROR_FULL ) - printf( "ERROR: ATTACH THREAD AGAIN PASSED UNEXPECTEDLY\n" ); - if ( rtems_cbs_attach_thread( server_id, Task_id ) != - SCHEDULER_CBS_ERROR_FULL ) - printf( "ERROR: ATTACH THREAD TO FULL SERVER PASSED UNEXPECTEDLY \n" ); + printf( "ERROR: ATTACH THREAD PASSED UNEXPECTEDLY 3\n" ); if ( rtems_cbs_destroy_server( server_id ) ) printf( "ERROR: DESTROY SERVER WITH THREAD ATTACHED FAILED\n" ); if ( rtems_cbs_attach_thread( server_id, RTEMS_SELF ) != SCHEDULER_CBS_ERROR_NOSERVER ) - printf( "ERROR: ATTACH THREAD PASSED UNEXPECTEDLY\n" ); - + printf( "ERROR: ATTACH THREAD PASSED UNEXPECTEDLY 4\n" ); + printf( "Init: Detach thread\n" ); - if ( rtems_cbs_detach_thread( -5, RTEMS_SELF ) != - SCHEDULER_CBS_ERROR_INVALID_PARAMETER ) + if ( rtems_cbs_detach_thread( RTEMS_SELF ) != + SCHEDULER_CBS_ERROR_NOSERVER ) printf( "ERROR: DETACH THREAD PASSED UNEXPECTEDLY\n" ); - if ( rtems_cbs_detach_thread( 5, RTEMS_SELF ) != - SCHEDULER_CBS_ERROR_INVALID_PARAMETER ) + if ( rtems_cbs_detach_thread( RTEMS_SELF ) != + SCHEDULER_CBS_ERROR_NOSERVER ) printf( "ERROR: DETACH THREAD PASSED UNEXPECTEDLY\n" ); - if ( rtems_cbs_detach_thread( server_id2, 1234 ) != + if ( rtems_cbs_detach_thread( 1234 ) != SCHEDULER_CBS_ERROR_INVALID_PARAMETER ) printf( "ERROR: DETACH THREAD PASSED UNEXPECTEDLY \n" ); - if ( rtems_cbs_detach_thread( server_id, RTEMS_SELF ) != + if ( rtems_cbs_detach_thread( RTEMS_SELF ) != SCHEDULER_CBS_ERROR_NOSERVER ) printf( "ERROR: DETACH THREAD PASSED UNEXPECTEDLY4\n" ); rtems_cbs_destroy_server( server_id2 ); @@ -160,7 +147,7 @@ rtems_task Init( printf( "ERROR: GET PARAMETERS PASSED UNEXPECTEDLY\n" ); if ( rtems_cbs_get_parameters( 5, ¶ms ) != SCHEDULER_CBS_ERROR_INVALID_PARAMETER ) - printf( "ERROR: GET PARAMETERS PASSED UNEXPECTEDLY\n" ); + printf( "ERROR: GET PARAM/*ETERS PASSED UNEXPECTEDLY\n" ); if ( rtems_cbs_get_parameters( server_id, ¶ms ) != SCHEDULER_CBS_ERROR_NOSERVER ) printf( "ERROR: GET PARAMETERS PASSED UNEXPECTEDLY\n" ); @@ -186,9 +173,7 @@ rtems_task Init( if ( rtems_cbs_get_approved_budget( 5, &approved_budget ) != SCHEDULER_CBS_ERROR_INVALID_PARAMETER ) printf( "ERROR: GET APPROVED BUDGET PASSED UNEXPECTEDLY\n" ); - if ( rtems_cbs_get_approved_budget( server_id, &approved_budget ) != - SCHEDULER_CBS_ERROR_NOSERVER ) - printf( "ERROR: GET APPROVED BUDGET PASSED UNEXPECTEDLY\n" ); + /* Error checks for Get remaining budget */ printf( "Init: Get remaining budget\n" ); @@ -198,26 +183,13 @@ rtems_task Init( if ( rtems_cbs_get_remaining_budget( 5, &remaining_budget ) != SCHEDULER_CBS_ERROR_INVALID_PARAMETER ) printf( "ERROR: GET REMAINING BUDGET PASSED UNEXPECTEDLY\n" ); - if ( rtems_cbs_get_remaining_budget( server_id, &remaining_budget ) != - SCHEDULER_CBS_ERROR_NOSERVER ) - printf( "ERROR: GET REMAINING BUDGET PASSED UNEXPECTEDLY\n" ); - /* Error checks for Get execution time */ - printf( "Init: Get execution time\n" ); - if ( rtems_cbs_get_execution_time( -5, &exec_time, &abs_time ) != - SCHEDULER_CBS_ERROR_INVALID_PARAMETER ) - printf( "ERROR: GET EXECUTION TIME PASSED UNEXPECTEDLY\n" ); - if ( rtems_cbs_get_execution_time( 5, &exec_time, &abs_time ) != - SCHEDULER_CBS_ERROR_INVALID_PARAMETER ) - printf( "ERROR: GET EXECUTION TIME PASSED UNEXPECTEDLY\n" ); - if ( rtems_cbs_get_execution_time( server_id, &exec_time, &abs_time ) != - SCHEDULER_CBS_ERROR_NOSERVER ) - printf( "ERROR: GET EXECUTION TIME PASSED UNEXPECTEDLY\n" ); /* Restart CBS library */ printf( "Init: Cleaning up CBS\n" ); if ( rtems_cbs_cleanup() ) printf( "ERROR: CBS CLEANUP FAILED\n" ); + printf( "Init: Initializing the CBS\n" ); if ( rtems_cbs_initialize() ) printf( "ERROR: CBS INITIALIZATION FAILED\n" ); @@ -231,12 +203,6 @@ rtems_task Init( rtems_task_wake_after( 130 ); - printf( "Init: Checking server with a deleted task\n" ); - if ( rtems_cbs_get_execution_time( 0, &exec_time, &abs_time ) ) - printf( "ERROR: GET EXECUTION TIME FAILED\n" ); - if ( rtems_cbs_get_remaining_budget( 0, &remaining_budget) ) - printf( "ERROR: GET REMAINING BUDGET FAILED\n" ); - if ( rtems_cbs_cleanup() ) printf( "ERROR: CBS CLEANUP\n" ); diff --git a/testsuites/sptests/spcbssched02/task_periodic.c b/testsuites/sptests/spcbssched02/task_periodic.c index 39516cc..0e1b1e6 100644 --- a/testsuites/sptests/spcbssched02/task_periodic.c +++ b/testsuites/sptests/spcbssched02/task_periodic.c @@ -26,7 +26,7 @@ rtems_task Task_Periodic( rtems_id rmid; rtems_status_code status; - time_t approved_budget, exec_time, abs_time, remaining_budget; + time_t approved_budget; int start, stop, now; @@ -35,11 +35,13 @@ rtems_task Task_Periodic( params.deadline = Period; params.budget = Execution+1; + + printf(" here \n"); /* Taks 1 will be attached to a server, task 2 not. */ if ( argument == 1 ) { printf( "Periodic task: Create server and Attach thread\n" ); - if ( rtems_cbs_create_server( ¶ms, NULL, &server_id ) ) + if ( rtems_cbs_create_server( ¶ms, &server_id ) ) printf( "ERROR: CREATE SERVER FAILED\n" ); if ( rtems_cbs_attach_thread( server_id, Task_id ) ) printf( "ERROR: ATTACH THREAD FAILED\n" ); @@ -55,25 +57,6 @@ rtems_task Task_Periodic( params.budget != tparams.budget ) printf( "ERROR: PARAMETERS MISMATCH\n" ); - printf( "Periodic task: Detach thread and Destroy server\n" ); - if ( rtems_cbs_detach_thread( server_id, Task_id ) ) - printf( "ERROR: DETACH THREAD FAILED\n" ); - if ( rtems_cbs_destroy_server( server_id ) ) - printf( "ERROR: DESTROY SERVER FAILED\n" ); - if ( rtems_cbs_create_server( ¶ms, NULL, &server_id ) ) - printf( "ERROR: CREATE SERVER FAILED\n" ); - - printf( "Periodic task: Remaining budget and Execution time\n" ); - if ( rtems_cbs_get_remaining_budget( server_id, &remaining_budget ) ) - printf( "ERROR: GET REMAINING BUDGET FAILED\n" ); - if ( remaining_budget != params.budget ) - printf( "ERROR: REMAINING BUDGET MISMATCH\n" ); - if ( rtems_cbs_get_execution_time( server_id, &exec_time, &abs_time ) ) - printf( "ERROR: GET EXECUTION TIME FAILED\n" ); - - printf( "Periodic task: Set parameters\n" ); - if ( rtems_cbs_attach_thread( server_id, Task_id ) ) - printf( "ERROR: ATTACH THREAD FAILED\n" ); params.deadline = Period * 2; params.budget = Execution * 2 +1; if ( rtems_cbs_set_parameters( server_id, ¶ms ) ) @@ -114,22 +97,11 @@ rtems_task Task_Periodic( while(FOREVER) { now = rtems_clock_get_ticks_since_boot(); if ( now >= start + Execution ) break; - - if ( server_id != 0 ) { - if ( rtems_cbs_get_execution_time( server_id, &exec_time, &abs_time ) ) - printf( "ERROR: GET EXECUTION TIME FAILED\n" ); - if ( rtems_cbs_get_remaining_budget( server_id, &remaining_budget) ) - printf( "ERROR: GET REMAINING BUDGET FAILED\n" ); - if ( (remaining_budget + exec_time) > (Execution + 1) ) { - printf( "ERROR: REMAINING BUDGET AND EXECUTION TIME MISMATCH\n" ); - rtems_test_exit( 0 ); - } - } } stop = rtems_clock_get_ticks_since_boot(); printf( "P%" PRIdPTR "-F ticks:%d\n", argument, stop ); } - + /* delete period and SELF */ status = rtems_rate_monotonic_delete( rmid ); if ( status != RTEMS_SUCCESSFUL ) { diff --git a/testsuites/sptests/spcbssched03/system.h b/testsuites/sptests/spcbssched03/system.h index 1f864b5..94fdaed 100644 --- a/testsuites/sptests/spcbssched03/system.h +++ b/testsuites/sptests/spcbssched03/system.h @@ -72,4 +72,5 @@ TEST_EXTERN uint32_t Phases[1 + NUM_TASKS]; TEST_EXTERN uint32_t Execution[1 + NUM_TASKS]; TEST_EXTERN bool Violating_task[1 + NUM_PERIODIC_TASKS]; + /* end of include file */ diff --git a/testsuites/sptests/spcbssched03/tasks_periodic.c b/testsuites/sptests/spcbssched03/tasks_periodic.c index aa68228..7a3869f 100644 --- a/testsuites/sptests/spcbssched03/tasks_periodic.c +++ b/testsuites/sptests/spcbssched03/tasks_periodic.c @@ -19,19 +19,6 @@ #include "system.h" -/* forward declarations to avoid warnings */ -void overrun_handler_task_4(rtems_cbs_server_id server_id); - -void overrun_handler_task_4( - rtems_cbs_server_id server_id -) -{ - printk( "Signal overrun, fixing the task\n" ); - Violating_task[ 4 ] = 0; - /* rtems_task_restart( RTEMS_SELF, 4 ); might be also possible*/ - return; -} - rtems_task Tasks_Periodic( rtems_task_argument argument ) @@ -50,11 +37,11 @@ rtems_task Tasks_Periodic( params.budget = Execution[ argument ]+1; if ( argument == 4 ) { - if ( rtems_cbs_create_server( ¶ms, &overrun_handler_task_4, &server_id )) + if ( rtems_cbs_create_server( ¶ms, &server_id )) printf( "ERROR: CREATE SERVER FAILED\n" ); } else { - if ( rtems_cbs_create_server( ¶ms, NULL, &server_id ) ) + if ( rtems_cbs_create_server( ¶ms, &server_id ) ) printf( "ERROR: CREATE SERVER FAILED\n" ); } if ( rtems_cbs_attach_thread( server_id, Task_id[ argument ] ) ) @@ -152,8 +139,7 @@ rtems_task Tasks_Periodic( printf("rtems_rate_monotonic_delete failed with status of %d.\n",status); rtems_test_exit( 0 ); } - if ( rtems_cbs_cleanup() ) - printf( "ERROR: CBS CLEANUP\n" ); + fflush(stdout); TEST_END(); rtems_test_exit( 0 ); diff --git a/testsuites/sptests/spcbssched04/hard_tasks.c b/testsuites/sptests/spcbssched04/hard_tasks.c new file mode 100644 index 0000000..a7f85b6 --- /dev/null +++ b/testsuites/sptests/spcbssched04/hard_tasks.c @@ -0,0 +1,74 @@ +/* Tasks_Periodic + * + * This routine serves as a test task for the CBS scheduler + * implementation. + * + * Input parameters: + * argument - task argument + * + * Output parameters: NONE + * + * 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 "system.h" + +rtems_task Hard_Task( + rtems_task_argument argument +) +{ + rtems_id rmid; + rtems_status_code status; + int start, stop, now; + + + status = rtems_rate_monotonic_create( argument, &rmid ); + directive_failed( status, "rtems_rate_monotonic_create" ); + + printf( "Periodic task: Starting periodic behavior\n" ); + //status = rtems_task_wake_after( 1 + Phase ); + + + while ( FOREVER ) { + //printf("Rate mon initiating \n "); + + if ( rtems_rate_monotonic_period(rmid, Hard_Period) == RTEMS_TIMEOUT ) + printf( "P%" PRIdPTR " - Deadline miss\n", argument ); + + if( !sync_milestone[ argument - 1] ) + { + status = rtems_barrier_wait( + barrier_id, + RTEMS_WAIT + ); + directive_failed( status , "Barrier waiting failed "); + sync_milestone[ argument - 1] = true; + } + + start = rtems_clock_get_ticks_since_boot(); + printf( "P%" PRIdPTR "-S ticks:%d\n", argument, start ); + + if ( start > 3 * Hard_Period ) break; /* stop */ + /* active computing */ + while(FOREVER) + { + now = rtems_clock_get_ticks_since_boot(); + if ( now >= ( start + Hard_Execution ) ) + break; + + } + stop = rtems_clock_get_ticks_since_boot(); + printf( "P%" PRIdPTR "-F ticks:%d\n", argument, stop ); + } + + printf("Gonna eliminate rms \n"); + status = rtems_rate_monotonic_delete( rmid ); + directive_failed( status, " ERROR Deleting RM \n"); + rtems_task_exit(); +} diff --git a/testsuites/sptests/spcbssched04/init.c b/testsuites/sptests/spcbssched04/init.c new file mode 100644 index 0000000..58762f9 --- /dev/null +++ b/testsuites/sptests/spcbssched04/init.c @@ -0,0 +1,114 @@ +/* Init + * + * This routine is the initialization task for this test program. + * It is a user initialization task and has the responsibility for creating + * and starting the tasks that make up the test. If the time of day + * clock is required for the test, it should also be set to a known + * value by this function. + * + * Input parameters: + * argument - task argument + * + * Output parameters: NONE + * + * 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 + +#define CONFIGURE_INIT +#include "system.h" +#include <inttypes.h> + +const char rtems_test_name[] = "SPCBSSCHED 4"; + +rtems_task Init( + rtems_task_argument argument +) +{ + rtems_status_code status; + uint8_t index; + + Hard_Period = 250; + Hard_Execution = 25; + Hard_Priority = 15; + Soft_Period = 400; + Soft_Execution = 25; + Soft_Priority = 30; + + TEST_BEGIN(); + + status = rtems_barrier_create( + rtems_build_name('B','A','A',' '), + RTEMS_BARRIER_AUTOMATIC_RELEASE, + CONFIGURE_MAXIMUM_TASKS - 1, + &barrier_id + ); + + directive_failed( status , " ERROR Creating barrier \n"); + + + for( index = 0 ; index < CONFIGURE_MAXIMUM_TASKS - 1 ; index++ ) + { + char name = " " + ( index + 1); + rtems_task_priority priority; + + ( index > MAXIMUM_HARD_TASKS - 1 )?(priority=Soft_Priority):(priority=Hard_Priority); + + + Task_name[ index ] = rtems_build_name( 'H', 'R', name, ' '); + status = rtems_task_create( + Task_name[ index ], + priority, + RTEMS_MINIMUM_STACK_SIZE * 5, + RTEMS_DEFAULT_MODES, + RTEMS_DEFAULT_ATTRIBUTES, + &Task_id[index] + ); + directive_failed( status, "rtems_task_create loop" ); + } + + + + printf( "Init: Initializing the CBS\n" ); + if ( rtems_cbs_initialize() ) + printf( "ERROR: CBS INITIALIZATION FAILED\n" ); + params.deadline = 300; + params.budget = 90; + + + printf( "Periodic task: Create server and Attach thread\n" ); + if ( rtems_cbs_create_server( ¶ms, &server_id ) ) + printf("ERROR CREATE s1 \n"); + if ( rtems_cbs_create_server( ¶ms, &server_id2 ) ) + printf("ERROR CREATE s1 \n"); + + for( index = 0; index < CONFIGURE_MAXIMUM_TASKS - 1; index++ ) + { + rtems_task_entry entry_point; + + ( index > MAXIMUM_HARD_TASKS - 1 )?(entry_point = Soft_Task):(entry_point = Hard_Task); + + status = rtems_task_start( Task_id[ index ], entry_point, index + 1 ); + directive_failed( status, "rtems_task_start error \n"); + } + + rtems_task_wake_after( 2000 ); + + rtems_cbs_detach_thread( Task_id[7]); + rtems_cbs_detach_thread( Task_id[8]); + + if ( rtems_cbs_cleanup() ) + printf( "ERROR: CBS CLEANUP\n" ); + + + printf("Test Time in Nanoseconds as %"PRIu64" \n", rtems_clock_get_uptime_nanoseconds()); + + fflush(stdout); + TEST_END(); + rtems_test_exit( 0 ); +} diff --git a/testsuites/sptests/spcbssched04/soft_tasks.c b/testsuites/sptests/spcbssched04/soft_tasks.c new file mode 100644 index 0000000..300eb70 --- /dev/null +++ b/testsuites/sptests/spcbssched04/soft_tasks.c @@ -0,0 +1,85 @@ +/* Tasks_Periodic + * + * This routine serves as a test task for the CBS scheduler + * implementation. + * + * Input parameters: + * argument - task argument + * + * Output parameters: NONE + * + * 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 "system.h" + +rtems_task Soft_Task( + rtems_task_argument argument +) +{ + rtems_id rmid; + rtems_status_code status; + int start, stop, now; + + status = rtems_rate_monotonic_create( argument, &rmid ); + directive_failed( status, "rtems_rate_monotonic_create \n"); + + + if( argument > 6 ) + { + status = rtems_cbs_attach_thread( server_id2, rtems_task_self() ); + directive_failed( status, "rtems_attach_thread error \n"); + } + else + { + status = rtems_cbs_attach_thread( server_id, rtems_task_self() ); + directive_failed( status, "rtems_attach_thread error \n"); + } + + while ( FOREVER ) { + if ( rtems_rate_monotonic_period(rmid, Soft_Period) == RTEMS_TIMEOUT ) + printf( "P%" PRIdPTR " thread %d- Deadline miss time %"PRIu64" \n ", argument, rtems_task_self(), rtems_clock_get_uptime_nanoseconds() ); + + if( !sync_milestone[ argument - 1] ) + { + status = rtems_barrier_wait( + barrier_id, + RTEMS_WAIT + ); + directive_failed( status , "Barrier waiting failed "); + sync_milestone[ argument - 1] = true; + } + + start = rtems_clock_get_ticks_since_boot(); + printf( "P%" PRIdPTR "-S ticks:%d\n", argument, start ); + + + if( argument == 5 && ( start > 3 * Soft_Period ) ) + break; + + + /* active computing */ + while(FOREVER) + { + now = rtems_clock_get_ticks_since_boot(); + if ( now >= ( start + Soft_Execution ) ) + break; + } + stop = rtems_clock_get_ticks_since_boot(); + printf( "P%" PRIdPTR "-F ticks:%d\n", argument, stop ); + } + + rtems_cbs_detach_thread( Task_id[ 5 ] ); + rtems_cbs_detach_thread( rtems_task_self() ); + + status = rtems_rate_monotonic_delete( rmid ); + directive_failed( status, " ERROR Deleting RM \n"); + + rtems_task_exit(); +} diff --git a/testsuites/sptests/spcbssched04/spcbssched04.doc b/testsuites/sptests/spcbssched04/spcbssched04.doc new file mode 100644 index 0000000..147c350 --- /dev/null +++ b/testsuites/sptests/spcbssched04/spcbssched04.doc @@ -0,0 +1,20 @@ +# COPYRIGHT (c) 2019. +# Joel Pinto. +# Research Centre in Real-Time & Embedded Computing Systems (CISTER). +# +# 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. +# + + +This file describes the directives and concepts tested by this test set. + +test set name: spcbssched04 + +directives: + + +concepts: + + a. Verifies CBS Scheduling behavior. diff --git a/testsuites/sptests/spcbssched04/spcbssched04.scn b/testsuites/sptests/spcbssched04/spcbssched04.scn new file mode 100644 index 0000000..28a8f0c --- /dev/null +++ b/testsuites/sptests/spcbssched04/spcbssched04.scn @@ -0,0 +1,79 @@ +*** BEGIN OF TEST SPCBSSCHED 4 *** +*** TEST VERSION: 5.0.0.c6cb95fd585d692f32c8c2253f8487abc84f9cd6-modified +*** TEST STATE: EXPECTED-PASS +*** TEST BUILD: RTEMS_NETWORKING RTEMS_POSIX_API +*** TEST TOOLS: 7.4.0 20181206 (RTEMS 5, RSB 38241392a4f96dabf2d1aba51a43dcb623db4dfb, Newlib 1d35a003f) +Init: Initializing the CBS +Periodic task: Create server and Attach thread +Periodic task: Starting periodic behavior +Periodic task: Starting periodic behavior +Periodic task: Starting periodic behavior +Periodic task: Starting periodic behavior +P1-S ticks:2 +P1-F ticks:27 +P2-S ticks:27 +P2-F ticks:52 +P3-S ticks:52 +P3-F ticks:77 +P4-S ticks:77 +P4-F ticks:102 +P8-S ticks:102 +P8-F ticks:127 +P5-S ticks:127 +P5-F ticks:152 +P7-S ticks:152 +P7-F ticks:177 +P6-S ticks:177 +P6-F ticks:202 +P1-S ticks:251 +P1-F ticks:276 +P2-S ticks:276 +P2-F ticks:301 +P3-S ticks:301 +P3-F ticks:326 +P4-S ticks:326 +P4-F ticks:351 +P5-S ticks:402 +P5-F ticks:427 +P7-S ticks:427 +P7-F ticks:452 +P6-S ticks:452 +P8-S ticks:467 +P6-F ticks:482 +P8-F ticks:492 +P1-S ticks:501 +P1-F ticks:526 +P2-S ticks:526 +P2-F ticks:551 +P3-S ticks:551 +P3-F ticks:576 +P4-S ticks:576 +P4-F ticks:601 +P1-S ticks:751 +Gonna eliminate rms +P2-S ticks:751 +Gonna eliminate rms +P3-S ticks:752 +Gonna eliminate rms +P4-S ticks:752 +Gonna eliminate rms +P5-S ticks:802 +P5-F ticks:827 +P7-S ticks:827 +P7-F ticks:852 +P6-S ticks:852 +P6-F ticks:877 +P8-S ticks:877 +P8-F ticks:902 +P5-S ticks:1202 +P7-S ticks:1202 +P7-F ticks:1227 +P8-S ticks:1227 +P8-F ticks:1252 +P7-S ticks:1602 +P7-F ticks:1627 +P8-S ticks:1627 +P8-F ticks:1652 +Test Time in Nanoseconds as 40020016999 + +*** END OF TEST SPCBSSCHED 4 *** \ No newline at end of file diff --git a/testsuites/sptests/spcbssched04/system.h b/testsuites/sptests/spcbssched04/system.h new file mode 100644 index 0000000..22f4a49 --- /dev/null +++ b/testsuites/sptests/spcbssched04/system.h @@ -0,0 +1,80 @@ +/* system.h + * + * This include file contains information that is included in every + * function in the test set. + * + * COPYRIGHT (c) 1989-1999. + * 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. + */ +#include <tmacros.h> + +/* functions */ + +rtems_task Init( + rtems_task_argument argument +); + +rtems_task Hard_Task( + rtems_task_argument argument +); + +rtems_task Soft_Task( + rtems_task_argument argument +); +/* configuration information */ + +#define CONFIGURE_APPLICATION_NEEDS_SIMPLE_CONSOLE_DRIVER +#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER + +#define CONFIGURE_MICROSECONDS_PER_TICK 20000 + +#define MAXIMUM_HARD_TASKS 4 +#define MAXIMUM_SOFT_TASKS 4 +#define CONFIGURE_MAXIMUM_TASKS ( MAXIMUM_HARD_TASKS + MAXIMUM_SOFT_TASKS + 1 ) +#define CONFIGURE_MAXIMUM_PERIODS 8 +#define CONFIGURE_MAXIMUM_BARRIERS 1 + +#define CONFIGURE_INIT_TASK_PRIORITY 10 +#define CONFIGURE_INIT_TASK_INITIAL_MODES RTEMS_DEFAULT_MODES +#define CONFIGURE_INITIAL_EXTENSIONS RTEMS_TEST_INITIAL_EXTENSION + +#define CONFIGURE_RTEMS_INIT_TASKS_TABLE + +#define CONFIGURE_EXTRA_TASK_STACKS (20 * 4 * RTEMS_MINIMUM_STACK_SIZE) + +#define CONFIGURE_SCHEDULER_CBS + +#define CONFIGURE_CBS_MAXIMUM_SERVERS 2 + + + +#define CONFIGURE_DISABLE_SMP_CONFIGURATION + + +#include <rtems/rtems/clock.h> +#include <rtems/cbs.h> +#include <rtems/confdefs.h> + +/* global variables */ + +TEST_EXTERN rtems_id Task_id[ CONFIGURE_MAXIMUM_TASKS - 1 ], barrier_id; +TEST_EXTERN rtems_name Task_name[ CONFIGURE_MAXIMUM_TASKS - 1 ]; + +TEST_EXTERN bool sync_milestone[ CONFIGURE_MAXIMUM_TASKS - 1]; + +TEST_EXTERN rtems_task_priority Hard_Priority; +TEST_EXTERN rtems_task_priority Soft_Priority; + +TEST_EXTERN time_t Hard_Period; +TEST_EXTERN time_t Hard_Execution; +TEST_EXTERN time_t Soft_Period; +TEST_EXTERN time_t Soft_Execution; + +TEST_EXTERN rtems_cbs_server_id server_id, server_id2; +TEST_EXTERN rtems_cbs_parameters params; + +/* end of include file */ diff --git a/testsuites/sptests/spcbssched05/init.c b/testsuites/sptests/spcbssched05/init.c new file mode 100644 index 0000000..f8ef631 --- /dev/null +++ b/testsuites/sptests/spcbssched05/init.c @@ -0,0 +1,102 @@ +/* Init + * + * This routine is the initialization task for this test program. + * It is a user initialization task and has the responsibility for creating + * and starting the tasks that make up the test. If the time of day + * clock is required for the test, it should also be set to a known + * value by this function. + * + * Input parameters: + * argument - task argument + * + * Output parameters: NONE + * + * 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 + +#define CONFIGURE_INIT +#include "system.h" +#include <inttypes.h> + +const char rtems_test_name[] = "SPCBSSCHED 5"; + +rtems_task Init( + rtems_task_argument argument +) +{ + rtems_status_code status; + uint8_t index; + + Soft_Period = 250; + Soft_Execution = 40; + Soft_Priority = 30; + + TEST_BEGIN(); + + status = rtems_barrier_create( + rtems_build_name('B','A','A',' '), + RTEMS_BARRIER_AUTOMATIC_RELEASE, + CONFIGURE_MAXIMUM_TASKS - 1, + &barrier_id + ); + + directive_failed( status , " ERROR Creating barrier \n"); + + + for( index = 0 ; index < CONFIGURE_MAXIMUM_TASKS - 1 ; index++ ) + { + char name = " " + ( index + 1); + rtems_task_priority priority; + + Task_name[ index ] = rtems_build_name( 'H', 'R', name, ' '); + status = rtems_task_create( + Task_name[ index ], + Soft_Priority, + RTEMS_MINIMUM_STACK_SIZE * 5, + RTEMS_DEFAULT_MODES, + RTEMS_DEFAULT_ATTRIBUTES, + &Task_id[index] + ); + directive_failed( status, "rtems_task_create loop" ); + } + + + + printf( "Init: Initializing the CBS\n" ); + if ( rtems_cbs_initialize() ) + printf( "ERROR: CBS INITIALIZATION FAILED\n" ); + params.deadline = 250; + params.budget = 90; + + + printf( "Periodic task: Create server and Attach thread\n" ); + if ( rtems_cbs_create_server( ¶ms, &server_id ) ) + printf("ERROR CREATE s1 \n"); + + + for( index = 0; index < CONFIGURE_MAXIMUM_TASKS - 1; index++ ) + { + rtems_task_entry entry_point; + + status = rtems_task_start( Task_id[ index ], Soft_Task, index + 1 ); + directive_failed( status, "rtems_task_start error \n"); + } + + rtems_task_wake_after( 2000 ); + + if ( rtems_cbs_cleanup() ) + printf( "ERROR: CBS CLEANUP\n" ); + + + printf("Test Time in Nanoseconds as %"PRIu64" \n", rtems_clock_get_uptime_nanoseconds()); + + fflush(stdout); + TEST_END(); + rtems_test_exit( 0 ); +} diff --git a/testsuites/sptests/spcbssched05/soft_tasks.c b/testsuites/sptests/spcbssched05/soft_tasks.c new file mode 100644 index 0000000..a46eb47 --- /dev/null +++ b/testsuites/sptests/spcbssched05/soft_tasks.c @@ -0,0 +1,79 @@ +/* Tasks_Periodic + * + * This routine serves as a test task for the CBS scheduler + * implementation. + * + * Input parameters: + * argument - task argument + * + * Output parameters: NONE + * + * 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 "system.h" + +rtems_task Soft_Task( + rtems_task_argument argument +) +{ + rtems_id rmid; + rtems_status_code status; + int start, stop, now, index; + + status = rtems_rate_monotonic_create( argument, &rmid ); + directive_failed( status, "rtems_rate_monotonic_create \n"); + + + status = rtems_cbs_attach_thread( server_id, rtems_task_self() ); + directive_failed( status, "rtems_attach_thread error \n"); + printf("Soft period %"PRIu64" \n", Soft_Period ); + + while ( FOREVER ) { + if ( rtems_rate_monotonic_period(rmid, Soft_Period) == RTEMS_TIMEOUT ) + printf( "P%" PRIdPTR " thread %d- Deadline miss time %"PRIu64" \n ", argument, rtems_task_self(), rtems_clock_get_uptime_nanoseconds() ); + + if( !sync_milestone[ argument - 1] ) + { + printf("Waiting for bar \n "); + status = rtems_barrier_wait( + barrier_id, + RTEMS_WAIT + ); + directive_failed( status , "Barrier waiting failed "); + sync_milestone[ argument - 1] = true; + } + + start = rtems_clock_get_ticks_since_boot(); + printf( "P%" PRIdPTR "-S ticks:%d\n", argument, start ); + + + if( argument == 1 && ( start > 7 * Soft_Period ) ) + break; + + + /* active computing */ + while(FOREVER) + { + now = rtems_clock_get_ticks_since_boot(); + if ( now >= ( start + Soft_Execution ) ) + break; + } + stop = rtems_clock_get_ticks_since_boot(); + printf( "P%" PRIdPTR "-F ticks:%d\n", argument, stop ); + } + + for( index = 1; index < CONFIGURE_MAXIMUM_TASKS - 1; index++ ) { + rtems_cbs_detach_thread( index ); + } + + rtems_cbs_detach_thread( rtems_task_self() ); + + rtems_task_exit(); +} diff --git a/testsuites/sptests/spcbssched05/spcbssched05.doc b/testsuites/sptests/spcbssched05/spcbssched05.doc new file mode 100644 index 0000000..931e76e --- /dev/null +++ b/testsuites/sptests/spcbssched05/spcbssched05.doc @@ -0,0 +1,20 @@ +# COPYRIGHT (c) 2019. +# Joel Pinto. +# Research Centre in Real-Time & Embedded Computing Systems (CISTER). +# +# 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. +# + + +This file describes the directives and concepts tested by this test set. + +test set name: spcbssched05 + +directives: + + +concepts: + + a. Verifies CBS Scheduling behavior. diff --git a/testsuites/sptests/spcbssched05/spcbssched05.scn b/testsuites/sptests/spcbssched05/spcbssched05.scn new file mode 100644 index 0000000..f296fb1 --- /dev/null +++ b/testsuites/sptests/spcbssched05/spcbssched05.scn @@ -0,0 +1,82 @@ +*** BEGIN OF TEST SPCBSSCHED 5 *** +*** TEST VERSION: 5.0.0.c6cb95fd585d692f32c8c2253f8487abc84f9cd6-modified +*** TEST STATE: EXPECTED-PASS +*** TEST BUILD: RTEMS_NETWORKING RTEMS_POSIX_API +*** TEST TOOLS: 7.4.0 20181206 (RTEMS 5, RSB 38241392a4f96dabf2d1aba51a43dcb623db4dfb, Newlib 1d35a003f) +Init: Initializing the CBS +Periodic task: Create server and Attach thread + +P3-S ticks:2 +P3-F ticks:42 +P2-S ticks:42 +P2-F ticks:82 +P1-S ticks:82 +P1-F ticks:122 +P4-S ticks:122 +P4-F ticks:162 +P3-S ticks:251 +P3-F ticks:291 +P2-S ticks:291 +P2-F ticks:331 +P1-S ticks:331 +P1-F ticks:371 +P4-S ticks:371 +P4-F ticks:411 +P3-S ticks:501 +P3-F ticks:541 +P2-S ticks:541 +P2-F ticks:581 +P1-S ticks:581 +P1-F ticks:621 +P4-S ticks:621 +P4-F ticks:661 +P3-S ticks:751 +P3-F ticks:791 +P2-S ticks:791 +P2-F ticks:831 +P1-S ticks:831 +P1-F ticks:871 +P4-S ticks:871 +P4-F ticks:911 +P3-S ticks:1001 +P3-F ticks:1041 +P2-S ticks:1041 +P2-F ticks:1081 +P1-S ticks:1081 +P1-F ticks:1121 +P4-S ticks:1121 +P4-F ticks:1161 +P3-S ticks:1251 +P3-F ticks:1291 +P2-S ticks:1291 +P2-F ticks:1331 +P1-S ticks:1331 +P1-F ticks:1371 +P4-S ticks:1371 +P4-F ticks:1411 +P3-S ticks:1501 +P3-F ticks:1541 +P2-S ticks:1541 +P2-F ticks:1581 +P1-S ticks:1581 +P1-F ticks:1621 +P4-S ticks:1621 +P4-F ticks:1661 +P3-S ticks:1751 +P3-F ticks:1791 +P2-S ticks:1791 +P2-F ticks:1831 +P1-S ticks:1831 +P4-S ticks:1831 +P4-F ticks:1871 +P3-S ticks:2001 +P3-F ticks:2041 +P2-S ticks:2041 +P2-F ticks:2081 +P4-S ticks:2081 +P4-F ticks:2121 +Test Time in Nanoseconds as 42420008999 + +*** END OF TEST SPCBSSCHED 5 *** + + diff --git a/testsuites/sptests/spcbssched05/system.h b/testsuites/sptests/spcbssched05/system.h new file mode 100644 index 0000000..d482e7f --- /dev/null +++ b/testsuites/sptests/spcbssched05/system.h @@ -0,0 +1,75 @@ +/* system.h + * + * This include file contains information that is included in every + * function in the test set. + * + * COPYRIGHT (c) 1989-1999. + * 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. + */ +#include <tmacros.h> + +/* functions */ + +rtems_task Init( + rtems_task_argument argument +); + +rtems_task Hard_Task( + rtems_task_argument argument +); + +rtems_task Soft_Task( + rtems_task_argument argument +); +/* configuration information */ + +#define CONFIGURE_APPLICATION_NEEDS_SIMPLE_CONSOLE_DRIVER +#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER + +#define CONFIGURE_MICROSECONDS_PER_TICK 20000 + +#define CONFIGURE_MAXIMUM_TASKS 5 +#define CONFIGURE_MAXIMUM_PERIODS 4 +#define CONFIGURE_MAXIMUM_BARRIERS 1 + +#define CONFIGURE_INIT_TASK_PRIORITY 10 +#define CONFIGURE_INIT_TASK_INITIAL_MODES RTEMS_DEFAULT_MODES +#define CONFIGURE_INITIAL_EXTENSIONS RTEMS_TEST_INITIAL_EXTENSION + +#define CONFIGURE_RTEMS_INIT_TASKS_TABLE + +#define CONFIGURE_EXTRA_TASK_STACKS (20 * 4 * RTEMS_MINIMUM_STACK_SIZE) + +#define CONFIGURE_SCHEDULER_CBS + +#define CONFIGURE_CBS_MAXIMUM_SERVERS 1 + + + +#define CONFIGURE_DISABLE_SMP_CONFIGURATION + + +#include <rtems/rtems/clock.h> +#include <rtems/cbs.h> +#include <rtems/confdefs.h> + +/* global variables */ + +TEST_EXTERN rtems_id Task_id[ CONFIGURE_MAXIMUM_TASKS - 1 ], barrier_id; +TEST_EXTERN rtems_name Task_name[ CONFIGURE_MAXIMUM_TASKS - 1 ]; + +TEST_EXTERN bool sync_milestone[ CONFIGURE_MAXIMUM_TASKS - 1]; + +TEST_EXTERN rtems_task_priority Soft_Priority; + +TEST_EXTERN time_t Soft_Period; +TEST_EXTERN time_t Soft_Execution; + +TEST_EXTERN rtems_cbs_server_id server_id; +TEST_EXTERN rtems_cbs_parameters params; + +/* end of include file */ diff --git a/testsuites/sptests/spqreslib/init.c b/testsuites/sptests/spqreslib/init.c index 33e638b..15b07f0 100644 --- a/testsuites/sptests/spqreslib/init.c +++ b/testsuites/sptests/spqreslib/init.c @@ -102,14 +102,7 @@ rtems_task Init( if ( qres_attach_thread( server_id, 0, 1234 ) != QOS_E_INVALID_PARAM ) printf( "ERROR: ATTACH THREAD PASSED UNEXPECTEDLY\n" ); - if ( qres_attach_thread( server_id, 0, RTEMS_SELF ) ) - printf( "ERROR: ATTACH THREAD FAILED\n" ); - if ( qres_attach_thread( server_id, 0, RTEMS_SELF ) != - QOS_E_FULL ) - printf( "ERROR: ATTACH THREAD AGAIN PASSED UNEXPECTEDLY\n" ); - if ( qres_attach_thread( server_id, 0, Task_id ) != - QOS_E_FULL ) - printf( "ERROR: ATTACH THREAD TO FULL SERVER PASSED UNEXPECTEDLY \n" ); + if ( qres_destroy_server( server_id ) ) printf( "ERROR: DESTROY SERVER WITH THREAD ATTACHED FAILED\n" ); if ( qres_attach_thread( server_id, 0, RTEMS_SELF ) != @@ -119,16 +112,16 @@ rtems_task Init( printf( "Init: Detach thread\n" ); if ( qres_detach_thread( -5, 0, RTEMS_SELF ) != QOS_E_INVALID_PARAM ) - printf( "ERROR: DETACH THREAD PASSED UNEXPECTEDLY\n" ); + printf( "ERROR: DETACH THREAD PASSED UNEXPECTEDLY 1 \n" ); if ( qres_detach_thread( 5, 0, RTEMS_SELF ) != QOS_E_INVALID_PARAM ) - printf( "ERROR: DETACH THREAD PASSED UNEXPECTEDLY\n" ); + printf( "ERROR: DETACH THREAD PASSED UNEXPECTEDLY 2 \n" ); if ( qres_detach_thread( server_id2, 0, 1234 ) != QOS_E_INVALID_PARAM ) - printf( "ERROR: DETACH THREAD PASSED UNEXPECTEDLY \n" ); + printf( "ERROR: DETACH THREAD PASSED UNEXPECTEDLY 3 \n" ); if ( qres_detach_thread( server_id, 0, RTEMS_SELF ) != QOS_E_NOSERVER ) - printf( "ERROR: DETACH THREAD PASSED UNEXPECTEDLY4\n" ); + printf( "ERROR: DETACH THREAD PASSED UNEXPECTEDLY 4\n" ); qres_destroy_server( server_id2 ); /* Error checks for Set params and Get params */ @@ -190,18 +183,6 @@ rtems_task Init( QOS_E_NOSERVER ) printf( "ERROR: GET REMAINING BUDGET PASSED UNEXPECTEDLY\n" ); - /* Error checks for Get execution time */ - printf( "Init: Get execution time\n" ); - if ( qres_get_exec_time( -5, &exec_time, &abs_time ) != - QOS_E_INVALID_PARAM ) - printf( "ERROR: GET EXECUTION TIME PASSED UNEXPECTEDLY\n" ); - if ( qres_get_exec_time( 5, &exec_time, &abs_time ) != - QOS_E_INVALID_PARAM ) - printf( "ERROR: GET EXECUTION TIME PASSED UNEXPECTEDLY\n" ); - if ( qres_get_exec_time( server_id, &exec_time, &abs_time ) != - QOS_E_NOSERVER ) - printf( "ERROR: GET EXECUTION TIME PASSED UNEXPECTEDLY\n" ); - /* Restart QRES library */ printf( "Init: Cleaning up QRES\n" ); if ( qres_cleanup() ) diff --git a/testsuites/sptests/spqreslib/task_periodic.c b/testsuites/sptests/spqreslib/task_periodic.c index b219514..5e5be59 100644 --- a/testsuites/sptests/spqreslib/task_periodic.c +++ b/testsuites/sptests/spqreslib/task_periodic.c @@ -22,7 +22,7 @@ rtems_task Task_Periodic( rtems_id rmid; rtems_status_code status; - time_t approved_budget, exec_time, abs_time, current_budget; + time_t approved_budget, current_budget; int start, stop, now; @@ -49,25 +49,13 @@ rtems_task Task_Periodic( params.Q != tparams.Q ) printf( "ERROR: PARAMETERS MISMATCH\n" ); - printf( "Periodic task: Detach thread and Destroy server\n" ); - if ( qres_detach_thread( server_id, 0, Task_id ) ) - printf( "ERROR: DETACH THREAD FAILED\n" ); - if ( qres_destroy_server( server_id ) ) - printf( "ERROR: DESTROY SERVER FAILED\n" ); - if ( qres_create_server( ¶ms, &server_id ) ) - printf( "ERROR: CREATE SERVER FAILED\n" ); - printf( "Periodic task: Current budget and Execution time\n" ); if ( qres_get_curr_budget( server_id, ¤t_budget ) ) printf( "ERROR: GET REMAINING BUDGET FAILED\n" ); if ( current_budget != params.Q ) printf( "ERROR: REMAINING BUDGET MISMATCH\n" ); - if ( qres_get_exec_time( server_id, &exec_time, &abs_time ) ) - printf( "ERROR: GET EXECUTION TIME FAILED\n" ); - printf( "Periodic task: Set parameters\n" ); - if ( qres_attach_thread( server_id, 0, Task_id ) ) - printf( "ERROR: ATTACH THREAD FAILED\n" ); + params.P = Period * 2; params.Q = Execution * 2 +1; if ( qres_set_params( server_id, ¶ms ) ) @@ -107,28 +95,16 @@ rtems_task Task_Periodic( while(FOREVER) { now = rtems_clock_get_ticks_since_boot(); if ( now >= start + Execution ) break; - - if ( qres_get_exec_time( server_id, &exec_time, &abs_time ) ) - printf( "ERROR: GET EXECUTION TIME FAILED\n" ); - if ( qres_get_curr_budget( server_id, ¤t_budget) ) - printf( "ERROR: GET CURRENT BUDGET FAILED\n" ); - if ( (current_budget + exec_time) > (Execution + 1) ) { - printf( "ERROR: CURRENT BUDGET AND EXECUTION TIME MISMATCH\n" ); - rtems_test_exit( 0 ); - } } stop = rtems_clock_get_ticks_since_boot(); printf( "P%" PRIdPTR "-F ticks:%d\n", argument, stop ); } - /* delete period and SELF */ status = rtems_rate_monotonic_delete( rmid ); if ( status != RTEMS_SUCCESSFUL ) { printf("rtems_rate_monotonic_delete failed with status of %d.\n", status); rtems_test_exit( 0 ); } - if ( qres_cleanup() ) - printf( "ERROR: QRES CLEANUP\n" ); fflush(stdout); TEST_END(); -- 2.7.4 _______________________________________________ devel mailing list devel@rtems.org http://lists.rtems.org/mailman/listinfo/devel