[PATCH] new CBS version
Joel Oliveira Pinto
jollp at isep.ipp.pt
Wed May 15 16:34:14 UTC 2019
From: JoelPinto <jollp at 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
* <rtems at 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
More information about the devel
mailing list