OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [rtems-20020807/] [c/] [src/] [tests/] [psxtests/] [psxmsgq01/] [init.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1026 ivang
/*
2
 *  COPYRIGHT (c) 1989-1999.
3
 *  On-Line Applications Research Corporation (OAR).
4
 *
5
 *  The license and distribution terms for this file may be
6
 *  found in the file LICENSE in this distribution or at
7
 *  http://www.OARcorp.com/rtems/license.html.
8
 *
9
 *  init.c,v 1.9 2002/08/02 00:53:21 joel Exp
10
 */
11
 
12
#define CONFIGURE_INIT
13
#include "system.h"
14
#include <sched.h>
15
#include <fcntl.h>
16
#include <time.h>
17
#include <tmacros.h>
18
#include <signal.h>   /* signal facilities */
19
 
20
typedef struct {
21
  char         msg[ 50 ];
22
  int          size;
23
  unsigned int priority;
24
}Test_Message_t;
25
Test_Message_t Predefined_Msgs[MAXMSG+1];
26
Test_Message_t Predefined_Msgs[MAXMSG+1] = {
27
  { "12345678",   9, MQ_PRIO_MAX-1 },  /* Max Length Message med  */
28
  { "",           1, 1             },  /* NULL  Message      low  */
29
  { "Last",       5, MQ_PRIO_MAX   },  /* Queue Full Message hi   */
30
  { "No Message", 0, MQ_PRIO_MAX-1 },  /* 0 length Message   med  */
31
  { "1",          2, 0             },  /* Cause Overflow Behavior */
32
};
33
int Priority_Order[MAXMSG+1] = { 2, 0, 3, 1, MAXMSG };
34
 
35
 
36
typedef struct {
37
  mqd_t              mq;
38
  Test_Queue_Types   index;
39
  char              *name;
40
  int                oflag;
41
  int                maxmsg;
42
  int                msgsize;
43
  int                count;
44
} Test_queue_type;
45
 
46
Test_queue_type Test_q[ NUMBER_OF_TEST_QUEUES ] =
47
{
48
  { 0, 0, "Qread",    ( O_CREAT | O_RDONLY | O_NONBLOCK ), MAXMSG, MSGSIZE, 0 },
49
  { 0, 1, "Qwrite",   ( O_CREAT | O_WRONLY | O_NONBLOCK ), MAXMSG, MSGSIZE, 0 },
50
  { 0, 2, "Qnoblock", ( O_CREAT | O_RDWR   | O_NONBLOCK ), MAXMSG, MSGSIZE, 0 },
51
  { 0, 3, "Qblock",   ( O_CREAT | O_RDWR )               , MAXMSG, MSGSIZE, 0 },
52
  { 0, 4, "Qdefault", ( O_CREAT | O_RDWR )               , 10,     16,      0 },
53
  { 0, 5, "mq6",      ( O_CREAT | O_WRONLY | O_NONBLOCK ), MAXMSG, MSGSIZE, 0 },
54
};
55
 
56
#define RW_NAME             Test_q[ RW_QUEUE ].name
57
#define DEFAULT_NAME        Test_q[ DEFAULT_RW ].name
58
#define RD_NAME             Test_q[ RD_QUEUE ].name
59
#define WR_NAME             Test_q[ WR_QUEUE ].name
60
#define BLOCKING_NAME       Test_q[ BLOCKING ].name
61
#define CLOSED_NAME         Test_q[ CLOSED ].name
62
 
63
#define RW_ATTR         Test_q[ RW_QUEUE ].oflag
64
#define DEFAULT_ATTR    Test_q[ DEFAULT_RW ].oflag
65
#define RD_ATTR         Test_q[ RD_QUEUE ].oflag
66
#define WR_ATTR         Test_q[ WR_QUEUE ].oflag
67
#define BLOCK_ATTR      Test_q[ BLOCKING ].oflag
68
#define CLOSED_ATTR     Test_q[ CLOSED ].oflag
69
 
70
/*
71
 * Outputs a header at each test section.
72
 */
73
void Start_Test(
74
  char *description
75
)
76
{
77
  printf( "_______________%s\n", description );
78
}
79
 
80
 
81
void Validate_attributes(
82
    mqd_t  mq,
83
    int    oflag,
84
    int    msg_count
85
)
86
{
87
  int             status;
88
  struct mq_attr  attr;
89
 
90
  status = mq_getattr( mq, &attr );
91
  fatal_posix_service_status( status, 0, "mq_getattr valid return status");
92
 
93
  if ( mq != Test_q[ DEFAULT_RW ].mq ){
94
    fatal_int_service_status((int)attr.mq_maxmsg, MAXMSG, "maxmsg attribute" );
95
    fatal_int_service_status((int)attr.mq_msgsize,MSGSIZE,"msgsize attribute");
96
  }
97
 
98
  fatal_int_service_status((int)attr.mq_curmsgs, msg_count, "count attribute" );
99
  fatal_int_service_status((int)attr.mq_flags, oflag, "flag attribute" );
100
}
101
 
102
char Queue_Name[PATH_MAX + 2];
103
#define Get_Queue_Name( i )  Test_q[i].name
104
 
105
char *Build_Queue_Name( int i ) {
106
  sprintf(Queue_Name,"mq%d", i+1 );
107
  return Queue_Name;
108
}
109
 
110
char *Get_Too_Long_Name()
111
{
112
  int i;
113
 
114
  for ( i=0; i< PATH_MAX+1; i++ )
115
    Queue_Name[i] = 'N';
116
  Queue_Name[i] = '\0';
117
  return Queue_Name;
118
}
119
 
120
 
121
void open_test_queues()
122
{
123
  struct mq_attr   attr;
124
  int              status;
125
  Test_queue_type *tq;
126
  int              que;
127
 
128
  attr.mq_maxmsg  = MAXMSG;
129
  attr.mq_msgsize = MSGSIZE;
130
 
131
  puts( "Init: Open Test Queues" );
132
 
133
  for( que = 0; que < NUMBER_OF_TEST_QUEUES; que++ ) {
134
 
135
    tq = &Test_q[ que ];
136
    if ( que == DEFAULT_RW)
137
      Test_q[que].mq = mq_open( tq->name, tq->oflag, 0x777, NULL );
138
    else
139
      Test_q[que].mq = mq_open( tq->name, tq->oflag, 0x777, &attr );
140
 
141
    assert( Test_q[que].mq != (-1) );
142
  }
143
 
144
  status = mq_close( Test_q[CLOSED].mq );
145
  fatal_posix_service_status( status, 0, "mq_close message queue");
146
  status = mq_unlink( CLOSED_NAME );
147
  fatal_posix_service_status( status, 0, "mq_unlink message queue");
148
}
149
 
150
/*
151
 * Opens CONFIGURE_MAXIMUM_POSIX_MESSAGE_QUEUES then leaves size queues
152
 * opened but closes the rest.
153
 */
154
 
155
void validate_mq_open_error_codes()
156
{
157
  int             i;
158
  mqd_t           n_mq2;
159
  struct mq_attr  attr;
160
  int             status;
161
  mqd_t           open_mq[CONFIGURE_MAXIMUM_POSIX_MESSAGE_QUEUES + 1];
162
 
163
  attr.mq_maxmsg  = MAXMSG;
164
  attr.mq_msgsize = MSGSIZE;
165
 
166
  Start_Test( "mq_open errors" );
167
 
168
  /*
169
   * XXX EINVAL - inappropriate name was given for the message queue
170
   */
171
 
172
  /*
173
   * EINVAL - Create with negative maxmsg.
174
   */
175
 
176
  attr.mq_maxmsg = -1;
177
  puts( "Init: mq_open - Create with maxmsg (-1) (EINVAL)" );
178
  n_mq2 = mq_open( "mq2", O_CREAT | O_RDONLY, 0x777, &attr);
179
  fatal_posix_service_status(
180
    (int) n_mq2, (int ) (-1), "mq_open error return status" );
181
  fatal_posix_service_status( errno, EINVAL,  "mq_open errno EINVAL");
182
  attr.mq_maxmsg  = MAXMSG;
183
 
184
  /*
185
   * EINVAL - Create withnegative msgsize.
186
   */
187
 
188
  attr.mq_msgsize = -1;
189
  puts( "Init: mq_open - Create with msgsize (-1) (EINVAL)" );
190
  n_mq2 = mq_open( "mq2", O_CREAT | O_RDONLY, 0x777, &attr);
191
  fatal_posix_service_status(
192
    (int) n_mq2, (int ) (-1), "mq_open error return status" );
193
  fatal_posix_service_status( errno, EINVAL,  "mq_open errno EINVAL");
194
  attr.mq_msgsize = MSGSIZE;
195
 
196
  /*
197
   * ENOENT - Open a non-created file.
198
   */
199
 
200
  puts( "Init: mq_open - Open new mq without create flag (ENOENT)" );
201
  n_mq2 = mq_open( "mq3", O_EXCL | O_RDONLY, 0x777, NULL);
202
  fatal_posix_service_status(
203
    (int) n_mq2, (int ) (-1), "mq_open error return status" );
204
  fatal_posix_service_status( errno, ENOENT,  "mq_open errno ENOENT");
205
 
206
  /*
207
   * XXX EINTR  - call was interrupted by a signal
208
   */
209
 
210
  /*
211
   * ENAMETOOLONG - Give a name greater than PATH_MAX.
212
   */
213
 
214
  puts( "Init: mq_open - Open with too long of a name (ENAMETOOLONG)" );
215
  n_mq2 = mq_open( Get_Too_Long_Name(), O_CREAT | O_RDONLY, 0x777, NULL );
216
  fatal_posix_service_status(
217
    (int) n_mq2, (int ) (-1), "mq_open error return status" );
218
  fatal_posix_service_status( errno, ENAMETOOLONG, "mq_open errno ENAMETOOLONG");
219
 
220
  /*
221
   * XXX - ENAMETOOLONG - Give a name greater than NAME_MAX
222
   *       Per implementation not possible.
223
   */
224
 
225
  /*
226
   * EEXIST - Create an existing queue.
227
   */
228
 
229
  puts( "Init: mq_open - Create an Existing mq (EEXIST)" );
230
  open_mq[0] = mq_open(
231
    Build_Queue_Name(0), O_CREAT | O_RDWR | O_NONBLOCK, 0x777, NULL );
232
  assert( open_mq[0] != (-1) );
233
 
234
  n_mq2 = mq_open(
235
    Build_Queue_Name(0), O_CREAT | O_EXCL | O_RDONLY, 0x777, NULL);
236
  fatal_posix_service_status(
237
    (int) n_mq2, (int ) (-1), "mq_open error return status" );
238
  fatal_posix_service_status( errno, EEXIST,  "mq_open errno EEXIST");
239
 
240
  status = mq_unlink( Build_Queue_Name(0) );
241
  fatal_posix_service_status( status, 0, "mq_unlink message queue");
242
 
243
  status = mq_close( open_mq[0]);
244
  fatal_posix_service_status( status, 0, "mq_close message queue");
245
 
246
  /*
247
   * Open maximum number of message queues
248
   */
249
 
250
  puts( "Init: mq_open - SUCCESSFUL" );
251
  for (i = 0; i < CONFIGURE_MAXIMUM_POSIX_MESSAGE_QUEUES; i++) {
252
    open_mq[i] = mq_open(
253
      Build_Queue_Name(i), O_CREAT | O_RDWR | O_NONBLOCK, 0x777, NULL );
254
    assert( open_mq[i] != (-1) );
255
    assert( open_mq[i] );
256
    /*XXX - Isn't there a more general check */
257
/* JRS     printf( "mq_open 0x%x %s\n", open_mq[i], Build_Queue_Name(i) ); */
258
  }
259
 
260
  /*
261
   * XXX EACCES - permission to create is denied.
262
   */
263
 
264
  /*
265
   * XXX EACCES - queue exists permissions specified by o_flag are denied.
266
   */
267
 
268
  /*
269
   * XXX EMFILE  - Too many message queues in use by the process
270
   */
271
 
272
  /*
273
   * ENFILE -  Too many message queues open in the system
274
   */
275
 
276
  puts( "Init: mq_open - system is out of resources (ENFILE)" );
277
  n_mq2 = mq_open( Build_Queue_Name(i), O_CREAT | O_RDONLY, 0x777, NULL );
278
  fatal_posix_service_status(
279
    (int) n_mq2, (int ) (-1), "mq_open error return status" );
280
  fatal_posix_service_status( errno, ENFILE,  "mq_open errno ENFILE");
281
 
282
  /*
283
   * Unlink and Close all queues.
284
   */
285
 
286
  puts( "Init: mq_close and mq_unlink (mq3...mqn) - SUCCESSFUL" );
287
  for (i = 0; i < CONFIGURE_MAXIMUM_POSIX_MESSAGE_QUEUES; i++) {
288
 
289
    status = mq_close( open_mq[i]);
290
    fatal_posix_service_status( status, 0, "mq_close message queue");
291
 
292
    status = mq_unlink( Build_Queue_Name(i) );
293
    if ( status == -1 )
294
      perror( "mq_unlink" );
295
    fatal_posix_service_status( status, 0, "mq_unlink message queue");
296
    /* JRS printf( "mq_close/mq_unlink 0x%x %s\n", open_mq[i], Build_Queue_Name(i) ); */
297
  }
298
}
299
 
300
void validate_mq_unlink_error_codes()
301
{
302
  int             status;
303
 
304
  Start_Test( "mq_unlink errors" );
305
 
306
  /*
307
   * XXX - EACCES Permission Denied
308
   */
309
 
310
  /*
311
   * ENAMETOOLONG - Give a name greater than PATH_MAX.
312
   */
313
 
314
  puts( "Init: mq_unlink - mq_unlink with too long of a name (ENAMETOOLONG)" );
315
  status = mq_unlink( Get_Too_Long_Name() );
316
  fatal_posix_service_status( status, -1, "mq_unlink error return status");
317
  fatal_posix_service_status( errno, ENAMETOOLONG, "mq_unlink errno ENAMETOOLONG");
318
 
319
  /*
320
   * XXX - ENAMETOOLONG - Give a name greater than NAME_MAX
321
   *       Per implementation not possible.
322
   */
323
 
324
  /*
325
   *  ENOENT - Unlink an unopened queue
326
   */
327
 
328
  puts( "Init: mq_unlink - A Queue not opened  (ENOENT)" );
329
  status = mq_unlink( CLOSED_NAME );
330
  fatal_posix_service_status( status, -1, "mq_unlink error return status");
331
  fatal_posix_service_status( errno, ENOENT, "mq_unlink errno ENOENT");
332
 
333
  /*
334
   * XXX - The following were not listed in the POSIX document as
335
   *       possible errors.  Under other commands the EINVAL is
336
   *       given for these conditions.
337
   */
338
 
339
  /*
340
   *  EINVAL - Unlink a queue with no name
341
   */
342
 
343
  puts( "Init: mq_unlink (NULL) - EINVAL" );
344
  status = mq_unlink( NULL );
345
  fatal_posix_service_status( status, -1, "mq_unlink error return status");
346
  fatal_posix_service_status( errno, EINVAL, "mq_unlink errno value");
347
 
348
  /*
349
   *  EINVAL - Unlink a queue with a null name
350
   */
351
 
352
  puts( "Init: mq_unlink (\"\") - EINVAL" );
353
  status = mq_unlink( "" );
354
  fatal_posix_service_status( status, -1, "mq_unlink error return status");
355
  fatal_posix_service_status( errno, EINVAL, "mq_unlink errno value");
356
}
357
 
358
void validate_mq_close_error_codes()
359
{
360
  int             status;
361
 
362
  Start_Test( "mq_close errors" );
363
 
364
  /*
365
   * EBADF - Close a queue that is not open.
366
   */
367
 
368
  puts( "Init: mq_close - unopened queue (EBADF)" );
369
  status = mq_close( Test_q[CLOSED].mq );
370
  fatal_posix_service_status( status, -1, "mq_close error return status");
371
  fatal_posix_service_status( errno, EBADF, "mq_close errno EBADF");
372
}
373
 
374
 
375
void validate_mq_getattr_error_codes()
376
{
377
  struct mq_attr  attr;
378
  int             status;
379
 
380
  Start_Test( "mq_getattr errors" );
381
 
382
  /*
383
   * EBADF - Get the attributes from a closed queue.
384
   */
385
 
386
  puts( "Init: mq_getattr - unopened queue (EBADF)" );
387
  status = mq_getattr( Test_q[CLOSED].mq, &attr );
388
  fatal_posix_service_status( status, -1, "mq_close error return status");
389
  fatal_posix_service_status( errno, EBADF, "mq_close errno EBADF");
390
 
391
  /*
392
   * XXX - The following are not listed in the POSIX manual but
393
   *       may occur.
394
   */
395
 
396
  /*
397
   * EINVAL - NULL attributes
398
   */
399
 
400
  puts( "Init: mq_getattr - NULL attributes (EINVAL)" );
401
  status = mq_getattr( Test_q[RW_QUEUE].mq, NULL );
402
  fatal_posix_service_status( status, -1, "mq_close error return status");
403
  fatal_posix_service_status( errno, EINVAL, "mq_close errno EINVAL");
404
 
405
}
406
 
407
 
408
void Send_msg_to_que(
409
  int que,
410
  int msg
411
)
412
{
413
  Test_Message_t *ptr = &Predefined_Msgs[msg];
414
  int             status;
415
 
416
  status = mq_send( Test_q[que].mq, ptr->msg, ptr->size , ptr->priority );
417
  fatal_posix_service_status( status, 0, "mq_send valid return status");
418
  Test_q[que].count++;
419
}
420
 
421
void Show_send_msg_to_que(
422
  char *task_name,
423
  int   que,
424
  int   msg
425
)
426
{
427
  Test_Message_t *ptr = &Predefined_Msgs[msg];
428
  printf( "%s mq_send -  to %s msg: %s priority %d\n",
429
    task_name, Test_q[que].name, ptr->msg, ptr->priority);
430
  Send_msg_to_que( que, msg );
431
}
432
 
433
void verify_queues_full(
434
  char *task_name
435
)
436
{
437
  int          que;
438
 
439
  /*
440
   * Validate that the queues are full.
441
   */
442
 
443
  printf( "%s Verify Queues are full\n", task_name );
444
  for( que = RW_QUEUE; que < CLOSED; que++ )
445
    Validate_attributes( Test_q[que].mq, Test_q[que].oflag, Test_q[que].count );
446
 
447
}
448
void verify_queues_empty(
449
  char *task_name
450
)
451
{
452
  int             que;
453
 
454
  printf( "%s Verify Queues are empty\n", task_name );
455
  for( que = RW_QUEUE; que < CLOSED; que++ )
456
    Validate_attributes( Test_q[que].mq, Test_q[que].oflag, 0 );
457
}
458
 
459
int fill_message_queues(
460
  char *task_name
461
)
462
{
463
  int             msg;
464
  int             que;
465
 
466
 
467
  verify_queues_empty( task_name );
468
 
469
  /*
470
   * Fill Queue with predefined messages.
471
   */
472
 
473
  printf( "%s Fill Queues with messages\n", task_name );
474
  for(msg=0; msg<MAXMSG; msg++){
475
    for( que = RW_QUEUE; que < CLOSED; que++ ) {
476
      Send_msg_to_que( que, msg );
477
    }
478
  }
479
 
480
  verify_queues_full( "Init:" );
481
  return msg;
482
}
483
 
484
 
485
void Read_msg_from_que(
486
  int que,
487
  int msg
488
)
489
{
490
  unsigned int    priority;
491
  Test_Message_t *ptr;
492
  int             status;
493
  char            message[100];
494
  char            err_msg[100];
495
 
496
  ptr = &Predefined_Msgs[msg];
497
  status = mq_receive(Test_q[ que ].mq, message, 100, &priority );
498
  Test_q[que].count--;
499
 
500
  sprintf( err_msg, "%s msg %s size failure", Test_q[ que ].name, ptr->msg );
501
  fatal_int_service_status( status, ptr->size, err_msg );
502
 
503
  assert( !strcmp( message, ptr->msg ) );
504
  strcpy( message, "No Message" );
505
 
506
  sprintf( err_msg,"%s msg %s size failure", Test_q[ que ].name, ptr->msg );
507
  fatal_int_service_status(priority, ptr->priority, err_msg );
508
}
509
 
510
int empty_message_queues(
511
  char *task_name
512
)
513
{
514
  int que;
515
  int i;
516
 
517
  printf( "%s Empty all Queues\n", task_name );
518
  for( que = RW_QUEUE; que < CLOSED; que++ ) {
519
    for(i=0; Test_q[que].count != 0; i++ )
520
      Read_msg_from_que( que,  Priority_Order[i] );
521
 
522
    Validate_attributes( Test_q[ que].mq, Test_q[ que ].oflag, 0 );
523
  }
524
  return 0;
525
}
526
 
527
/*
528
 * Returns the number of messages queued after the test on the
529
 * first queue.
530
 */
531
 
532
int validate_mq_send_error_codes( )
533
{
534
  int             status;
535
  int             i;
536
  char           *str;
537
 
538
  Start_Test( "mq_send errors" );
539
 
540
  /*
541
   * EBADF - Write to a closed queue.
542
   */
543
 
544
  puts( "Init: mq_send - Closed message queue (EBADF)" );
545
  status = mq_send( Test_q[CLOSED].mq, "", 1, 0 );
546
  fatal_posix_service_status( status, -1, "mq_send error return status");
547
  fatal_posix_service_status( errno, EBADF, "mq_send errno EBADF");
548
 
549
  /*
550
   * EBADF - Write to a read only  queue.
551
   */
552
 
553
  puts( "Init: mq_send - Read only message queue (EBADF)" );
554
  status = mq_send( Test_q[ RD_QUEUE ].mq, "", 1, 0 );
555
  fatal_posix_service_status( status, -1, "mq_send error return status");
556
  fatal_posix_service_status( errno, EBADF, "mq_send errno EBADF");
557
 
558
  /*
559
   * XXX - EINTR      Signal interrupted the call.
560
   *
561
  puts( "Init: mq_send - UNSUCCESSFUL (EINTR)" );
562
  status = mq_send( Test_q, "", 0xffff, 0 );
563
  fatal_posix_service_status( status, -1, "mq_send error return status");
564
  fatal_posix_service_status( errno, E, "mq_send errno E");
565
   */
566
 
567
  /*
568
   * EINVAL priority is out of range.
569
   */
570
 
571
  puts( "Init: mq_send - Priority out of range (EINVAL)" );
572
  status = mq_send( Test_q[ RW_QUEUE ].mq, "", 1, MQ_PRIO_MAX + 1 );
573
  fatal_posix_service_status( status, -1, "mq_send error return status");
574
  fatal_posix_service_status( errno, EINVAL, "mq_send errno EINVAL");
575
 
576
  /*
577
   *  EMSGSIZE - Message size larger than msg_len
578
   *             Validates that msgsize is stored correctly.
579
   */
580
 
581
  puts( "Init: mq_send - Message longer than msg_len (EMSGSIZE)" );
582
  status = mq_send( Test_q[ RW_QUEUE ].mq, "", MSGSIZE+1, 0 );
583
  fatal_posix_service_status( status, -1, "mq_send error return status");
584
  fatal_posix_service_status( errno, EMSGSIZE, "mq_send errno EMSGSIZE");
585
 
586
  i = fill_message_queues( "Init:" );
587
 
588
  /*
589
   * ENOSYS - send not supported
590
  puts( "Init: mq_send - Blocking Queue overflow (ENOSYS)" );
591
  status = mq_send( n_mq1, Predefined_Msgs[i], 0, 0 );
592
  fatal_posix_service_status( status, -1, "mq_send error return status");
593
  fatal_posix_service_status( errno, EBADF, "mq_send errno EBADF");
594
 
595
  status = mq_close( n_mq1 );
596
  fatal_posix_service_status( status, 0, "mq_close message queue");
597
 
598
  status = mq_unlink( "read_only" );
599
  fatal_posix_service_status( status, 0, "mq_unlink message queue");
600
   */
601
 
602
  /*
603
   * EAGAIN - O_NONBLOCK and message queue is full.
604
   */
605
 
606
  puts( "Init: mq_send - on a FULL non-blocking queue with (EAGAIN)" );
607
  str = Predefined_Msgs[i].msg;
608
  status = mq_send(Test_q[RW_QUEUE].mq, str, 0, 0 );
609
  fatal_posix_service_status( status, -1, "mq_send error return status");
610
  fatal_posix_service_status( errno, EAGAIN, "mq_send errno EAGAIN");
611
 
612
  return i-1;
613
}
614
 
615
void validate_mq_receive_error_codes( )
616
{
617
  int            status;
618
  char           message[100];
619
  unsigned int   priority;
620
 
621
  Start_Test( "mq_receive errors"  );
622
 
623
  /*
624
   * EBADF - Not A Valid Message Queue
625
   */
626
 
627
  puts( "Init: mq_receive - Unopened message queue (EBADF)" );
628
  status = mq_receive( Test_q[CLOSED].mq, message, 100, &priority );
629
  fatal_posix_service_status( status, -1, "mq_ error return status");
630
  fatal_posix_service_status( errno, EBADF, "mq_receive errno EBADF");
631
 
632
  /*
633
   * EBADF - Queue not opened to read
634
   */
635
 
636
  puts( "Init: mq_receive - Write only queue (EBADF)" );
637
  status = mq_receive( Test_q[WR_QUEUE].mq, message, 100, &priority  );
638
  fatal_posix_service_status( status, -1, "mq_ error return status");
639
  fatal_posix_service_status( errno, EBADF, "mq_receive errno EBADF");
640
 
641
  /*
642
   * EMSGSIZE - Size is less than the message size attribute
643
   */
644
 
645
  puts( "Init: mq_receive - Size is less than the message (EMSGSIZE)" );
646
  status = mq_receive(
647
    Test_q[RW_QUEUE].mq, message, Predefined_Msgs[0].size-1, &priority );
648
  fatal_posix_service_status( status, -1, "mq_ error return status");
649
  fatal_posix_service_status( errno, EMSGSIZE, "mq_receive errno EMSGSIZE");
650
 
651
 
652
  /*
653
   * EAGAIN - O_NONBLOCK and Queue is empty
654
   */
655
  verify_queues_full( "Init:" );
656
  empty_message_queues( "Init:" );
657
 
658
  puts( "Init: mq_receive - Queue is empty (EAGAIN)" );
659
  status = mq_receive( Test_q[RW_QUEUE].mq, message, 100, &priority );
660
  fatal_posix_service_status( status, -1, "mq_ error return status");
661
  fatal_posix_service_status( errno, EAGAIN, "mq_receive errno EAGAIN");
662
 
663
  /*
664
   * XXX - EINTR - Interrupted by a signal
665
   */
666
 
667
  /*
668
   * XXX - EBADMSG - a data corruption problem.
669
   */
670
 
671
  /*
672
   * XXX - ENOSYS - mq_receive not supported
673
   */
674
}
675
 
676
void verify_open_functionality()
677
{
678
  mqd_t           n_mq;
679
 
680
  Start_Test( "mq_open functionality" );
681
 
682
  /*
683
   * Validate a second open returns the same message queue.
684
   */
685
 
686
#if 0
687
  puts( "Init: mq_open - Open an existing mq ( same id )" );
688
  n_mq = mq_open( RD_NAME, 0 );
689
  fatal_posix_service_status(
690
    (int) n_mq, (int ) Test_q[RD_QUEUE].mq, "mq_open error return status" );
691
#endif
692
}
693
 
694
void verify_unlink_functionality()
695
{
696
  mqd_t           n_mq;
697
  int             status;
698
 
699
  Start_Test( "mq_unlink functionality" );
700
 
701
  /*
702
   * Unlink the message queue, then verify an open of the same name produces a
703
   * different message queue.
704
   */
705
 
706
  puts( "Init: Unlink and Open without closing SUCCESSFUL" );
707
  status = mq_unlink( DEFAULT_NAME );
708
  fatal_posix_service_status( status, 0, "mq_unlink locked message queue");
709
 
710
  n_mq = mq_open( DEFAULT_NAME, DEFAULT_ATTR, 0x777, NULL );
711
  assert( n_mq != (-1) );
712
  assert( n_mq != Test_q[ DEFAULT_RW ].mq );
713
 
714
 
715
  status = mq_unlink( DEFAULT_NAME );
716
  fatal_posix_service_status( status, 0, "mq_unlink locked message queue");
717
  status = mq_close( Test_q[ DEFAULT_RW ].mq );
718
  fatal_posix_service_status( status, 0, "mq_close message queue");
719
 
720
  Test_q[ DEFAULT_RW ].mq = n_mq;
721
}
722
 
723
void verify_close_functionality()
724
{
725
  int i;
726
  int status;
727
  Start_Test( "Unlink and Close All Files"  );
728
  for (i=0; i<DEFAULT_RW; i++) {
729
 
730
    status = mq_unlink( Get_Queue_Name(i) );
731
    fatal_posix_service_status( status, 0, "mq_unlink message queue");
732
 
733
    status = mq_close( Test_q[i].mq );
734
    fatal_posix_service_status( status, 0, "mq_close message queue");
735
  }
736
}
737
 
738
 
739
void verify_timed_send_queue(
740
  int  que,
741
  int  is_blocking
742
)
743
{
744
  struct timespec timeout;
745
  struct timeval  tv1, tv2, tv3;
746
  struct timezone tz1, tz2;
747
  int              len;
748
  int              status;
749
  char            *msg;
750
 
751
  timeout.tv_sec  = 1;
752
  timeout.tv_nsec = 0;
753
 
754
  printf( "Init: mq_timedsend - on queue %s ", Test_q[que].name);
755
  len = Predefined_Msgs[MAXMSG].size;
756
  msg = Predefined_Msgs[MAXMSG].msg;
757
  gettimeofday( &tv1, &tz1 );
758
  status = mq_timedsend( Test_q[que].mq, msg, len , 0, &timeout );
759
  gettimeofday( &tv2, &tz2 );
760
  tv3.tv_sec  = tv2.tv_sec - tv1.tv_sec;
761
  tv3.tv_usec = tv2.tv_usec - tv1.tv_usec;
762
 
763
  if ( is_blocking ) { /* Don't verify the non-blocking queue */
764
    fatal_int_service_status( status, -1, "mq_timedsend status");
765
    fatal_posix_service_status( errno, ETIMEDOUT,  "errno ETIMEDOUT");
766
  }
767
 
768
  printf("Init: %d sec %d us\n", tv3.tv_sec, tv3.tv_usec );
769
 
770
  if ( is_blocking ) /* non-blocking queue */
771
    assert( tv3.tv_sec == 1 );
772
  else
773
    assert( tv3.tv_sec == 0 );
774
 
775
  if ( que == DEFAULT_RW )
776
    Test_q[que].count++;
777
}
778
 
779
void verify_timed_send()
780
{
781
  int              que;
782
 
783
  Start_Test( "mq_timedsend"  );
784
 
785
  for( que = RW_QUEUE; que < CLOSED; que++ ) {
786
    if ( que == BLOCKING )
787
      verify_timed_send_queue( que, 1 );
788
    else
789
      verify_timed_send_queue( que, 0 );
790
  }
791
}
792
 
793
void verify_timed_receive_queue(
794
  char *task_name,
795
  int   que,
796
  int   is_blocking
797
)
798
{
799
  char message[ 100 ];
800
  unsigned int priority;
801
  struct timespec tm;
802
  struct timeval  tv1, tv2, tv3;
803
  struct timezone tz1, tz2;
804
  int              status;
805
 
806
  tm.tv_sec  = 1;
807
  tm.tv_nsec = 0;
808
 
809
  printf( "Init: %s mq_timedreceive - on queue %s ", task_name, Test_q[que].name);
810
 
811
  gettimeofday( &tv1, &tz1 );
812
  status = mq_timedreceive( Test_q[ que ].mq, message, 100, &priority, &tm );
813
  gettimeofday( &tv2, &tz2 );
814
  tv3.tv_sec  = tv2.tv_sec - tv1.tv_sec;
815
  tv3.tv_usec = tv2.tv_usec - tv1.tv_usec;
816
 
817
  fatal_int_service_status( status, -1, "mq_timedreceive status");
818
  if ( is_blocking )
819
    fatal_posix_service_status( errno, ETIMEDOUT,  "errno ETIMEDOUT");
820
  printf( "Init: %d sec %d us\n", tv3.tv_sec, tv3.tv_usec );
821
 
822
  if ( is_blocking )
823
    assert( tv3.tv_sec == 1 );
824
  else
825
    assert( tv3.tv_sec == 0 );
826
}
827
 
828
 
829
 
830
void verify_timed_receive()
831
{
832
  int  que;
833
 
834
  Start_Test( "mq_timedreceive"  );
835
 
836
  for( que = RW_QUEUE; que < CLOSED; que++ ) {
837
    if (( que == BLOCKING ) || ( que == DEFAULT_RW ))
838
      verify_timed_receive_queue( "Init:", que, 1 );
839
    else
840
      verify_timed_receive_queue( "Init:", que, 0 );
841
  }
842
}
843
 
844
#if (0)
845
void verify_set_attr()
846
{
847
  struct mq_attr save_attr[ NUMBER_OF_TEST_QUEUES ];
848
  struct mq_attr attr;
849
  int            i;
850
  int            status;
851
 
852
  attr.mq_maxmsg  = 0;
853
  attr.mq_msgsize = 0;
854
 
855
  Start_Test( "mq_setattr"  );
856
 
857
  puts( "Init: set_attr all queues to blocking" );
858
  for(i=0; i<CLOSED; i++) {
859
    attr.mq_flags =  Test_q[i].oflag & (~O_NONBLOCK );
860
    status = mq_setattr( Test_q[i].mq, &attr, &save_attr[i] );
861
    fatal_int_service_status( status, 0, "mq_setattr valid return status");
862
 
863
    Validate_attributes( Test_q[i].mq, attr.mq_flags, 0 );
864
  }
865
 
866
  for( i = RW_QUEUE; i < CLOSED; i++ ) {
867
    verify_timed_receive_queue( "Init:", i, 1 );
868
  }
869
 
870
  for(i=0; i<CLOSED; i++) {
871
    attr.mq_flags =  Test_q[i].oflag & (~O_NONBLOCK );
872
    status = mq_setattr( Test_q[i].mq, &save_attr[i], NULL );
873
    fatal_int_service_status( status, 0, "mq_setattr valid return status");
874
 
875
    Validate_attributes( Test_q[i].mq, Test_q[i].oflag, 0 );
876
  }
877
}
878
#endif
879
 
880
void wait_for_signal(
881
  sigset_t     *waitset,
882
  int           sec,
883
  int           expect_signal
884
)
885
{
886
  siginfo_t         siginfo;
887
  int               status;
888
  struct timespec   timeout;
889
  int               signo;
890
 
891
  siginfo.si_code = -1;
892
  siginfo.si_signo = -1;
893
  siginfo.si_value.sival_int = -1;
894
 
895
  timeout.tv_sec = sec;
896
  timeout.tv_nsec = 0;
897
 
898
  status = sigemptyset( waitset );
899
  assert( !status );
900
 
901
  status = sigaddset( waitset, SIGUSR1 );
902
  assert( !status );
903
 
904
  printf( "waiting on any signal for %d seconds.\n", sec );
905
  signo = sigtimedwait( waitset, &siginfo, &timeout );
906
  if (expect_signal) {
907
    fatal_int_service_status( signo, SIGUSR1, "got SISUSR1" );
908
  } else {
909
    fatal_int_service_status( signo, -1, "error return status");
910
    fatal_posix_service_status( errno, EAGAIN, "errno EAGAIN");
911
  }
912
}
913
 
914
void verify_notify()
915
{
916
  struct sigevent event;
917
  int             status;
918
  timer_t         timer_id;
919
  sigset_t        set;
920
 
921
  Start_Test( "mq_notify"  );
922
 
923
  /* timer create */
924
  event.sigev_notify = SIGEV_SIGNAL;
925
  event.sigev_signo  = SIGUSR1;
926
  if (timer_create (CLOCK_REALTIME, &event, &timer_id) == -1)
927
    fatal_posix_service_status( errno, 0,  "errno ETIMEDOUT");
928
 
929
  /* block the timer signal */
930
  sigemptyset( &set );
931
  sigaddset( &set, SIGUSR1 );
932
  pthread_sigmask( SIG_BLOCK, &set, NULL );
933
 
934
  /*
935
   * EBADF - Not A Valid Message Queue
936
   */
937
 
938
  puts( "Init: mq_notify - Unopened message queue (EBADF)" );
939
  status = mq_notify( Test_q[CLOSED].mq, NULL );
940
  fatal_posix_service_status( status, -1, "mq_ error return status");
941
  fatal_posix_service_status( errno, EBADF, "mq_receive errno EBADF");
942
 
943
  /*
944
   * Create ...
945
   */
946
 
947
  /*
948
   * XXX setup notification
949
   */
950
 
951
  printf( "_____mq_notify - notify when %s gets a message\n",RW_NAME);
952
  status = mq_notify( Test_q[RW_QUEUE].mq, &event );
953
  fatal_posix_service_status( status, 0, "mq_notify valid status");
954
  wait_for_signal( &set, 3, 0 );
955
 
956
  /*
957
   * Send and verify signal occurs and registration is removed.
958
   */
959
 
960
  puts( "Init: Verify Signal when send" );
961
  Show_send_msg_to_que( "Init:", RW_QUEUE, 0 );
962
  wait_for_signal( &set, 3, 1 );
963
  Read_msg_from_que( RW_QUEUE, 0 );
964
 
965
  puts( "Init: Verify No Signal when send" );
966
  Show_send_msg_to_que( "Init:", RW_QUEUE, 0 );
967
  wait_for_signal( &set, 3, 0 );
968
  Read_msg_from_que( RW_QUEUE, 0 );
969
 
970
 
971
  /*
972
   * EBUSY - Already Registered
973
   */
974
 
975
  printf( "____mq_notify - notify when %s gets a message\n",RD_NAME);
976
  status = mq_notify( Test_q[RW_QUEUE].mq, &event );
977
  fatal_posix_service_status( status, 0, "mq_notify valid status");
978
  wait_for_signal( &set, 3, 0 );
979
 
980
  puts( "Init: mq_notify -  (EBUSY)" );
981
  status = mq_notify( Test_q[RW_QUEUE].mq, &event );
982
  fatal_posix_service_status( status, -1, "mq_notify error return status");
983
  fatal_posix_service_status( errno, EBUSY, "mq_notify errno EBUSY");
984
 
985
  /*
986
   * Verify NULL removes registration.
987
   */
988
 
989
  puts( "Init: mq_notify - Remove notification with null" );
990
  status = mq_notify( Test_q[RW_QUEUE].mq, NULL );
991
  fatal_posix_service_status( status, 0, "mq_notify valid status");
992
 
993
  puts( "Init: Verify No Signal when send" );
994
  Show_send_msg_to_que( "Init:", RW_QUEUE, 0 );
995
  wait_for_signal( &set, 3, 0 );
996
  Read_msg_from_que( RW_QUEUE, 0 );
997
 
998
}
999
 
1000
void verify_with_threads()
1001
{
1002
  int               status;
1003
  pthread_t         id;
1004
  Test_Message_t   *ptr;
1005
  unsigned int      priority;
1006
  char              message[100];
1007
 
1008
 
1009
  /*
1010
   * Create a task then block until the task sends the message.
1011
   * Task tests set attributes so one queue will have a thread
1012
   * blocked while attributes are changed.
1013
   */
1014
 
1015
  Start_Test( "multi-thread Task 4 Receive Test"  );
1016
  status = pthread_create( &id, NULL, Task_4, NULL );
1017
  assert( !status );
1018
  puts( "Init: mq_receive - Empty queue changes to non-blocking (EAGAIN)" );
1019
  status = mq_receive( Test_q[BLOCKING].mq, message, 100, &priority );
1020
  fatal_int_service_status( status, -1, "mq_receive error return status");
1021
  fatal_posix_service_status( errno, EAGAIN, "mq_receive errno EAGAIN");
1022
  print_current_time( "Init: ", "" );
1023
 
1024
  /*
1025
   * Create a task then block until the task sends the message.
1026
   * Task tests set attributes so one queue will have a thread
1027
   * blocked while attributes are changed.
1028
   */
1029
 
1030
  Start_Test( "multi-thread Task 1 Test"  );
1031
  status = pthread_create( &id, NULL, Task_1, NULL );
1032
  assert( !status );
1033
  Read_msg_from_que(  BLOCKING, 0 ); /* Block until init writes */
1034
  print_current_time( "Init: ", "" );
1035
 
1036
  /*
1037
   * Create a task then block until the task reads a message.
1038
   */
1039
 
1040
  Start_Test( "multi-thread Task 4 Send Test"  );
1041
  fill_message_queues( "Init:" );
1042
  status = pthread_create( &id, NULL, Task_4, NULL );
1043
  assert( !status );
1044
  puts( "Init: mq_send - Full queue changes to non-blocking (EAGAIN)" );
1045
  status = mq_send(Test_q[BLOCKING].mq, message, 0, 0 );
1046
  fatal_posix_service_status( status, -1, "mq_send error return status");
1047
  fatal_posix_service_status( errno, EAGAIN, "mq_send errno EAGAIN");
1048
  verify_queues_full( "Init:" );
1049
  empty_message_queues( "Init:" );
1050
 
1051
  /*
1052
   * Create a task then block until the task reads a message.
1053
   */
1054
 
1055
  Start_Test( "multi-thread Task 2 Test"  );
1056
  fill_message_queues( "Init:" );
1057
  status = pthread_create( &id, NULL, Task_2, NULL );
1058
  assert( !status );
1059
  Show_send_msg_to_que( "Init:", BLOCKING, Priority_Order[0] );
1060
  print_current_time( "Init: ", "" );
1061
  verify_queues_full( "Init:" );
1062
  empty_message_queues( "Init:" );
1063
 
1064
  /*
1065
   * Create a task then block until it deletes and closes all queues.
1066
   *     EBADF - Queue unlinked and closed while blocked
1067
   */
1068
 
1069
  Start_Test( "multi-thread Task 3 Test"  );
1070
  fill_message_queues( "Init:" );
1071
  status = pthread_create( &id, NULL, Task_3, NULL );
1072
  assert( !status );
1073
  puts( "Init: mq_send - Block while thread deletes queue (EBADF)" );
1074
  ptr = &Predefined_Msgs[0];
1075
  status = mq_send( Test_q[BLOCKING].mq, ptr->msg, ptr->size , ptr->priority );
1076
  fatal_posix_service_status( status, -1, "mq_send error return status");
1077
  fatal_posix_service_status( errno, EBADF, "mq_send errno EBADF");
1078
 
1079
}
1080
 
1081
void validate_mq_setattr()
1082
{
1083
  struct mq_attr  attr;
1084
  struct mq_attr  save_attr[ NUMBER_OF_TEST_QUEUES ];
1085
  int             status;
1086
  int            i;
1087
 
1088
  /*
1089
   * EBADF - Get the attributes from a closed queue.
1090
   */
1091
 
1092
  puts( "Task1:mq_setattr - unopened queue (EBADF)" );
1093
  status = mq_setattr( Test_q[CLOSED].mq, &attr, NULL );
1094
  fatal_posix_service_status( status, -1, "mq_setattr error return status");
1095
  fatal_posix_service_status( errno, EBADF, "mq_setattr errno EBADF");
1096
 
1097
  /*
1098
   * XXX - The following are not listed in the POSIX manual but
1099
   *       may occur.
1100
   */
1101
 
1102
  /*
1103
   * EINVAL - NULL attributes
1104
   */
1105
 
1106
  puts( "Task1:mq_setattr - NULL attributes (EINVAL)" );
1107
  status = mq_setattr( Test_q[RW_QUEUE].mq, NULL, NULL );
1108
  fatal_posix_service_status( status, -1, "mq_setattr error return status");
1109
  fatal_posix_service_status( errno, EINVAL, "mq_setattr errno EINVAL");
1110
 
1111
  /*
1112
   * Verify change queues to blocking, by verifying all queues block
1113
   * for a timed receive.
1114
   */
1115
 
1116
  puts( "Init: set_attr all queues to blocking" );
1117
  for(i=0; i<CLOSED; i++) {
1118
    attr.mq_flags =  Test_q[i].oflag & (~O_NONBLOCK );
1119
    status = mq_setattr( Test_q[i].mq, &attr, &save_attr[i] );
1120
    fatal_int_service_status( status, 0, "mq_setattr valid return status");
1121
    Validate_attributes( Test_q[i].mq, attr.mq_flags, 0 );
1122
  }
1123
  for( i = RW_QUEUE; i < CLOSED; i++ ) {
1124
    verify_timed_receive_queue( "Init:", i, 1 );
1125
  }
1126
 
1127
  /*
1128
   * Restore restore all queues to their old attribute.
1129
   */
1130
 
1131
  for(i=0; i<CLOSED; i++) {
1132
    status = mq_setattr( Test_q[i].mq, &save_attr[i], NULL );
1133
    fatal_int_service_status( status, 0, "mq_setattr valid return status");
1134
    Validate_attributes( Test_q[i].mq, Test_q[i].oflag, 0 );
1135
  }
1136
}
1137
 
1138
void *POSIX_Init(
1139
  void *argument
1140
)
1141
{
1142
  puts( "\n\n*** POSIX MESSAGE QUEUE TEST ***" );
1143
 
1144
  validate_mq_open_error_codes( );
1145
  open_test_queues();
1146
  validate_mq_unlink_error_codes();
1147
  validate_mq_close_error_codes();
1148
  verify_unlink_functionality();
1149
  validate_mq_setattr( );
1150
  validate_mq_send_error_codes();
1151
  validate_mq_getattr_error_codes();
1152
  verify_timed_send();
1153
  validate_mq_receive_error_codes();
1154
  verify_timed_receive();
1155
  verify_open_functionality();
1156
  verify_notify();
1157
  verify_with_threads();
1158
 
1159
  puts( "*** END OF POSIX MESSAGE QUEUE TEST ***" );
1160
  rtems_test_exit( 0 );
1161
 
1162
  return NULL; /* just so the compiler thinks we returned something */
1163
}
1164
 
1165
 
1166
void *Task_1 (
1167
  void *argument
1168
)
1169
{
1170
  /* Block Waiting for a message */
1171
 
1172
  print_current_time( "Task_1: ", "" );
1173
 
1174
  Show_send_msg_to_que( "Task_1:", BLOCKING, 0 );
1175
 
1176
  puts( "Task_1: pthread_exit" );
1177
  pthread_exit( NULL );
1178
 
1179
  /* switch to Init */
1180
 
1181
  assert( 0 );
1182
  return NULL; /* just so the compiler thinks we returned something */
1183
}
1184
 
1185
void *Task_2(
1186
  void *argument
1187
)
1188
{
1189
  print_current_time( "Task_2: ", "" );
1190
 
1191
 
1192
  /* Block waiting to send a message */
1193
 
1194
  verify_queues_full( "Task_2:" );
1195
  Read_msg_from_que( BLOCKING, Priority_Order[0] ); /* Cause context switch */
1196
 
1197
  puts( "Task_2: pthread_exit" );
1198
  pthread_exit( NULL );
1199
 
1200
     /* switch to Init */
1201
 
1202
  return NULL; /* just so the compiler thinks we returned something */
1203
}
1204
 
1205
void *Task_3 (
1206
  void *argument
1207
)
1208
{
1209
 
1210
  print_current_time( "Task_3: ", "" );
1211
 
1212
  /*
1213
   * close and unlink all queues.
1214
   */
1215
 
1216
  verify_close_functionality( "Task_3: " );
1217
  puts( "Task_3: pthread_exit" );
1218
  pthread_exit( NULL );
1219
 
1220
     /* switch to Init */
1221
 
1222
  return NULL; /* just so the compiler thinks we returned something */
1223
 
1224
}
1225
 
1226
void *Task_4 (
1227
  void *argument
1228
)
1229
{
1230
  struct mq_attr  attr;
1231
  int             status;
1232
  int             count;
1233
 
1234
  print_current_time( "Task_4: ", "" );
1235
 
1236
  /*
1237
   * Set the count to the number of messages in the queue.
1238
   */
1239
 
1240
  status = mq_getattr( Test_q[BLOCKING].mq, &attr );
1241
  fatal_posix_service_status( status, 0, "mq_getattr valid return status");
1242
  count = attr.mq_curmsgs;
1243
 
1244
  puts("Task_4: Set queue to non-blocking");
1245
  attr.mq_flags =  Test_q[BLOCKING].oflag | O_NONBLOCK;
1246
  status = mq_setattr( Test_q[BLOCKING].mq, &attr, NULL );
1247
  fatal_int_service_status( status, 0, "mq_setattr valid return status");
1248
  Validate_attributes( Test_q[BLOCKING].mq, attr.mq_flags, count );
1249
 
1250
  puts("Task_4: Return queue to blocking");
1251
  attr.mq_flags =  Test_q[BLOCKING].oflag;
1252
  status = mq_setattr( Test_q[BLOCKING].mq, &attr, NULL );
1253
  fatal_int_service_status( status, 0, "mq_setattr valid return status");
1254
  Validate_attributes( Test_q[BLOCKING].mq, attr.mq_flags, count );
1255
 
1256
  puts( "Task_4: pthread_exit" );
1257
  pthread_exit( NULL );
1258
 
1259
     /* switch to Init */
1260
 
1261
  return NULL; /* just so the compiler thinks we returned something */
1262
 
1263
}
1264
 
1265
void *Task_5 (
1266
  void *argument
1267
)
1268
{
1269
 
1270
  print_current_time( "Task_5: ", "" );
1271
 
1272
  puts( "Task_5: pthread_exit" );
1273
  pthread_exit( NULL );
1274
 
1275
     /* switch to Init */
1276
 
1277
  return NULL; /* just so the compiler thinks we returned something */
1278
 
1279
}
1280
 
1281
void *Task_ (
1282
  void *argument
1283
)
1284
{
1285
 
1286
  print_current_time( "Task_: ", "" );
1287
 
1288
  puts( "Task_: pthread_exit" );
1289
  pthread_exit( NULL );
1290
 
1291
     /* switch to Init */
1292
 
1293
  return NULL; /* just so the compiler thinks we returned something */
1294
 
1295
}
1296
 
1297
 
1298
 
1299
 
1300
 
1301
 
1302
 
1303
 
1304
 
1305
 
1306
 
1307
 
1308
 
1309
 
1310
 
1311
 
1312
 
1313
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.