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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [rtems/] [c/] [src/] [tests/] [psxtests/] [psxmsgq01/] [init.c] - Blame information for rev 609

Go to most recent revision | Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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