Subversion Repositories shark

Rev

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