[LITMUS^RT] [PATCH 2/2] Add a task skeleton that uses the new modules functionality
Manohar Vanga
mvanga at mpi-sws.org
Tue Feb 4 03:20:27 CET 2014
This patch adds a sample task skeleton that can be used as the
basis for developing LITMUS^RT tasks in independent folders.
The Makefile assumes that the path to liblitmus is available in
the $DIR_LIBLITMUS environment variable.
Signed-off-by: Manohar Vanga <mvanga at mpi-sws.org>
---
task-skeleton/Makefile | 11 ++++
task-skeleton/task.c | 162 ++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 173 insertions(+)
create mode 100644 task-skeleton/Makefile
create mode 100644 task-skeleton/task.c
diff --git a/task-skeleton/Makefile b/task-skeleton/Makefile
new file mode 100644
index 0000000..91a3519
--- /dev/null
+++ b/task-skeleton/Makefile
@@ -0,0 +1,11 @@
+obj-m += mod_task
+obj-mod_task += task.o
+
+export obj-m
+export obj-mod_task
+
+all:
+ make -C $(DIR_LIBLITMUS) M=$(PWD) modules
+
+clean:
+ rm $(obj-m) $(foreach obj, $(obj-m), $(obj-$(obj)))
diff --git a/task-skeleton/task.c b/task-skeleton/task.c
new file mode 100644
index 0000000..58f22c7
--- /dev/null
+++ b/task-skeleton/task.c
@@ -0,0 +1,162 @@
+/* Based on liblitmus/bin/base_task.c -- A basic real-time task skeleton.
+ *
+ * This (by itself useless) task demos how to setup a
+ * single-threaded LITMUS^RT real-time task.
+ */
+
+/* First, we include standard headers.
+ * Generally speaking, a LITMUS^RT real-time task can perform any
+ * system call, etc., but no real-time guarantees can be made if a
+ * system call blocks. To be on the safe side, only use I/O for debugging
+ * purposes and from non-real-time sections.
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+/* Second, we include the LITMUS^RT user space library header.
+ * This header, part of liblitmus, provides the user space API of
+ * LITMUS^RT.
+ */
+#include "litmus.h"
+
+/* Next, we define period and execution cost to be constant.
+ * These are only constants for convenience in this example, they can be
+ * determined at run time, e.g., from command line parameters.
+ *
+ * These are in milliseconds.
+ */
+#define PERIOD 100
+#define RELATIVE_DEADLINE 100
+#define EXEC_COST 10
+
+/* Catch errors.
+ */
+#define CALL( exp ) do { \
+ int ret; \
+ ret = exp; \
+ if (ret != 0) \
+ fprintf(stderr, "%s failed: %m\n", #exp);\
+ else \
+ fprintf(stderr, "%s ok.\n", #exp); \
+ } while (0)
+
+
+/* Declare the periodically invoked job.
+ * Returns 1 -> task should exit.
+ * 0 -> task should continue.
+ */
+int job(void);
+
+/* typically, main() does a couple of things:
+ * 1) parse command line parameters, etc.
+ * 2) Setup work environment.
+ * 3) Setup real-time parameters.
+ * 4) Transition to real-time mode.
+ * 5) Invoke periodic or sporadic jobs.
+ * 6) Transition to background mode.
+ * 7) Clean up and exit.
+ *
+ * The following main() function provides the basic skeleton of a single-threaded
+ * LITMUS^RT real-time task. In a real program, all the return values should be
+ * checked for errors.
+ */
+int main(int argc, char** argv)
+{
+ int do_exit;
+ struct rt_task param;
+
+ /* Setup task parameters */
+ init_rt_task_param(¶m);
+ param.exec_cost = ms2ns(EXEC_COST);
+ param.period = ms2ns(PERIOD);
+ param.relative_deadline = ms2ns(RELATIVE_DEADLINE);
+
+ /* What to do in the case of budget overruns? */
+ param.budget_policy = NO_ENFORCEMENT;
+
+ /* The task class parameter is ignored by most plugins. */
+ param.cls = RT_CLASS_SOFT;
+
+ /* The priority parameter is only used by fixed-priority plugins. */
+ param.priority = LITMUS_LOWEST_PRIORITY;
+
+ /* The task is in background mode upon startup. */
+
+
+ /*****
+ * 1) Command line paramter parsing would be done here.
+ */
+
+
+
+ /*****
+ * 2) Work environment (e.g., global data structures, file data, etc.) would
+ * be setup here.
+ */
+
+
+
+ /*****
+ * 3) Setup real-time parameters.
+ * In this example, we create a sporadic task that does not specify a
+ * target partition (and thus is intended to run under global scheduling).
+ * If this were to execute under a partitioned scheduler, it would be assigned
+ * to the first partition (since partitioning is performed offline).
+ */
+ CALL( init_litmus() );
+
+ /* To specify a partition, do
+ *
+ * param.cpu = CPU;
+ * be_migrate_to(CPU);
+ *
+ * where CPU ranges from 0 to "Number of CPUs" - 1 before calling
+ * set_rt_task_param().
+ */
+ CALL( set_rt_task_param(gettid(), ¶m) );
+
+
+ /*****
+ * 4) Transition to real-time mode.
+ */
+ CALL( task_mode(LITMUS_RT_TASK) );
+
+ /* The task is now executing as a real-time task if the call didn't fail.
+ */
+
+
+
+ /*****
+ * 5) Invoke real-time jobs.
+ */
+ do {
+ /* Wait until the next job is released. */
+ sleep_next_period();
+ /* Invoke job. */
+ do_exit = job();
+ } while (!do_exit);
+
+
+
+ /*****
+ * 6) Transition to background mode.
+ */
+ CALL( task_mode(BACKGROUND_TASK) );
+
+
+
+ /*****
+ * 7) Clean up, maybe print results and stats, and exit.
+ */
+ return 0;
+}
+
+
+int job(void)
+{
+ /* Do real-time calculation. */
+
+ /* Don't exit. */
+ return 0;
+}
--
1.7.9.5
More information about the litmus-dev
mailing list