[LITMUS^RT] [PATCH] Implement modules rule and move skeleton tasks to examples/

Manohar Vanga mvanga at mpi-sws.org
Thu Feb 6 00:29:14 CET 2014


This patch adds a modules rule to the Makefile in liblitmus that
allows the compilation of out-of-tree tasks with a simple Makefile
that is syntactically very clean (similar to kernel module
Makefile's).

This patch also moves base_task and base_mt_task to a separate
examples/ directory that employs the new module rule.

Further details regarding how to use the modules rule can be found
in examples/README.

Signed-off-by: Manohar Vanga <mvanga at mpi-sws.org>
---
 Makefile                |   15 ++--
 bin/base_mt_task.c      |  201 -----------------------------------------------
 bin/base_task.c         |  162 --------------------------------------
 examples/Makefile       |   11 +++
 examples/README         |   37 +++++++++
 examples/base_mt_task.c |  201 +++++++++++++++++++++++++++++++++++++++++++++++
 examples/base_task.c    |  162 ++++++++++++++++++++++++++++++++++++++
 inc/module.makefile     |   10 +++
 8 files changed, 429 insertions(+), 370 deletions(-)
 delete mode 100644 bin/base_mt_task.c
 delete mode 100644 bin/base_task.c
 create mode 100644 examples/Makefile
 create mode 100644 examples/README
 create mode 100644 examples/base_mt_task.c
 create mode 100644 examples/base_task.c
 create mode 100644 inc/module.makefile

diff --git a/Makefile b/Makefile
index e8003e8..ea10fee 100644
--- a/Makefile
+++ b/Makefile
@@ -72,8 +72,8 @@ AR  := ${CROSS_COMPILE}${AR}
 # Targets
 
 all     = lib ${rt-apps}
-rt-apps = cycles base_task rt_launch rtspin release_ts measure_syscall \
-	  base_mt_task uncache runtests
+rt-apps = cycles rt_launch rtspin release_ts measure_syscall \
+	  uncache runtests
 
 .PHONY: all lib clean dump-config TAGS tags cscope help
 
@@ -113,6 +113,8 @@ dump-config:
 		AR "${AR}" \
 		obj-all "${obj-all}"
 
+modules: liblitmus.a $(obj-m)
+
 help:
 	@cat INSTALL
 
@@ -212,11 +214,6 @@ vpath %.c bin/
 
 obj-cycles = cycles.o
 
-obj-base_task = base_task.o
-
-obj-base_mt_task = base_mt_task.o
-ldf-base_mt_task = -pthread
-
 obj-rt_launch = rt_launch.o common.o
 
 obj-rtspin = rtspin.o common.o
@@ -234,6 +231,10 @@ lib-measure_syscall = -lm
 # Build everything that depends on liblitmus.
 
 .SECONDEXPANSION:
+$(obj-m): $$M/$$(obj-$$@)
+	$(CC) -o $M/$@ $(LDFLAGS) ${ldf-$@} $M/$(obj-$@) $(LOADLIBS) $(LDLIBS) ${liblitmus-flags} ${lib-$@}
+
+.SECONDEXPANSION:
 ${rt-apps}: $${obj-$$@} liblitmus.a
 	$(CC) -o $@ $(LDFLAGS) ${ldf-$@} $(filter-out liblitmus.a,$+) $(LOADLIBS) $(LDLIBS) ${liblitmus-flags} ${lib-$@}
 
diff --git a/bin/base_mt_task.c b/bin/base_mt_task.c
deleted file mode 100644
index aec79a4..0000000
--- a/bin/base_mt_task.c
+++ /dev/null
@@ -1,201 +0,0 @@
-/* based_mt_task.c -- A basic multi-threaded real-time task skeleton. 
- *
- * This (by itself useless) task demos how to setup a multi-threaded LITMUS^RT
- * real-time task. Familiarity with the single threaded example (base_task.c)
- * is assumed.
- *
- * Currently, liblitmus still lacks automated support for real-time
- * tasks, but internaly it is thread-safe, and thus can be used together
- * with pthreads.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-/* Include gettid() */
-#include <sys/types.h>
-
-/* Include threading support. */
-#include <pthread.h>
-
-/* Include the LITMUS^RT API.*/
-#include "litmus.h"
-
-#define PERIOD            100
-#define RELATIVE_DEADLINE 100
-#define EXEC_COST         10
-
-/* Let's create 10 threads in the example, 
- * for a total utilization of 1.
- */
-#define NUM_THREADS      10 
-
-/* The information passed to each thread. Could be anything. */
-struct thread_context {
-	int id;
-};
-
-/* The real-time thread program. Doesn't have to be the same for
- * all threads. Here, we only have one that will invoke job().
- */
-void* rt_thread(void *tcontext);
-
-/* Declare the periodically invoked job. 
- * Returns 1 -> task should exit.
- *         0 -> task should continue.
- */
-int job(void);
-
-
-/* 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)
-
-
-/* Basic setup is the same as in the single-threaded example. However, 
- * we do some thread initiliazation first before invoking the job.
- */
-int main(int argc, char** argv)
-{
-	int i;
-	struct thread_context ctx[NUM_THREADS];
-	pthread_t             task[NUM_THREADS];
-
-	/* 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) Initialize LITMUS^RT.
-	 *    Task parameters will be specified per thread.
-	 */
-	init_litmus();
-
-
-	/***** 
-	 * 4) Launch threads.
-	 */
-	for (i = 0; i < NUM_THREADS; i++) {
-		ctx[i].id = i;
-		pthread_create(task + i, NULL, rt_thread, (void *) (ctx + i));
-	}
-
-	
-	/*****
-	 * 5) Wait for RT threads to terminate.
-	 */
-	for (i = 0; i < NUM_THREADS; i++)
-		pthread_join(task[i], NULL);
-	
-
-	/***** 
-	 * 6) Clean up, maybe print results and stats, and exit.
-	 */
-	return 0;
-}
-
-
-
-/* A real-time thread is very similar to the main function of a single-threaded
- * real-time app. Notice, that init_rt_thread() is called to initialized per-thread
- * data structures of the LITMUS^RT user space libary.
- */
-void* rt_thread(void *tcontext)
-{
-	int do_exit;
-	struct thread_context *ctx = (struct thread_context *) tcontext;
-	struct rt_task param;
-
-	/* Set up task parameters */
-	init_rt_task_param(&param);
-	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;
-
-	/* Make presence visible. */
-	printf("RT Thread %d active.\n", ctx->id);
-
-	/*****
-	 * 1) Initialize real-time settings.
-	 */
-	CALL( init_rt_thread() );
-
-	/* 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(), &param) );
-
-	/*****
-	 * 2) 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. 
-	 */
-
-
-
-	/*****
-	 * 3) Invoke real-time jobs.
-	 */
-	do {
-		/* Wait until the next job is released. */
-		sleep_next_period();
-		/* Invoke job. */
-		do_exit = job();		
-	} while (!do_exit);
-
-
-	
-	/*****
-	 * 4) Transition to background mode.
-	 */
-	CALL( task_mode(BACKGROUND_TASK) );
-
-
-	return NULL;
-}
-
-
-
-int job(void) 
-{
-	/* Do real-time calculation. */
-
-	/* Don't exit. */
-	return 0;
-}
diff --git a/bin/base_task.c b/bin/base_task.c
deleted file mode 100644
index 09edba9..0000000
--- a/bin/base_task.c
+++ /dev/null
@@ -1,162 +0,0 @@
-/* based_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(&param);
-	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(), &param) );
-
-
-	/*****
-	 * 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;
-}
diff --git a/examples/Makefile b/examples/Makefile
new file mode 100644
index 0000000..2583c59
--- /dev/null
+++ b/examples/Makefile
@@ -0,0 +1,11 @@
+# Define the list of targets we want
+obj-m += base_task base_mt_task
+
+# Define the object files for each target that we want
+obj-base_task += base_task.o
+obj-base_mt_task += base_mt_task.o
+
+# If a specific target needs a library, use lib-NAME
+lib-base_mt_task = -lpthread
+
+include $(LIBLITMUS)/inc/module.makefile
diff --git a/examples/README b/examples/README
new file mode 100644
index 0000000..cee4f78
--- /dev/null
+++ b/examples/README
@@ -0,0 +1,37 @@
+================================================================================
+Compiling liblitmus Tasks
+================================================================================
+
+This file describes how to compile LITMUS^RT tasks using the modules
+rule of the Makefile.
+
+Before beginning, please ensure that the LIBLITMUS environment variable
+is set to the location of the liblitmus source tree on disk. You can
+do this with the following (can be placed in your .bashrc):
+
+    export LIBLITMUS=/path/to/liblitmus/source
+
+Now, in your source directory, first create a Makefile that defines an
+'obj-m' variable specifying a list of your targets. For example,
+
+    obj-m = base_task base_mt_task
+
+Now, for each of the targets, define a variable specifying the list of
+object files that comprise it. The variable should be named using the
+convention 'obj-TARGET_NAME'. For example:
+
+    obj-base_task = base_task.o
+    obj-base_mt_task = base_mt_task.o
+
+If certain targets require additional libraries to be linked, they can
+be specified using the 'lib-TARGET_NAME' variable as shown below:
+
+    lib-base_mt_task = -lpthread
+
+Finally, in order to load all the rules (currently the default rule 'all' and
+the rule 'clean'), append the following line to the end of your Makefile:
+
+    include $(LIBLITMUS)/inc/module.makefile
+
+You're done! Now run 'make'! If liblitmus is not compiled, it will compile
+itself before compiling your targets.
diff --git a/examples/base_mt_task.c b/examples/base_mt_task.c
new file mode 100644
index 0000000..aec79a4
--- /dev/null
+++ b/examples/base_mt_task.c
@@ -0,0 +1,201 @@
+/* based_mt_task.c -- A basic multi-threaded real-time task skeleton. 
+ *
+ * This (by itself useless) task demos how to setup a multi-threaded LITMUS^RT
+ * real-time task. Familiarity with the single threaded example (base_task.c)
+ * is assumed.
+ *
+ * Currently, liblitmus still lacks automated support for real-time
+ * tasks, but internaly it is thread-safe, and thus can be used together
+ * with pthreads.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+/* Include gettid() */
+#include <sys/types.h>
+
+/* Include threading support. */
+#include <pthread.h>
+
+/* Include the LITMUS^RT API.*/
+#include "litmus.h"
+
+#define PERIOD            100
+#define RELATIVE_DEADLINE 100
+#define EXEC_COST         10
+
+/* Let's create 10 threads in the example, 
+ * for a total utilization of 1.
+ */
+#define NUM_THREADS      10 
+
+/* The information passed to each thread. Could be anything. */
+struct thread_context {
+	int id;
+};
+
+/* The real-time thread program. Doesn't have to be the same for
+ * all threads. Here, we only have one that will invoke job().
+ */
+void* rt_thread(void *tcontext);
+
+/* Declare the periodically invoked job. 
+ * Returns 1 -> task should exit.
+ *         0 -> task should continue.
+ */
+int job(void);
+
+
+/* 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)
+
+
+/* Basic setup is the same as in the single-threaded example. However, 
+ * we do some thread initiliazation first before invoking the job.
+ */
+int main(int argc, char** argv)
+{
+	int i;
+	struct thread_context ctx[NUM_THREADS];
+	pthread_t             task[NUM_THREADS];
+
+	/* 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) Initialize LITMUS^RT.
+	 *    Task parameters will be specified per thread.
+	 */
+	init_litmus();
+
+
+	/***** 
+	 * 4) Launch threads.
+	 */
+	for (i = 0; i < NUM_THREADS; i++) {
+		ctx[i].id = i;
+		pthread_create(task + i, NULL, rt_thread, (void *) (ctx + i));
+	}
+
+	
+	/*****
+	 * 5) Wait for RT threads to terminate.
+	 */
+	for (i = 0; i < NUM_THREADS; i++)
+		pthread_join(task[i], NULL);
+	
+
+	/***** 
+	 * 6) Clean up, maybe print results and stats, and exit.
+	 */
+	return 0;
+}
+
+
+
+/* A real-time thread is very similar to the main function of a single-threaded
+ * real-time app. Notice, that init_rt_thread() is called to initialized per-thread
+ * data structures of the LITMUS^RT user space libary.
+ */
+void* rt_thread(void *tcontext)
+{
+	int do_exit;
+	struct thread_context *ctx = (struct thread_context *) tcontext;
+	struct rt_task param;
+
+	/* Set up task parameters */
+	init_rt_task_param(&param);
+	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;
+
+	/* Make presence visible. */
+	printf("RT Thread %d active.\n", ctx->id);
+
+	/*****
+	 * 1) Initialize real-time settings.
+	 */
+	CALL( init_rt_thread() );
+
+	/* 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(), &param) );
+
+	/*****
+	 * 2) 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. 
+	 */
+
+
+
+	/*****
+	 * 3) Invoke real-time jobs.
+	 */
+	do {
+		/* Wait until the next job is released. */
+		sleep_next_period();
+		/* Invoke job. */
+		do_exit = job();		
+	} while (!do_exit);
+
+
+	
+	/*****
+	 * 4) Transition to background mode.
+	 */
+	CALL( task_mode(BACKGROUND_TASK) );
+
+
+	return NULL;
+}
+
+
+
+int job(void) 
+{
+	/* Do real-time calculation. */
+
+	/* Don't exit. */
+	return 0;
+}
diff --git a/examples/base_task.c b/examples/base_task.c
new file mode 100644
index 0000000..09edba9
--- /dev/null
+++ b/examples/base_task.c
@@ -0,0 +1,162 @@
+/* based_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(&param);
+	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(), &param) );
+
+
+	/*****
+	 * 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;
+}
diff --git a/inc/module.makefile b/inc/module.makefile
new file mode 100644
index 0000000..696155d
--- /dev/null
+++ b/inc/module.makefile
@@ -0,0 +1,10 @@
+export $(filter obj%, $(.VARIABLES))
+export $(filter lib%, $(.VARIABLES))
+
+LIBLITMUS ?= ../liblitmus
+
+all:
+	make -C $(LIBLITMUS) M=$(PWD) modules
+
+clean:
+	rm -f $(obj-m) $(foreach obj, $(obj-m), $(obj-$(obj)))
-- 
1.7.9.5





More information about the litmus-dev mailing list