From ea71ba9e1275495edf9b03b7109fe290d959a47a Mon Sep 17 00:00:00 2001 From: "Bjoern B. Brandenburg" Date: Thu, 24 Jan 2008 15:53:56 -0500 Subject: add multi-threaded example --- bin/base_mt_task.c | 159 +++++++++++++++++++++++++++++++++++++++++++++++++++++ bin/base_task.c | 9 +-- 2 files changed, 162 insertions(+), 6 deletions(-) create mode 100644 bin/base_mt_task.c (limited to 'bin') diff --git a/bin/base_mt_task.c b/bin/base_mt_task.c new file mode 100644 index 0000000..096b124 --- /dev/null +++ b/bin/base_mt_task.c @@ -0,0 +1,159 @@ +/* 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 +#include + +/* Include threading support. */ +#include + +/* Include the LITMUS^RT API.*/ +#include "litmus.h" + +#define PERIOD 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(struct thread_context* ctx); + +/* Declare the periodically invoked job. + * Returns 1 -> task should exit. + * 0 -> task should continue. + */ +int job(void); + +/* 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, 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(struct thread_context* ctx) +{ + int do_exit; + + /* Make presence visible. */ + printf("RT Thread %d active.\n", ctx->id); + + /***** + * 1) Initialize real-time settings. + */ + init_rt_thread(); + sporadic_global(EXEC_COST, PERIOD); + + + + /***** + * 2) Transition to real-time mode. + */ + 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. + */ + 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 index e5f50b1..067c088 100644 --- a/bin/base_task.c +++ b/bin/base_task.c @@ -1,12 +1,9 @@ /* based_task.c -- A basic real-time task skeleton. * - * This (by itself useless) task demos how to setup LITMUS^RT real-time task. - * - * Compile: - * + * 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 @@ -118,7 +115,7 @@ int main(int argc, char** argv) /***** - * 7) Clean up and exit. + * 7) Clean up, maybe print results and stats, and exit. */ return 0; } -- cgit v1.2.2