File: test_ipc.c

package info (click to toggle)
rtlinux 3.1pre3-3
  • links: PTS
  • area: non-free
  • in suites: etch, etch-m68k
  • size: 4,896 kB
  • ctags: 4,228
  • sloc: ansic: 26,204; sh: 2,069; makefile: 1,414; perl: 855; tcl: 489; asm: 380; cpp: 42
file content (161 lines) | stat: -rw-r--r-- 4,521 bytes parent folder | download | duplicates (3)
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);
}