Subversion Repositories shark

Rev

Rev 1550 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
1085 pj 1
/*
2
 * Project: S.Ha.R.K.
3
 *
4
 * Coordinators:
5
 *   Giorgio Buttazzo    <giorgio@sssup.it>
6
 *   Paolo Gai           <pj@gandalf.sssup.it>
7
 *
8
 * Authors     :
9
 *   Paolo Gai           <pj@gandalf.sssup.it>
10
 *   (see the web pages for full authors list)
11
 *
12
 * ReTiS Lab (Scuola Superiore S.Anna - Pisa - Italy)
13
 *
14
 * http://www.sssup.it
15
 * http://retis.sssup.it
16
 * http://shark.sssup.it
17
 */
18
 
19
/**
20
 ------------
1550 pj 21
 CVS :        $Id: ptest6.c,v 1.3 2005-01-08 14:36:11 pj Exp $
1085 pj 22
 
23
 File:        $File$
1550 pj 24
 Revision:    $Revision: 1.3 $
25
 Last update: $Date: 2005-01-08 14:36:11 $
1085 pj 26
 ------------
27
 
28
 Posix test 6:
29
 
30
   message queues
31
 
32
   main thread:
33
     set a sigevent to sigev_thread on a mailbox (that creates thread 2)
34
     creates thread 1
35
     waits t=3.5 sec.
36
     pthread_cancel(T4)
37
 
38
   thread 1:
39
     send a msg to the mailbox (the event fires and thread 2 is created)
40
 
41
   thread 2:
42
     receive the msg sent by thread 1
43
     set the event to a signal
44
     creates thread 3 and 4
45
     waits t = 1 sec
46
     send another msg
47
 
48
   thread 3:
49
     receive the msg sent by 2 (it blocks!)
50
     waits t = 2 sec
51
     send 5 msgs (with different priorities!!!
52
 
53
   thread 4:
54
     receives 5 msgs every 0.5 sec.
55
     then receive another message that never will arrive...
56
 
57
 non standard function used:
58
   cprintf
59
   sys_gettime
60
   keyboard stuffs
61
 
62
**/
63
 
64
/*
65
 * Copyright (C) 2000 Paolo Gai
66
 *
67
 * This program is free software; you can redistribute it and/or modify
68
 * it under the terms of the GNU General Public License as published by
69
 * the Free Software Foundation; either version 2 of the License, or
70
 * (at your option) any later version.
71
 *
72
 * This program is distributed in the hope that it will be useful,
73
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
74
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
75
 * GNU General Public License for more details.
76
 *
77
 * You should have received a copy of the GNU General Public License
78
 * along with this program; if not, write to the Free Software
79
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
80
 *
81
 */
82
 
83
#include <sys/types.h>
84
#include <pthread.h>
85
#include <mqueue.h>
86
 
87
#include <kernel/kern.h>
88
 
89
struct sigevent ev25, evtask;
90
pthread_attr_t task_attr;
91
struct sched_param task_param;
92
mqd_t mq;
93
pthread_t T1,T2,T3,T4,T5;
94
 
95
#define MESSAGE_LENGTH 100
96
 
97
void *t1(void *arg)
98
{
99
  cprintf("T1: started, sending a message\n");
100
  if (mq_send(mq,"Donald Duck",12,1))
101
  { cprintf("T1: mq_send returns errno %d\n",errno); return 0; }
102
 
103
  cprintf("T1: ending...\n");
104
  return 0;
105
}
106
 
107
void *t4(void *arg);
108
void *t3(void *arg);
109
 
110
void t2(union sigval value)
111
{
112
  ssize_t x;
113
  char buf[MESSAGE_LENGTH];
114
  int prio;
115
 
116
  cprintf("T2: value = %d, receiving a message\n", value.sival_int);
117
 
118
  x = mq_receive(mq,buf,MESSAGE_LENGTH,&prio);
119
 
120
  cprintf("T2: received message: length=%ld, prio=%d, text=°%s°, notify...\n",
121
              x,prio,buf);
122
 
123
  if (mq_notify(mq, &ev25))
1550 pj 124
  { cprintf("T2: mq_notify returns errno %d\n",errno); exit(1); }
1085 pj 125
 
126
  cprintf("T2: waiting t = 1 sec.\n");
127
  while (sys_gettime(NULL)<1000000);
128
  cprintf("T2: 1 sec. reached, sending another message and creating T3 and T4, \n");
129
 
130
  if (mq_send(mq,"Mickey Mouse",13,1))
1550 pj 131
  { cprintf("T2: mq_send returns errno %d\n",errno); exit(1); }
1085 pj 132
 
133
  pthread_create(&T3, NULL, t3, NULL);
134
  pthread_create(&T4, NULL, t4, NULL);
135
 
136
  cprintf("T2: ending...\n");
137
}
138
 
