summaryrefslogtreecommitdiffstats
path: root/cpukit/include/rtems
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2021-04-08 08:18:20 +0200
committerSebastian Huber <sebastian.huber@embedded-brains.de>2022-03-24 11:10:48 +0100
commitcc1c944042bcf500b7c39ecb7ce826e914722d73 (patch)
treeca486586b194c7ca54873c5069817d3d541ded50 /cpukit/include/rtems
parentscore: Add _IO_Relax() (diff)
downloadrtems-cc1c944042bcf500b7c39ecb7ce826e914722d73.tar.bz2
libtest: Add scheduler test support
Add support to record scheduler operations. This support is especially important for tests in SMP configurations since the thread switch extension is quite difficult to use due to the asynchronous nature of thread dispatching. In contrast, the scheduler operations occur normally in a deterministic order. Update #3716.
Diffstat (limited to 'cpukit/include/rtems')
-rw-r--r--cpukit/include/rtems/test-scheduler.h290
1 files changed, 290 insertions, 0 deletions
diff --git a/cpukit/include/rtems/test-scheduler.h b/cpukit/include/rtems/test-scheduler.h
new file mode 100644
index 0000000000..b9e8bf2993
--- /dev/null
+++ b/cpukit/include/rtems/test-scheduler.h
@@ -0,0 +1,290 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup RTEMSTestFramework
+ *
+ * @brief This header file defines the scheduler test support API.
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH (http://www.embedded-brains.de)
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _RTEMS_TEST_SCHEDULER_H
+#define _RTEMS_TEST_SCHEDULER_H
+
+#include <rtems/test.h>
+#include <rtems/score/processormask.h>
+#include <rtems/score/scheduler.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @addtogroup RTEMSTestFramework
+ *
+ * @{
+ */
+
+typedef enum {
+ T_SCHEDULER_NOP,
+ T_SCHEDULER_ADD_PROCESSOR,
+ T_SCHEDULER_ANY,
+ T_SCHEDULER_ASK_FOR_HELP,
+ T_SCHEDULER_BLOCK,
+ T_SCHEDULER_CANCEL_JOB,
+ T_SCHEDULER_CLEAN_STICKY,
+ T_SCHEDULER_INITIALIZE,
+ T_SCHEDULER_MAKE_STICKY,
+ T_SCHEDULER_MAP_PRIORITY,
+ T_SCHEDULER_NODE_DESTROY,
+ T_SCHEDULER_NODE_INITIALIZE,
+ T_SCHEDULER_PIN,
+ T_SCHEDULER_RECONSIDER_HELP_REQUEST,
+ T_SCHEDULER_RELEASE_JOB,
+ T_SCHEDULER_REMOVE_PROCESSOR,
+ T_SCHEDULER_SCHEDULE,
+ T_SCHEDULER_SET_AFFINITY,
+ T_SCHEDULER_START_IDLE,
+ T_SCHEDULER_UNBLOCK,
+ T_SCHEDULER_UNMAP_PRIORITY,
+ T_SCHEDULER_UNPIN,
+ T_SCHEDULER_UPDATE_PRIORITY,
+ T_SCHEDULER_WITHDRAW_NODE,
+ T_SCHEDULER_YIELD
+} T_scheduler_operation;
+
+typedef struct {
+ Thread_Control *executing;
+ uint32_t cpu;
+ T_time instant;
+ T_scheduler_operation operation;
+ Thread_Control *thread;
+ Scheduler_Node *node;
+ union {
+ struct {
+ Priority_Control in;
+ Priority_Control out;
+ } map_unmap_priority;
+ struct {
+ bool success;
+ } ask_for_help;
+ struct {
+#ifdef RTEMS_SMP
+ Thread_Scheduler_state next_state;
+#else
+ int next_state;
+#endif
+ } withdraw_node;
+ struct {
+ struct Per_CPU_Control *cpu;
+ } pin_unpin;
+ struct {
+ Thread_Control *idle;
+ } add_processor;
+ struct {
+ struct Per_CPU_Control *cpu;
+ Thread_Control *idle;
+ } remove_processor;
+ struct {
+ Priority_Node *priority;
+ uint64_t deadline;
+ } release_job;
+ struct {
+ Priority_Node *priority;
+ } cancel_job;
+ struct {
+ Processor_mask affinity;
+ Status_Control status;
+ } set_affinity;
+ };
+} T_scheduler_event;
+
+typedef struct {
+ size_t recorded;
+ size_t capacity;
+ uint64_t operations;
+} T_scheduler_header;
+
+typedef struct {
+ T_scheduler_header header;
+ T_scheduler_event events[T_ZERO_LENGTH_ARRAY];
+} T_scheduler_log;
+
+typedef struct {
+ T_scheduler_header header;
+ T_scheduler_event events[2];
+} T_scheduler_log_2;
+
+typedef struct {
+ T_scheduler_header header;
+ T_scheduler_event events[4];
+} T_scheduler_log_4;
+
+typedef struct {
+ T_scheduler_header header;
+ T_scheduler_event events[10];
+} T_scheduler_log_10;
+
+typedef struct {
+ T_scheduler_header header;
+ T_scheduler_event events[20];
+} T_scheduler_log_20;
+
+typedef struct {
+ T_scheduler_header header;
+ T_scheduler_event events[40];
+} T_scheduler_log_40;
+
+T_scheduler_log *T_scheduler_record(T_scheduler_log *);
+
+T_scheduler_log *T_scheduler_record_2(T_scheduler_log_2 *);
+
+T_scheduler_log *T_scheduler_record_4(T_scheduler_log_4 *);
+
+T_scheduler_log *T_scheduler_record_10(T_scheduler_log_10 *);
+
+T_scheduler_log *T_scheduler_record_20(T_scheduler_log_20 *);
+
+T_scheduler_log *T_scheduler_record_40(T_scheduler_log_40 *);
+
+typedef enum {
+ T_SCHEDULER_BEFORE,
+ T_SCHEDULER_AFTER
+} T_scheduler_when;
+
+typedef void (*T_scheduler_event_handler)(void *, const T_scheduler_event *,
+ T_scheduler_when);
+
+void T_scheduler_set_event_handler(T_scheduler_event_handler, void *);
+
+extern const T_scheduler_event T_scheduler_event_null;
+
+const T_scheduler_event *T_scheduler_next(T_scheduler_header *,
+ T_scheduler_operation, size_t *);
+
+const T_scheduler_event *T_scheduler_next_any(T_scheduler_header *,
+ size_t *);
+
+void T_scheduler_initialize(const Scheduler_Control *);
+
+void T_scheduler_schedule(const Scheduler_Control *, Thread_Control *);
+
+void T_scheduler_yield(const Scheduler_Control *, Thread_Control *,
+ Scheduler_Node *);
+
+void T_scheduler_block(const Scheduler_Control *, Thread_Control *,
+ Scheduler_Node *);
+
+void T_scheduler_unblock(const Scheduler_Control *, Thread_Control *,
+ Scheduler_Node *);
+
+void T_scheduler_update_priority(const Scheduler_Control *, Thread_Control *,
+ Scheduler_Node *);
+
+Priority_Control T_scheduler_map_priority(const Scheduler_Control *,
+ Priority_Control);
+
+Priority_Control T_scheduler_unmap_priority(const Scheduler_Control *,
+ Priority_Control);
+
+void T_scheduler_node_initialize(const Scheduler_Control *, Scheduler_Node *,
+ Thread_Control *, Priority_Control);
+
+void T_scheduler_node_destroy(const Scheduler_Control *, Scheduler_Node *);
+
+void T_scheduler_release_job(const Scheduler_Control *, Thread_Control *,
+ Priority_Node *, uint64_t, Thread_queue_Context *);
+
+void T_scheduler_cancel_job(const Scheduler_Control *, Thread_Control *,
+ Priority_Node *, Thread_queue_Context *);
+
+void T_scheduler_start_idle(const Scheduler_Control *, Thread_Control *,
+ struct Per_CPU_Control *);
+
+#ifdef RTEMS_SMP
+bool T_scheduler_ask_for_help(const Scheduler_Control *, Thread_Control *,
+ Scheduler_Node *);
+
+void T_scheduler_reconsider_help_request(const Scheduler_Control *,
+ Thread_Control *, Scheduler_Node *);
+
+void T_scheduler_withdraw_node(const Scheduler_Control *, Thread_Control *,
+ Scheduler_Node *, Thread_Scheduler_state);
+
+void T_scheduler_make_sticky(const Scheduler_Control *, Thread_Control *,
+ Scheduler_Node *);
+
+void T_scheduler_clean_sticky(const Scheduler_Control *, Thread_Control *,
+ Scheduler_Node *);
+
+void T_scheduler_pin(const Scheduler_Control *, Thread_Control *,
+ Scheduler_Node *, struct Per_CPU_Control *);
+
+void T_scheduler_unpin(const Scheduler_Control *, Thread_Control *,
+ Scheduler_Node *, struct Per_CPU_Control *);
+
+void T_scheduler_add_processor(const Scheduler_Control *, Thread_Control *);
+
+Thread_Control *T_scheduler_remove_processor(const Scheduler_Control *,
+ struct Per_CPU_Control *);
+
+Status_Control T_scheduler_set_affinity(const Scheduler_Control *,
+ Thread_Control *, Scheduler_Node *, const Processor_mask *);
+#endif
+
+#ifdef RTEMS_SMP
+#define T_SCHEDULER_ENTRY_POINTS { T_scheduler_initialize, \
+ T_scheduler_schedule, T_scheduler_yield, T_scheduler_block, \
+ T_scheduler_unblock, T_scheduler_update_priority, \
+ T_scheduler_map_priority, T_scheduler_unmap_priority, \
+ T_scheduler_ask_for_help, T_scheduler_reconsider_help_request, \
+ T_scheduler_withdraw_node, T_scheduler_make_sticky, \
+ T_scheduler_clean_sticky, T_scheduler_pin, T_scheduler_unpin, \
+ T_scheduler_add_processor, T_scheduler_remove_processor, \
+ T_scheduler_node_initialize, T_scheduler_node_destroy, \
+ T_scheduler_release_job, T_scheduler_cancel_job, \
+ T_scheduler_start_idle, T_scheduler_set_affinity }
+#else
+#define T_SCHEDULER_ENTRY_POINTS { T_scheduler_initialize, \
+ T_scheduler_schedule, T_scheduler_yield, T_scheduler_block, \
+ T_scheduler_unblock, T_scheduler_update_priority, \
+ T_scheduler_map_priority, T_scheduler_unmap_priority, \
+ T_scheduler_node_initialize, T_scheduler_node_destroy, \
+ T_scheduler_release_job, T_scheduler_cancel_job, \
+ T_scheduler_start_idle }
+#endif
+
+extern const Scheduler_Operations T_scheduler_operations[];
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _RTEMS_TEST_SCHEDULER_H */