diff options
23 files changed, 1361 insertions, 1 deletions
diff --git a/cpukit/ChangeLog b/cpukit/ChangeLog index 4e5423fb65..3db300ffb2 100644 --- a/cpukit/ChangeLog +++ b/cpukit/ChangeLog @@ -1,3 +1,30 @@ +2011-09-15 Petr Benes <benesp16@fel.cvut.cz> + + PR 1906/cpukit + * sapi/Makefile.am, sapi/preinstall.am, sapi/include/confdefs.h, + score/Makefile.am, score/preinstall.am: Add the CBS (Constant + Bandwidth Server) scheduler. This is a complex scheduling policy + built atop of the EDF scheduler. Unlike other schedulers, this one + provides a user API and handles not only deadlines of tasks but also + claimed budget per period. The main aim of the scheduler is isolation + of tasks so that each task is guaranteed to meet all deadlines + regardless of how other tasks behave. + * sapi/include/rtems/cbs.h, sapi/inline/rtems/cbs.inl, + score/include/rtems/score/schedulercbs.h, score/src/schedulercbs.c, + score/src/schedulercbsattachthread.c, + score/src/schedulercbscleanup.c, + score/src/schedulercbscreateserver.c, + score/src/schedulercbsdestroyserver.c, + score/src/schedulercbsdetachthread.c, + score/src/schedulercbsgetapprovedbudget.c, + score/src/schedulercbsgetexecutiontime.c, + score/src/schedulercbsgetparameters.c, + score/src/schedulercbsgetremainingbudget.c, + score/src/schedulercbsgetserverid.c, + score/src/schedulercbsreleasejob.c, + score/src/schedulercbssetparameters.c, + score/src/schedulercbsunblock.c: New files. + 2011-09-15 Sebastian Huber <sebastian.huber@embedded-brains.de> * cpukit/libmisc/cpuuse/cpuuse.h, diff --git a/cpukit/sapi/Makefile.am b/cpukit/sapi/Makefile.am index aadccf4b76..9b7ad53201 100644 --- a/cpukit/sapi/Makefile.am +++ b/cpukit/sapi/Makefile.am @@ -15,6 +15,7 @@ include_rtems_HEADERS += include/rtems/fatal.h include_rtems_HEADERS += include/rtems/init.h include_rtems_HEADERS += include/rtems/io.h include_rtems_HEADERS += include/rtems/mptables.h +include_rtems_HEADERS += include/rtems/cbs.h include_rtems_HEADERS += include/rtems/rbtree.h include_rtems_HEADERS += include/rtems/sptables.h @@ -22,6 +23,7 @@ EXTRA_DIST = include/rtems/README include_rtems_HEADERS += inline/rtems/chain.inl include_rtems_HEADERS += inline/rtems/extension.inl +include_rtems_HEADERS += inline/rtems/cbs.inl include_rtems_HEADERS += inline/rtems/rbtree.inl ## src diff --git a/cpukit/sapi/include/confdefs.h b/cpukit/sapi/include/confdefs.h index 2a9d75ac2c..a82dd00a87 100644 --- a/cpukit/sapi/include/confdefs.h +++ b/cpukit/sapi/include/confdefs.h @@ -574,6 +574,7 @@ rtems_fs_init_functions_t rtems_fs_init_helper = * CONFIGURE_SCHEDULER_SIMPLE - Light-weight Priority Scheduler * CONFIGURE_SCHEDULER_SIMPLE_SMP - Simple SMP Priority Scheduler * CONFIGURE_SCHEDULER_EDF - EDF Scheduler + * CONFIGURE_SCHEDULER_CBS - CBS Scheduler * * If no configuration is specified by the application, then * CONFIGURE_SCHEDULER_PRIORITY is assumed to be the default. @@ -600,7 +601,8 @@ rtems_fs_init_functions_t rtems_fs_init_helper = !defined(CONFIGURE_SCHEDULER_PRIORITY) && \ !defined(CONFIGURE_SCHEDULER_SIMPLE) && \ !defined(CONFIGURE_SCHEDULER_SIMPLE_SMP) && \ - !defined(CONFIGURE_SCHEDULER_EDF) + !defined(CONFIGURE_SCHEDULER_EDF) && \ + !defined(CONFIGURE_SCHEDULER_CBS) #if defined(RTEMS_SMP) && defined(CONFIGURE_SMP_APPLICATION) #define CONFIGURE_SCHEDULER_SIMPLE_SMP #else @@ -676,6 +678,31 @@ rtems_fs_init_functions_t rtems_fs_init_helper = _Configure_From_workspace(sizeof(Scheduler_EDF_Per_thread))) #endif +/* + * If the CBS Scheduler is selected, then configure for it. + */ +#if defined(CONFIGURE_SCHEDULER_CBS) + #include <rtems/score/schedulercbs.h> + #define CONFIGURE_SCHEDULER_ENTRY_POINTS SCHEDULER_CBS_ENTRY_POINTS + + #ifndef CONFIGURE_CBS_MAXIMUM_SERVERS + #define CONFIGURE_CBS_MAXIMUM_SERVERS CONFIGURE_MAXIMUM_TASKS + #endif + + #ifdef CONFIGURE_INIT + uint32_t _Scheduler_CBS_Maximum_servers = CONFIGURE_CBS_MAXIMUM_SERVERS; + #endif + + /** + * define the memory used by the CBS scheduler + */ + #define CONFIGURE_MEMORY_FOR_SCHEDULER ( \ + _Configure_From_workspace((sizeof(Scheduler_CBS_Server) + \ + sizeof(Scheduler_CBS_Server*)) * CONFIGURE_CBS_MAXIMUM_SERVERS)) + #define CONFIGURE_MEMORY_PER_TASK_FOR_SCHEDULER ( \ + _Configure_From_workspace(sizeof(Scheduler_CBS_Per_thread))) +#endif + #if defined(CONFIGURE_SCHEDULER_USER) #define CONFIGURE_SCHEDULER_ENTRY_POINTS \ CONFIGURE_SCHEDULER_USER_ENTRY_POINTS diff --git a/cpukit/sapi/include/rtems/cbs.h b/cpukit/sapi/include/rtems/cbs.h new file mode 100644 index 0000000000..d016e5cdec --- /dev/null +++ b/cpukit/sapi/include/rtems/cbs.h @@ -0,0 +1,65 @@ +/** + * @file rtems/cbs.h + * + * This include file contains all the constants and structures associated + * with the CBS library in RTEMS. + */ + +/* + * 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.com/license/LICENSE. + * + * $Id$ + */ + +#ifndef CONFIGURE_SCHEDULER_CBS + #error "cbs.h available only with CONFIGURE_SCHEDULER_CBS" +#endif + +#ifndef _RTEMS_CBS_H +#define _RTEMS_CBS_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include <stdint.h> +#include <rtems/score/schedulercbs.h> + +/* Return codes. */ +#define RTEMS_CBS_OK SCHEDULER_CBS_OK +#define RTEMS_CBS_ERROR_GENERIC SCHEDULER_CBS_ERROR_GENERIC +#define RTEMS_CBS_ERROR_NO_MEMORY SCHEDULER_CBS_ERROR_NO_MEMORY +#define RTEMS_CBS_ERROR_INVALID_PARAMETER SCHEDULER_CBS_ERROR_INVALID_PARAM +#define RTEMS_CBS_ERROR_UNAUTHORIZED SCHEDULER_CBS_ERROR_UNAUTHORIZED +#define RTEMS_CBS_ERROR_UNIMPLEMENTED SCHEDULER_CBS_ERROR_UNIMPLEMENTED +#define RTEMS_CBS_ERROR_MISSING_COMPONENT SCHEDULER_CBS_ERROR_MISSING_COMPONENT +#define RTEMS_CBS_ERROR_INCONSISTENT_STATE SCHEDULER_CBS_ERROR_INCONSISTENT_STATE +#define RTEMS_CBS_ERROR_SYSTEM_OVERLOAD SCHEDULER_CBS_ERROR_SYSTEM_OVERLOAD +#define RTEMS_CBS_ERROR_INTERNAL_ERROR SCHEDULER_CBS_ERROR_INTERNAL_ERROR +#define RTEMS_CBS_ERROR_NOT_FOUND SCHEDULER_CBS_ERROR_NOT_FOUND +#define RTEMS_CBS_ERROR_FULL SCHEDULER_CBS_ERROR_FULL +#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; + +/** Server parameters. */ +typedef Scheduler_CBS_Parameters rtems_cbs_parameters; + +#include <rtems/cbs.inl> + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include file */ diff --git a/cpukit/sapi/inline/rtems/cbs.inl b/cpukit/sapi/inline/rtems/cbs.inl new file mode 100644 index 0000000000..451d8cbc04 --- /dev/null +++ b/cpukit/sapi/inline/rtems/cbs.inl @@ -0,0 +1,205 @@ +/** + * @file cbs.inl + * + * This include file contains all the constants and structures associated + * with the CBS library. + * + */ + +/* + * 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.com/license/LICENSE. + * + * $Id$ + */ + +#ifndef _RTEMS_CBS_H +# error "Never use <rtems/cbs.inl> directly; include <rtems/cbs.h> instead." +#endif + +#include <rtems/score/schedulercbs.h> + +/** + * @brief rtems cbs init + * + * Initializes the CBS library. + * + * @return status code. + */ +RTEMS_INLINE_ROUTINE int rtems_cbs_initialize ( void ) +{ + return _Scheduler_CBS_Initialize(); +} + +/** + * @brief rtems cbs cleanup + * + * Cleanup resources associated to the CBS Library. + * + * @return status code. + */ +RTEMS_INLINE_ROUTINE int rtems_cbs_cleanup ( void ) +{ + return _Scheduler_CBS_Cleanup(); +} + +/** + * @brief rtems cbs create server + * + * Create a new server with specified parameters. + * + * @return status code. + */ +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 + ); +} + +/** + * @brief rtems cbs attach thread + * + * Attach a task to an already existing server. + * + * @return status code. + */ +RTEMS_INLINE_ROUTINE int rtems_cbs_attach_thread ( + rtems_cbs_server_id server_id, + rtems_id task_id +) +{ + return _Scheduler_CBS_Attach_thread( server_id, task_id ); +} + +/** + * @brief rtems cbs detach thread + * + * Detach from the CBS Server. + * + * @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 ); +} + +/** + * @brief rtems cbs destroy server + * + * Detach all tasks from a server and destroy it. + * + * @return status code. + */ +RTEMS_INLINE_ROUTINE int rtems_cbs_destroy_server ( + rtems_cbs_server_id server_id +) +{ + return _Scheduler_CBS_Destroy_server( server_id ); +} + +/** + * @brief rtems cbs get server id + * + * Get a thread server id, or RTEMS_CBS_E_NOT_FOUND if it is not + * attached to any server. + * + * @return status code. + */ +RTEMS_INLINE_ROUTINE int rtems_cbs_get_server_id ( + rtems_id task_id, + rtems_cbs_server_id *server_id +) +{ + return _Scheduler_CBS_Get_server_id( task_id, server_id ); +} + +/** + * @brief rtems cbs get parameters + * + * Retrieve CBS scheduling parameters. + * + * @return status code. + */ +RTEMS_INLINE_ROUTINE int rtems_cbs_get_parameters ( + rtems_cbs_server_id server_id, + rtems_cbs_parameters *params +) +{ + return _Scheduler_CBS_Get_parameters( server_id, params ); +} + +/** + * @brief rtems cbs set parameters + * + * Change CBS scheduling parameters. + * + * @return status code. + */ +RTEMS_INLINE_ROUTINE int rtems_cbs_set_parameters ( + rtems_cbs_server_id server_id, + rtems_cbs_parameters *params +) +{ + return _Scheduler_CBS_Set_parameters( server_id, params ); +} + +/** + * @brief rtems 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 rtems cbs get remaining budget + * + * Retrieve remaining budget for the current server instance. + * + * @return status code. + */ +RTEMS_INLINE_ROUTINE int rtems_cbs_get_remaining_budget ( + rtems_cbs_server_id server_id, + time_t *remaining_budget +) +{ + return _Scheduler_CBS_Get_remaining_budget( server_id, remaining_budget ); +} + +/** + * @brief rtems cbs get approved budget + * + * Retrieve the budget that has been approved for the subsequent + * server instances. + * + * @return status code. + */ +RTEMS_INLINE_ROUTINE int rtems_cbs_get_approved_budget ( + rtems_cbs_server_id server_id, + time_t *appr_budget +) +{ + return _Scheduler_CBS_Get_approved_budget( server_id, appr_budget ); +} diff --git a/cpukit/sapi/preinstall.am b/cpukit/sapi/preinstall.am index f49f81427c..5ce9966786 100644 --- a/cpukit/sapi/preinstall.am +++ b/cpukit/sapi/preinstall.am @@ -60,6 +60,10 @@ $(PROJECT_INCLUDE)/rtems/mptables.h: include/rtems/mptables.h $(PROJECT_INCLUDE) $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/mptables.h PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/mptables.h +$(PROJECT_INCLUDE)/rtems/cbs.h: include/rtems/cbs.h $(PROJECT_INCLUDE)/rtems/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/cbs.h +PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/cbs.h + $(PROJECT_INCLUDE)/rtems/rbtree.h: include/rtems/rbtree.h $(PROJECT_INCLUDE)/rtems/$(dirstamp) $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/rbtree.h PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/rbtree.h @@ -76,6 +80,10 @@ $(PROJECT_INCLUDE)/rtems/extension.inl: inline/rtems/extension.inl $(PROJECT_INC $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/extension.inl PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/extension.inl +$(PROJECT_INCLUDE)/rtems/cbs.inl: inline/rtems/cbs.inl $(PROJECT_INCLUDE)/rtems/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/cbs.inl +PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/cbs.inl + $(PROJECT_INCLUDE)/rtems/rbtree.inl: inline/rtems/rbtree.inl $(PROJECT_INCLUDE)/rtems/$(dirstamp) $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/rbtree.inl PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/rbtree.inl diff --git a/cpukit/score/Makefile.am b/cpukit/score/Makefile.am index d05ccfdb81..44a0df4c4f 100644 --- a/cpukit/score/Makefile.am +++ b/cpukit/score/Makefile.am @@ -40,6 +40,7 @@ include_rtems_score_HEADERS += include/rtems/score/priority.h include_rtems_score_HEADERS += include/rtems/score/prioritybitmap.h include_rtems_score_HEADERS += include/rtems/score/rbtree.h include_rtems_score_HEADERS += include/rtems/score/scheduler.h +include_rtems_score_HEADERS += include/rtems/score/schedulercbs.h include_rtems_score_HEADERS += include/rtems/score/scheduleredf.h include_rtems_score_HEADERS += include/rtems/score/schedulerpriority.h include_rtems_score_HEADERS += include/rtems/score/schedulersimple.h @@ -238,6 +239,22 @@ libscore_a_SOURCES += src/scheduleredf.c \ src/scheduleredfupdate.c \ src/scheduleredfyield.c +## SCHEDULERCBS_C_FILES +libscore_a_SOURCES += src/schedulercbs.c \ + src/schedulercbsattachthread.c \ + src/schedulercbscleanup.c \ + src/schedulercbscreateserver.c \ + src/schedulercbsdestroyserver.c \ + src/schedulercbsdetachthread.c \ + src/schedulercbsgetapprovedbudget.c \ + src/schedulercbsgetexecutiontime.c \ + src/schedulercbsgetparameters.c \ + src/schedulercbsgetremainingbudget.c \ + src/schedulercbsgetserverid.c \ + src/schedulercbssetparameters.c \ + src/schedulercbsreleasejob.c \ + src/schedulercbsunblock.c + ## PROTECTED_HEAP_C_FILES libscore_a_SOURCES += src/pheapallocate.c \ src/pheapextend.c src/pheapfree.c src/pheapgetsize.c \ diff --git a/cpukit/score/include/rtems/score/schedulercbs.h b/cpukit/score/include/rtems/score/schedulercbs.h new file mode 100644 index 0000000000..4cc00a65de --- /dev/null +++ b/cpukit/score/include/rtems/score/schedulercbs.h @@ -0,0 +1,327 @@ +/** + * @file rtems/score/schedulercbs.h + * + * 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). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#ifndef _RTEMS_SCORE_SCHEDULERCBS_H +#define _RTEMS_SCORE_SCHEDULERCBS_H + +#include <rtems/score/chain.h> +#include <rtems/score/priority.h> +#include <rtems/score/scheduler.h> +#include <rtems/score/rbtree.h> +#include <rtems/score/scheduleredf.h> +#include <rtems/rtems/signal.h> +#include <rtems/rtems/timer.h> +#include <rtems/score/thread.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @addtogroup ScoreScheduler + * + */ +/**@{*/ + +/** + * Entry points for the Constant Bandwidth Server Scheduler. + * + * @note: The CBS scheduler is an enhancement of EDF scheduler, + * therefor some routines are similar. + */ +#define SCHEDULER_CBS_ENTRY_POINTS \ + { \ + _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_Unblock, /* unblock entry point */ \ + _Scheduler_EDF_Allocate, /* allocate entry point */ \ + _Scheduler_EDF_Free, /* free entry point */ \ + _Scheduler_EDF_Update, /* update entry point */ \ + _Scheduler_EDF_Enqueue, /* enqueue entry point */ \ + _Scheduler_EDF_Enqueue_first, /* enqueue_first entry point */ \ + _Scheduler_EDF_Extract, /* extract entry point */ \ + _Scheduler_EDF_Priority_compare, /* compares two priorities */ \ + _Scheduler_CBS_Release_job, /* new period of task */ \ + _Scheduler_priority_Tick /* tick entry point */ \ + } + +/* Return values for CBS server. */ +#define SCHEDULER_CBS_OK 0 +#define SCHEDULER_CBS_ERROR_GENERIC -16 +#define SCHEDULER_CBS_ERROR_NO_MEMORY -17 +#define SCHEDULER_CBS_ERROR_INVALID_PARAMETER -18 +#define SCHEDULER_CBS_ERROR_UNAUTHORIZED -19 +#define SCHEDULER_CBS_ERROR_UNIMPLEMENTED -20 +#define SCHEDULER_CBS_ERROR_MISSING_COMPONENT -21 +#define SCHEDULER_CBS_ERROR_INCONSISTENT_STATE -22 +#define SCHEDULER_CBS_ERROR_SYSTEM_OVERLOAD -23 +#define SCHEDULER_CBS_ERROR_INTERNAL_ERROR -24 +#define SCHEDULER_CBS_ERROR_NOT_FOUND -25 +#define SCHEDULER_CBS_ERROR_FULL -26 +#define SCHEDULER_CBS_ERROR_EMPTY -27 +#define SCHEDULER_CBS_ERROR_NOSERVER SCHEDULER_CBS_ERROR_NOT_FOUND + +/** Maximum number of simultaneous servers. */ +extern 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. + */ +typedef struct { + /** Relative deadline of the server. */ + time_t deadline; + /** Budget (computation time) of the server. */ + time_t budget; +} Scheduler_CBS_Parameters; + +/** + * This structure represents a time server. + */ +typedef struct { + /** + * Task id. + * + * @note: The current implementation of CBS handles only one task per server. + */ + rtems_id task_id; + /** Server paramenters. */ + Scheduler_CBS_Parameters parameters; + /** Callback function invoked when a budget overrun occurs. */ + Scheduler_CBS_Budget_overrun cbs_budget_overrun; +} Scheduler_CBS_Server; + +/** + * This structure handles CBS specific data of a thread. + */ +typedef struct { + /** EDF scheduler specific data of a task. */ + Scheduler_EDF_Per_thread edf_per_thread; + /** CBS server specific data of a task. */ + Scheduler_CBS_Server *cbs_server; +} Scheduler_CBS_Per_thread; + + +/** + * List of servers. The @a Scheduler_CBS_Server is the index to the array + * of pointers to @a _Scheduler_CBS_Server_list. + */ +Scheduler_CBS_Server **_Scheduler_CBS_Server_list; + +/** + * @brief Scheduler CBS Unblock + * + * This routine adds @a the_thread to the scheduling decision, that is, + * adds it to the ready queue and updates any appropriate scheduling + * variables, for example the heir thread. + * + * It is checked whether the remaining budget is sufficient. If not, the + * thread continues as a new job in order to protect concurrent threads. + * + * @note This has to be asessed as missed deadline of the current job. + * + * @param[in] the_thread will be unblocked. + */ +void _Scheduler_CBS_Unblock( + Thread_Control *the_thread +); + +/** + * @brief Scheduler CBS Release job + * + * This routine is called when a new job of task is released. + * It is called only from Rate Monotonic manager in the beginning + * of new period. Deadline has to be shifted and budget replenished. + * + * @param[in] the_thread is the owner of the job. + * @param[in] length of the new job from now. If equal to 0, + * the job was cancelled or deleted. + */ + +void _Scheduler_CBS_Release_job ( + Thread_Control *the_thread, + uint32_t length +); + +/** + * @brief _Scheduler_CBS_Initialize + * + * Initializes the CBS library. + * + * @return status code. + */ +int _Scheduler_CBS_Initialize(void); + +/** + * @brief _Scheduler_CBS_Attach_thread + * + * Attach a task to an already existing server. + * + * @return status code. + */ +int _Scheduler_CBS_Attach_thread ( + Scheduler_CBS_Server_id server_id, + rtems_id task_id +); + +/** + * @brief _Scheduler_CBS_Detach_thread + * + * Detach from the CBS Server. + * + * @return status code. + */ +int _Scheduler_CBS_Detach_thread ( + Scheduler_CBS_Server_id server_id, + rtems_id task_id +); + +/** + * @brief _Scheduler_CBS_Cleanup + * + * Cleanup resources associated to the CBS Library. + * + * @return status code. + */ +int _Scheduler_CBS_Cleanup (void); + +/** + * @brief _Scheduler_CBS_Create_server + * + * Create a new server with specified parameters. + * + * @return status code. + */ +int _Scheduler_CBS_Create_server ( + Scheduler_CBS_Parameters *params, + Scheduler_CBS_Budget_overrun budget_overrun_callback, + rtems_id *server_id +); + +/** + * @brief _Scheduler_CBS_Destroy_server + * + * Detach all tasks from a server and destroy it. + * + * @return status code. + */ +int _Scheduler_CBS_Destroy_server ( + Scheduler_CBS_Server_id server_id +); + +/** + * @brief _Scheduler_CBS_Get_approved_budget + * + * Retrieve the budget that has been approved for the subsequent + * server instances. + * + * @return status code. + */ +int _Scheduler_CBS_Get_approved_budget ( + Scheduler_CBS_Server_id server_id, + time_t *approved_budget +); + +/** + * @brief _Scheduler_CBS_Get_remaining_budget + * + * Retrieve remaining budget for the current server instance. + * + * @return status code. + */ +int _Scheduler_CBS_Get_remaining_budget ( + Scheduler_CBS_Server_id server_id, + time_t *remaining_budget +); + +/** + * @brief _Scheduler_CBS_Get_execution_time + * + * Retrieve time info relative to the current server. + * + * @return status code. + */ +int _Scheduler_CBS_Get_execution_time ( + Scheduler_CBS_Server_id server_id, + time_t *exec_time, + time_t *abs_time +); + +/** + * @brief _Scheduler_CBS_Get_parameters + * + * Retrieve CBS scheduling parameters. + * + * @return status code. + */ +int _Scheduler_CBS_Get_parameters ( + Scheduler_CBS_Server_id server_id, + Scheduler_CBS_Parameters *params +); + +/** + * @brief _Scheduler_CBS_Get_server_id + * + * Get a thread server id, or SCHEDULER_CBS_ERROR_NOT_FOUND if it is not + * attached to any server. + * + * @return status code. + */ +int _Scheduler_CBS_Get_server_id ( + rtems_id task_id, + Scheduler_CBS_Server_id *server_id +); + +/** + * @brief _Scheduler_CBS_Set_parameters + * + * Change CBS scheduling parameters. + * + * @return status code. + */ +int _Scheduler_CBS_Set_parameters ( + Scheduler_CBS_Server_id server_id, + Scheduler_CBS_Parameters *parameters +); + +/** + * @brief Scheduler CBS Budget overrun + * + * This routine is invoked when a limited time quantum is exceeded. + */ +void _Scheduler_CBS_Budget_callout( + Thread_Control *the_thread +); + +#ifdef __cplusplus +} +#endif + +/**@}*/ + +#endif +/* end of include file */ diff --git a/cpukit/score/preinstall.am b/cpukit/score/preinstall.am index 0461648517..09c6fa93ac 100644 --- a/cpukit/score/preinstall.am +++ b/cpukit/score/preinstall.am @@ -127,6 +127,10 @@ $(PROJECT_INCLUDE)/rtems/score/scheduler.h: include/rtems/score/scheduler.h $(PR $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/scheduler.h PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/scheduler.h +$(PROJECT_INCLUDE)/rtems/score/schedulercbs.h: include/rtems/score/schedulercbs.h $(PROJECT_INCLUDE)/rtems/score/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/schedulercbs.h +PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/schedulercbs.h + $(PROJECT_INCLUDE)/rtems/score/scheduleredf.h: include/rtems/score/scheduleredf.h $(PROJECT_INCLUDE)/rtems/score/$(dirstamp) $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/scheduleredf.h PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/scheduleredf.h diff --git a/cpukit/score/src/schedulercbs.c b/cpukit/score/src/schedulercbs.c new file mode 100644 index 0000000000..dba4925b8d --- /dev/null +++ b/cpukit/score/src/schedulercbs.c @@ -0,0 +1,59 @@ +/* + * 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.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/system.h> +#include <rtems/config.h> +#include <rtems/score/scheduler.h> +#include <rtems/score/schedulercbs.h> +#include <rtems/rtems/signal.h> + +void _Scheduler_CBS_Budget_callout( + Thread_Control *the_thread +) +{ + Priority_Control new_priority; + Scheduler_CBS_Per_thread *sched_info; + Scheduler_CBS_Server_id server_id; + + /* Put violating task to background until the end of period. */ + new_priority = the_thread->Start.initial_priority; + if ( the_thread->real_priority != new_priority ) + the_thread->real_priority = new_priority; + if ( the_thread->current_priority != new_priority ) + _Thread_Change_priority(the_thread, new_priority, true); + + /* Invoke callback function if any. */ + sched_info = (Scheduler_CBS_Per_thread *) the_thread->scheduler_info; + if ( sched_info->cbs_server->cbs_budget_overrun ) { + _Scheduler_CBS_Get_server_id( + sched_info->cbs_server->task_id, + &server_id + ); + sched_info->cbs_server->cbs_budget_overrun( server_id ); + } +} + +int _Scheduler_CBS_Initialize(void) +{ + unsigned int i; + _Scheduler_CBS_Server_list = (Scheduler_CBS_Server **) _Workspace_Allocate( + _Scheduler_CBS_Maximum_servers * sizeof(Scheduler_CBS_Server*) ); + if ( !_Scheduler_CBS_Server_list ) + return SCHEDULER_CBS_ERROR_NO_MEMORY; + for (i = 0; i<_Scheduler_CBS_Maximum_servers; i++) { + _Scheduler_CBS_Server_list[i] = NULL; + } + return SCHEDULER_CBS_OK; +} diff --git a/cpukit/score/src/schedulercbsattachthread.c b/cpukit/score/src/schedulercbsattachthread.c new file mode 100644 index 0000000000..7796f12a6b --- /dev/null +++ b/cpukit/score/src/schedulercbsattachthread.c @@ -0,0 +1,63 @@ +/* + * 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.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/system.h> +#include <rtems/config.h> +#include <rtems/score/scheduler.h> +#include <rtems/score/schedulercbs.h> +#include <rtems/rtems/object.h> + +int _Scheduler_CBS_Attach_thread ( + Scheduler_CBS_Server_id server_id, + rtems_id task_id +) +{ + Objects_Locations location; + Thread_Control *the_thread; + Scheduler_CBS_Per_thread *sched_info; + + if ( server_id < 0 || server_id >= _Scheduler_CBS_Maximum_servers ) + return SCHEDULER_CBS_ERROR_INVALID_PARAMETER; + + the_thread = _Thread_Get(task_id, &location); + /* The routine _Thread_Get may disable dispatch and not enable again. */ + if ( the_thread ) + _Thread_Enable_dispatch(); + if ( !the_thread ) + return SCHEDULER_CBS_ERROR_INVALID_PARAMETER; + + sched_info = (Scheduler_CBS_Per_thread *) the_thread->scheduler_info; + + /* Thread is already attached to a server. */ + if ( sched_info->cbs_server ) + return SCHEDULER_CBS_ERROR_FULL; + + /* Server is not valid. */ + if ( !_Scheduler_CBS_Server_list[server_id] ) + return SCHEDULER_CBS_ERROR_NOSERVER; + + /* Server is already attached to a thread. */ + if ( _Scheduler_CBS_Server_list[server_id]->task_id != -1 ) + return SCHEDULER_CBS_ERROR_FULL; + + _Scheduler_CBS_Server_list[server_id]->task_id = task_id; + sched_info->cbs_server = (void *) _Scheduler_CBS_Server_list[server_id]; + + the_thread->budget_callout = _Scheduler_CBS_Budget_callout; + the_thread->budget_algorithm = THREAD_CPU_BUDGET_ALGORITHM_CALLOUT; + the_thread->is_preemptible = true; + + return SCHEDULER_CBS_OK; +} diff --git a/cpukit/score/src/schedulercbscleanup.c b/cpukit/score/src/schedulercbscleanup.c new file mode 100644 index 0000000000..c6c0b94129 --- /dev/null +++ b/cpukit/score/src/schedulercbscleanup.c @@ -0,0 +1,31 @@ +/* + * 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.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/system.h> +#include <rtems/config.h> +#include <rtems/score/scheduler.h> +#include <rtems/score/schedulercbs.h> + +int _Scheduler_CBS_Cleanup (void) +{ + unsigned int i; + + for ( i = 0; i<_Scheduler_CBS_Maximum_servers; i++ ) { + if ( _Scheduler_CBS_Server_list[ i ] ) + _Scheduler_CBS_Destroy_server( i ); + } + _Workspace_Free( _Scheduler_CBS_Server_list ); + return SCHEDULER_CBS_OK; +} diff --git a/cpukit/score/src/schedulercbscreateserver.c b/cpukit/score/src/schedulercbscreateserver.c new file mode 100644 index 0000000000..c604423d50 --- /dev/null +++ b/cpukit/score/src/schedulercbscreateserver.c @@ -0,0 +1,55 @@ +/* + * 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.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/system.h> +#include <rtems/config.h> +#include <rtems/score/scheduler.h> +#include <rtems/score/schedulercbs.h> + +int _Scheduler_CBS_Create_server ( + Scheduler_CBS_Parameters *params, + Scheduler_CBS_Budget_overrun budget_overrun_callback, + rtems_id *server_id +) +{ + unsigned int i; + Scheduler_CBS_Server *the_server; + + if ( params->budget <= 0 || + params->deadline <= 0 || + params->budget >= SCHEDULER_EDF_PRIO_MSB || + params->deadline >= SCHEDULER_EDF_PRIO_MSB ) + return SCHEDULER_CBS_ERROR_INVALID_PARAMETER; + + for ( i = 0; i<_Scheduler_CBS_Maximum_servers; i++ ) { + if ( !_Scheduler_CBS_Server_list[i] ) + break; + } + + if ( i == _Scheduler_CBS_Maximum_servers ) + return SCHEDULER_CBS_ERROR_FULL; + + *server_id = i; + _Scheduler_CBS_Server_list[*server_id] = (Scheduler_CBS_Server *) + _Workspace_Allocate( sizeof(Scheduler_CBS_Server) ); + the_server = _Scheduler_CBS_Server_list[*server_id]; + if ( !the_server ) + return SCHEDULER_CBS_ERROR_NO_MEMORY; + + the_server->parameters = *params; + the_server->task_id = -1; + the_server->cbs_budget_overrun = budget_overrun_callback; + return SCHEDULER_CBS_OK; +} diff --git a/cpukit/score/src/schedulercbsdestroyserver.c b/cpukit/score/src/schedulercbsdestroyserver.c new file mode 100644 index 0000000000..85867cf7dc --- /dev/null +++ b/cpukit/score/src/schedulercbsdestroyserver.c @@ -0,0 +1,40 @@ +/* + * 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.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/system.h> +#include <rtems/config.h> +#include <rtems/score/scheduler.h> +#include <rtems/score/schedulercbs.h> + +int _Scheduler_CBS_Destroy_server ( + Scheduler_CBS_Server_id server_id +) +{ + int ret = SCHEDULER_CBS_OK; + rtems_id tid; + + if ( server_id < 0 || server_id >= _Scheduler_CBS_Maximum_servers ) + return SCHEDULER_CBS_ERROR_INVALID_PARAMETER; + + if ( !_Scheduler_CBS_Server_list[server_id] ) + return SCHEDULER_CBS_ERROR_NOSERVER; + + if ( (tid = _Scheduler_CBS_Server_list[server_id]->task_id) != -1 ) + ret = _Scheduler_CBS_Detach_thread ( server_id, tid ); + + _Workspace_Free( _Scheduler_CBS_Server_list[server_id] ); + _Scheduler_CBS_Server_list[server_id] = NULL; + return ret; +} diff --git a/cpukit/score/src/schedulercbsdetachthread.c b/cpukit/score/src/schedulercbsdetachthread.c new file mode 100644 index 0000000000..65aa88dd8f --- /dev/null +++ b/cpukit/score/src/schedulercbsdetachthread.c @@ -0,0 +1,56 @@ +/* + * 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.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/system.h> +#include <rtems/config.h> +#include <rtems/score/scheduler.h> +#include <rtems/score/schedulercbs.h> + +int _Scheduler_CBS_Detach_thread ( + Scheduler_CBS_Server_id server_id, + rtems_id task_id +) +{ + Objects_Locations location; + Thread_Control *the_thread; + Scheduler_CBS_Per_thread *sched_info; + + the_thread = _Thread_Get(task_id, &location); + /* The routine _Thread_Get may disable dispatch and not enable again. */ + if ( the_thread ) { + _Thread_Enable_dispatch(); + sched_info = (Scheduler_CBS_Per_thread *) the_thread->scheduler_info; + } + + if ( server_id < 0 || server_id >= _Scheduler_CBS_Maximum_servers ) + return SCHEDULER_CBS_ERROR_INVALID_PARAMETER; + if ( !the_thread ) + return SCHEDULER_CBS_ERROR_INVALID_PARAMETER; + /* Server is not valid. */ + if ( !_Scheduler_CBS_Server_list[server_id] ) + return SCHEDULER_CBS_ERROR_NOSERVER; + /* Thread and server are not attached. */ + if ( _Scheduler_CBS_Server_list[server_id]->task_id != task_id ) + return SCHEDULER_CBS_ERROR_INVALID_PARAMETER; + + _Scheduler_CBS_Server_list[server_id]->task_id = -1; + sched_info->cbs_server = NULL; + + 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; + + return SCHEDULER_CBS_OK; +} diff --git a/cpukit/score/src/schedulercbsgetapprovedbudget.c b/cpukit/score/src/schedulercbsgetapprovedbudget.c new file mode 100644 index 0000000000..14db13031f --- /dev/null +++ b/cpukit/score/src/schedulercbsgetapprovedbudget.c @@ -0,0 +1,33 @@ +/* + * 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.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/system.h> +#include <rtems/config.h> +#include <rtems/score/scheduler.h> +#include <rtems/score/schedulercbs.h> + +int _Scheduler_CBS_Get_approved_budget ( + Scheduler_CBS_Server_id server_id, + time_t *approved_budget +) +{ + if ( server_id < 0 || server_id >= _Scheduler_CBS_Maximum_servers ) + return SCHEDULER_CBS_ERROR_INVALID_PARAMETER; + if ( !_Scheduler_CBS_Server_list[server_id] ) + 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 new file mode 100644 index 0000000000..b8d92ada30 --- /dev/null +++ b/cpukit/score/src/schedulercbsgetexecutiontime.c @@ -0,0 +1,53 @@ +/* + * 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.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/system.h> +#include <rtems/config.h> +#include <rtems/score/scheduler.h> +#include <rtems/score/schedulercbs.h> + +int _Scheduler_CBS_Get_execution_time ( + Scheduler_CBS_Server_id server_id, + time_t *exec_time, + time_t *abs_time +) +{ + Objects_Locations location; + Thread_Control *the_thread; + + if ( server_id < 0 || server_id >= _Scheduler_CBS_Maximum_servers ) + return SCHEDULER_CBS_ERROR_INVALID_PARAMETER; + if ( !_Scheduler_CBS_Server_list[server_id] ) + return SCHEDULER_CBS_ERROR_NOSERVER; + if ( !_Scheduler_CBS_Server_list[server_id]->task_id ) { + *exec_time = 0; + return SCHEDULER_CBS_OK; + } + + the_thread = _Thread_Get( + _Scheduler_CBS_Server_list[server_id]->task_id, + &location + ); + /* The routine _Thread_Get may disable dispatch and not enable again. */ + if ( the_thread ) { + _Thread_Enable_dispatch(); + *exec_time = _Scheduler_CBS_Server_list[server_id]->parameters.budget - + the_thread->cpu_time_budget; + } + else { + *exec_time = _Scheduler_CBS_Server_list[server_id]->parameters.budget; + } + return SCHEDULER_CBS_OK; +} diff --git a/cpukit/score/src/schedulercbsgetparameters.c b/cpukit/score/src/schedulercbsgetparameters.c new file mode 100644 index 0000000000..450afd0d68 --- /dev/null +++ b/cpukit/score/src/schedulercbsgetparameters.c @@ -0,0 +1,33 @@ +/* + * 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.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/system.h> +#include <rtems/config.h> +#include <rtems/score/scheduler.h> +#include <rtems/score/schedulercbs.h> + +int _Scheduler_CBS_Get_parameters ( + Scheduler_CBS_Server_id server_id, + Scheduler_CBS_Parameters *params +) +{ + if ( server_id < 0 || server_id >= _Scheduler_CBS_Maximum_servers ) + return SCHEDULER_CBS_ERROR_INVALID_PARAMETER; + if ( !_Scheduler_CBS_Server_list[server_id] ) + 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 new file mode 100644 index 0000000000..664c7e1bc4 --- /dev/null +++ b/cpukit/score/src/schedulercbsgetremainingbudget.c @@ -0,0 +1,52 @@ +/* + * 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.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/system.h> +#include <rtems/config.h> +#include <rtems/score/scheduler.h> +#include <rtems/score/schedulercbs.h> + +int _Scheduler_CBS_Get_remaining_budget ( + Scheduler_CBS_Server_id server_id, + time_t *remaining_budget +) +{ + Objects_Locations location; + Thread_Control *the_thread; + + if ( server_id < 0 || server_id >= _Scheduler_CBS_Maximum_servers ) + return SCHEDULER_CBS_ERROR_INVALID_PARAMETER; + if ( !_Scheduler_CBS_Server_list[server_id] ) + return SCHEDULER_CBS_ERROR_NOSERVER; + if ( _Scheduler_CBS_Server_list[server_id]->task_id == -1 ) { + *remaining_budget = _Scheduler_CBS_Server_list[server_id]->parameters.budget; + return SCHEDULER_CBS_OK; + } + + the_thread = _Thread_Get( + _Scheduler_CBS_Server_list[server_id]->task_id, + &location + ); + /* The routine _Thread_Get may disable dispatch and not enable again. */ + if ( the_thread ) { + _Thread_Enable_dispatch(); + *remaining_budget = the_thread->cpu_time_budget; + } + else { + *remaining_budget = 0; + } + + return SCHEDULER_CBS_OK; +} diff --git a/cpukit/score/src/schedulercbsgetserverid.c b/cpukit/score/src/schedulercbsgetserverid.c new file mode 100644 index 0000000000..1460b0c058 --- /dev/null +++ b/cpukit/score/src/schedulercbsgetserverid.c @@ -0,0 +1,35 @@ +/* + * 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.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/system.h> +#include <rtems/config.h> +#include <rtems/score/scheduler.h> +#include <rtems/score/schedulercbs.h> + +int _Scheduler_CBS_Get_server_id ( + rtems_id task_id, + Scheduler_CBS_Server_id *server_id +) +{ + unsigned int i; + for ( i = 0; i<_Scheduler_CBS_Maximum_servers; i++ ) { + if ( _Scheduler_CBS_Server_list[i] && + _Scheduler_CBS_Server_list[i]->task_id == task_id ) { + *server_id = i; + return SCHEDULER_CBS_OK; + } + } + return SCHEDULER_CBS_ERROR_NOSERVER; +} diff --git a/cpukit/score/src/schedulercbsreleasejob.c b/cpukit/score/src/schedulercbsreleasejob.c new file mode 100644 index 0000000000..c64b60ffb1 --- /dev/null +++ b/cpukit/score/src/schedulercbsreleasejob.c @@ -0,0 +1,52 @@ +/* + * 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.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/system.h> +#include <rtems/config.h> +#include <rtems/score/scheduler.h> +#include <rtems/score/schedulercbs.h> + +void _Scheduler_CBS_Release_job( + Thread_Control *the_thread, + uint32_t deadline +) +{ + Priority_Control new_priority; + Scheduler_CBS_Per_thread *sched_info = + (Scheduler_CBS_Per_thread *) the_thread->scheduler_info; + Scheduler_CBS_Server *serv_info = + (Scheduler_CBS_Server *) sched_info->cbs_server; + + if (deadline) { + /* Initializing or shifting deadline. */ + if (serv_info && serv_info->parameters.budget) + new_priority = (_Watchdog_Ticks_since_boot + serv_info->parameters.deadline) + & ~SCHEDULER_EDF_PRIO_MSB; + else + new_priority = (_Watchdog_Ticks_since_boot + deadline) + & ~SCHEDULER_EDF_PRIO_MSB; + } + else { + /* Switch back to background priority. */ + new_priority = the_thread->Start.initial_priority; + } + + /* Budget replenishment for the next job. */ + if (serv_info && serv_info->parameters.budget) + the_thread->cpu_time_budget = serv_info->parameters.budget; + + the_thread->real_priority = new_priority; + _Thread_Change_priority(the_thread, new_priority, true); +} diff --git a/cpukit/score/src/schedulercbssetparameters.c b/cpukit/score/src/schedulercbssetparameters.c new file mode 100644 index 0000000000..4268110364 --- /dev/null +++ b/cpukit/score/src/schedulercbssetparameters.c @@ -0,0 +1,40 @@ +/* + * 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.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/system.h> +#include <rtems/config.h> +#include <rtems/score/scheduler.h> +#include <rtems/score/schedulercbs.h> + +int _Scheduler_CBS_Set_parameters ( + Scheduler_CBS_Server_id server_id, + Scheduler_CBS_Parameters *params +) +{ + if ( server_id < 0 || server_id >= _Scheduler_CBS_Maximum_servers ) + return SCHEDULER_CBS_ERROR_INVALID_PARAMETER; + + if ( params->budget <= 0 || + params->deadline <= 0 || + params->budget >= SCHEDULER_EDF_PRIO_MSB || + params->deadline >= SCHEDULER_EDF_PRIO_MSB ) + return SCHEDULER_CBS_ERROR_INVALID_PARAMETER; + + if ( !_Scheduler_CBS_Server_list[server_id] ) + return SCHEDULER_CBS_ERROR_NOSERVER; + + _Scheduler_CBS_Server_list[server_id]->parameters = *params; + return SCHEDULER_CBS_OK; +} diff --git a/cpukit/score/src/schedulercbsunblock.c b/cpukit/score/src/schedulercbsunblock.c new file mode 100644 index 0000000000..0f417d8c9e --- /dev/null +++ b/cpukit/score/src/schedulercbsunblock.c @@ -0,0 +1,76 @@ +/* + * 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.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/system.h> +#include <rtems/score/scheduler.h> +#include <rtems/score/schedulercbs.h> + +void _Scheduler_CBS_Unblock( + Thread_Control *the_thread +) +{ + Scheduler_CBS_Per_thread *sched_info; + Scheduler_CBS_Server *serv_info; + Priority_Control new_priority; + + _Scheduler_EDF_Enqueue(the_thread); + /* TODO: flash critical section? */ + + sched_info = (Scheduler_CBS_Per_thread *) the_thread->scheduler_info; + serv_info = (Scheduler_CBS_Server *) sched_info->cbs_server; + + /* + * 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) { + time_t deadline = serv_info->parameters.deadline; + time_t budget = serv_info->parameters.budget; + time_t deadline_left = the_thread->cpu_time_budget; + time_t budget_left = the_thread->real_priority - + _Watchdog_Ticks_since_boot; + + if ( deadline*budget_left > budget*deadline_left ) { + /* Put late unblocked task to background until the end of period. */ + new_priority = the_thread->Start.initial_priority; + if ( the_thread->real_priority != new_priority ) + the_thread->real_priority = new_priority; + if ( the_thread->current_priority != new_priority ) + _Thread_Change_priority(the_thread, new_priority, true); + } + } + + /* + * If the thread that was unblocked is more important than the heir, + * then we have a new heir. This may or may not result in a + * context switch. + * + * Normal case: + * If the current thread is preemptible, then we need to do + * a context switch. + * Pseudo-ISR case: + * Even if the thread isn't preemptible, if the new heir is + * a pseudo-ISR system task, we need to do a context switch. + */ + if ( _Scheduler_Is_priority_higher_than( the_thread->current_priority, + _Thread_Heir->current_priority)) { + _Thread_Heir = the_thread; + if ( _Thread_Executing->is_preemptible || + the_thread->current_priority == 0 ) + _Thread_Dispatch_necessary = true; + } +} |