139
void *t3(void *arg)
140
{
141
  ssize_t x;
142
  char buf[MESSAGE_LENGTH];
143
  int prio;
144
 
145
  cprintf("T3: waiting a message...\n");
146
 
147
  x = mq_receive(mq,buf,MESSAGE_LENGTH,&prio);
148
 
149
  // mickey mouse
150
  cprintf("T3: received message: length=%ld, prio=%d, text=°%s°\n",
151
              x,prio,buf);
152
 
153
  cprintf("T3: waiting t = 1.5 sec.\n");
154
  while (sys_gettime(NULL)<1500000);
155
  cprintf("T3: 2 sec. reached, sending 5 messages\n");
156
 
157
  if (mq_send(mq,"Goofy",6,1))
1550 pj 158
  { cprintf("T3: mq_send1 returns errno %d\n",errno); exit(1); }
1085 pj 159
  cprintf("Û");
160
 
161
  if (mq_send(mq,"Minnie",7,1))
1550 pj 162
  { cprintf("T3: mq_send2 returns errno %d\n",errno); exit(1); }
1085 pj 163
  cprintf("Û");
164
 
165
  if (mq_send(mq,"Pluto",6,2))  // NB: different priority!!!
1550 pj 166
  { cprintf("T3: mq_send3 returns errno %d\n",errno); exit(1); }
1085 pj 167
  cprintf("Û");
168
 
169
  if (mq_send(mq,"Rocker Duck",12,2))  // NB: different priority!!!
1550 pj 170
  { cprintf("T3: mq_send4 returns errno %d\n",errno); exit(1); }
1085 pj 171
  cprintf("Û");
172
 
173
  if (mq_send(mq,"Oncle Scroodge",15,2))  // NB: different priority!!!
1550 pj 174
  { cprintf("T3: mq_send5 returns errno %d\n",errno); exit(1); }
1085 pj 175
  cprintf("Û");
176
 
177
  cprintf("T3: ending...\n");
178
 
179
  return 0;
180
}
181
 
182
void t4exit(void *arg)
183
{
184
  cprintf("T4: AAAARRRRGGGHHH!!! killed by someone...\n");
185
}
186
 
187
void *t4(void *arg)
188
{
189
  ssize_t x;
190
  char buf[MESSAGE_LENGTH];
191
  int prio;
192
 
193
  cprintf("T4: waiting t = 2.2 sec.\n");
194
 
195
  while (sys_gettime(NULL)<2200000);
196
  x = mq_receive(mq,buf,MESSAGE_LENGTH,&prio);
197
  cprintf("T4: received message: length=%ld, prio=%d, text=°%s°\n",x,prio,buf);
198
 
199
  while (sys_gettime(NULL)<2400000);
200
  x = mq_receive(mq,buf,MESSAGE_LENGTH,&prio);
201
  cprintf("T4: received message: length=%ld, prio=%d, text=°%s°\n",x,prio,buf);
202
  while (sys_gettime(NULL)<2600000);
203
 
204
  x = mq_receive(mq,buf,MESSAGE_LENGTH,&prio);
205
  cprintf("T4: received message: length=%ld, prio=%d, text=°%s°\n",x,prio,buf);
206
  while (sys_gettime(NULL)<2800000);
207
 
208
  x = mq_receive(mq,buf,MESSAGE_LENGTH,&prio);
209
  cprintf("T4: received message: length=%ld, prio=%d, text=°%s°\n",x,prio,buf);
210
  while (sys_gettime(NULL)<3000000);
211
 
212
  x = mq_receive(mq,buf,MESSAGE_LENGTH,&prio);
213
  cprintf("T4: received message: length=%ld, prio=%d, text=°%s°\n",x,prio,buf);
214
 
215
  pthread_cleanup_push(t4exit,NULL);
216
  x = mq_receive(mq,buf,MESSAGE_LENGTH,&prio);
217
  cprintf("T4: received message: length=%ld, prio=%d, text=°%s°\n",x,prio,buf);
218
  pthread_cleanup_pop(0);
219
 
220
  return 0;
221
}
222
 
223
void signal_handler(int signo, siginfo_t *info, void *extra)
224
{
225
  cprintf("Signal %d code=%s value=%d task=%d time=%ldusec\n",
226
              info->si_signo,
227
              (info->si_code == SI_TIMER) ? "Timer" : "Other",
228
              info->si_value.sival_int,
229
              info->si_task,
230
              sys_gettime(NULL));
231
}
232
 
233
int main(int argc, char **argv)
234
{
235
//  int err;
236
  struct sigaction sig_act;
237
  struct mq_attr attr;
238
 
239
  sig_act.sa_sigaction = (void *) signal_handler;
240
  sig_act.sa_flags = SA_SIGINFO;
241
  sigemptyset(&sig_act.sa_mask);
242
  sigaction(25, &sig_act, NULL);
243
 
244
  // set ev25, evtask
245
  ev25.sigev_notify           = SIGEV_SIGNAL;
246
  ev25.sigev_signo            = 25;
247
  ev25.sigev_value.sival_int  = 555;
248
 
249
  evtask.sigev_notify            = SIGEV_THREAD;
250
  evtask.sigev_value.sival_int   = 777;
251
  evtask.sigev_notify_function   = t2;
252
  evtask.sigev_notify_attributes = &task_attr;
253
 
254
  // set pthread attributes
255
  pthread_attr_init(&task_attr);
256
  pthread_attr_setdetachstate(&task_attr, PTHREAD_CREATE_DETACHED);
257
  pthread_attr_setschedpolicy(&task_attr, SCHED_FIFO);
258
  task_param.sched_priority = 10;
259
  pthread_attr_setschedparam(&task_attr, &task_param);
260
 
261
  // set mqueue attributes
262
  attr.mq_flags   = 0;
263
  attr.mq_maxmsg  = 3;
264
  attr.mq_msgsize = MESSAGE_LENGTH;
265
 
266
  // create the message queue
267
  if ((mq = mq_open("mq", O_CREAT|O_RDWR, 0, &attr)) == -1)
268
  { cprintf("main: mq_open returns errno %d\n",errno); return 0; }
269
 
270
  if (mq_notify(mq, &evtask))
271
  { cprintf("main: mq_notify returns errno %d\n",errno); return 0; }
272
 
273
  cprintf("main: created mq, creating T1...\n");
274
 
275
  pthread_create(&T1, NULL, t1, NULL);
276
 
277
  cprintf("main: waiting t= 3.5 sec., then kill T4...\n");
278
 
279
  while (sys_gettime(NULL)<3500000);
280
 
281
  pthread_cancel(T4);
282
 
283
  cprintf("main: ending...\n");
284
 
285
  return 0;
286
}