1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161
|
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/version.h>
#include <linux/errno.h>
#include <rtl_sched.h>
#include "../rt_ipc.h"
static char *strs[] = { "Joey ", "Johnny ", "Dee Dee ", "Marky " };
static char sync_str[] = "gabba\n";
#define NUM_TASKS (sizeof(strs) / sizeof(char *))
RT_TASK_IPC start_task, tasks[NUM_TASKS];
rt_sem_t sems[NUM_TASKS], sync_sem, prio_sem;
rt_mq_t mq_in, mq_out;
#define DBG_PRINT_SETUP rt_sem_t print_sem;
#define DBG_PRINT_INIT rt_sem_init(&print_sem, RT_SEM_BINARY, 1);
#define TAKE_PRINT rt_sem_wait(&print_sem, RT_WAIT_FOREVER);
#define GIVE_PRINT rt_sem_post(&print_sem);
DBG_PRINT_SETUP
/*
* Each task waits to receive the semaphore, prints its string, and
* passes the semaphore to the next task. Then it sends a sync semaphore,
* and waits for another semaphore, and this time displays it in
* priority order. Finally, message queues are tested.
*/
void task_code(int task_no)
{
int i, ret;
char buf[20];
for (i=0 ; i<5 ; ++i)
{
rt_sem_wait(&sems[task_no], RT_WAIT_FOREVER);
printk(strs[task_no]);
if (task_no == NUM_TASKS-1)
printk("\n");
rt_sem_post(&sems[(task_no + 1) % NUM_TASKS]);
}
rt_sem_post(&sync_sem);
rt_sem_wait(&prio_sem, RT_WAIT_FOREVER);
printk(strs[task_no]);
rt_task_delay(RELATIVE_TIME(RT_TICKS_PER_SEC));
rt_sem_wait(&prio_sem, RELATIVE_TIME((task_no+1) * RT_TICKS_PER_SEC));
printk(strs[task_no]);
rt_sem_post(&sync_sem);
/* message queue stuff */
if ((ret = rt_mq_receive(&mq_in, buf, RT_WAIT_FOREVER)) != 0)
printk("rt_mq_receive() failed with %d\n", ret);
TAKE_PRINT; printk("\nreceived by task %d ", task_no);
printk(buf); GIVE_PRINT;
rt_mq_send(&mq_out, strs[task_no], RT_MQ_NORMAL, RT_WAIT_FOREVER);
/* test receive timeout */
rt_sem_wait(&sync_sem, RT_WAIT_FOREVER);
if (rt_mq_receive(&mq_in, buf, RELATIVE_TIME(RT_TICKS_PER_SEC*(task_no+1))) == -ETIME)
{ TAKE_PRINT; printk("task %d timed out.\n", task_no); GIVE_PRINT; }
rt_task_suspend(MAKE_RT_TASK(&tasks[task_no]));
}
/*
* initialization task
*/
void start_task_code(int notused)
{
int i;
DBG_PRINT_INIT;
if (rt_mq_init(&mq_in, NUM_TASKS, 20) || rt_mq_init(&mq_out, NUM_TASKS, 20))
{
printk("could not create message queue\n");
return;
}
for (i=0 ; i<NUM_TASKS ; ++i)
{
if (rt_sem_init(&sems[i], RT_SEM_BINARY, 0) != 0)
{
printk("rt_sem_init failed\n");
return;
}
if (rt_task_ipc_init(&tasks[i], task_code, i, 3000, NUM_TASKS-i) != 0)
{
printk("rt_task_ipc_init failed\n");
return;
}
rt_task_wakeup(MAKE_RT_TASK(&tasks[i]));
}
/* create the sync semaphore */
if (rt_sem_init(&sync_sem, RT_SEM_COUNTING, 0) != 0)
{
printk("rt_sem_init failed on sync_sem\n");
return;
}
/* create the priority-test semaphore */
if (rt_sem_init(&prio_sem, RT_SEM_BINARY, 0) != 0)
{
printk("rt_sem_init failed on prio_sem\n");
return;
}
/* pass the semaphore to the first task */
rt_sem_post(&sems[0]);
/* wait for each task to send the sync semaphore */
for (i=0 ; i<NUM_TASKS ; ++i)
rt_sem_wait(&sync_sem, RT_WAIT_FOREVER);
printk(sync_str);
/* post the priority-test semaphore -- the tasks should then run */
/* in priority order */
for (i=0 ; i<NUM_TASKS ; ++i)
rt_sem_post(&prio_sem);
printk("\n");
for (i=0 ; i<NUM_TASKS ; ++i)
rt_sem_wait(&sync_sem, RT_WAIT_FOREVER);
printk(sync_str);
/* now, test message queues */
printk("testing message queues\n");
for (i=0 ; i<NUM_TASKS ; ++i)
if (rt_mq_send(&mq_in, strs[i], RT_MQ_NORMAL, RT_WAIT_FOREVER))
printk("rt_mq_send() failed\n");
for (i=0 ; i<NUM_TASKS ; ++i)
{
char buf[20];
rt_mq_receive(&mq_out, buf, RT_WAIT_FOREVER);
TAKE_PRINT; printk("\nreceived from mq_out: %s", buf); GIVE_PRINT;
}
for (i=0 ; i<NUM_TASKS ; ++i)
rt_sem_post(&sync_sem);
TAKE_PRINT; printk("\ninit task complete\n"); GIVE_PRINT;
/* nothing more for this task to do */
rt_task_suspend(MAKE_RT_TASK(&start_task));
}
int init_module(void)
{
if (rt_task_ipc_init(&start_task, start_task_code, 0, 3000, 10) != 0)
printk("Could not start init task\n");
rt_task_wakeup(MAKE_RT_TASK(&start_task));
return 0;
}
void cleanup_module(void)
{
int i;
for (i=0 ; i<NUM_TASKS ; ++i)
{
rt_sem_destroy(&sems[i]);
rt_task_ipc_delete(&tasks[i]);
}
rt_sem_destroy(&sync_sem);
rt_mq_destroy(&mq_in);
rt_mq_destroy(&mq_out);
rt_task_ipc_delete(&start_task);
}
|