source: rtems/testsuites/psxtests/psxrwlock01/test.c @ 9a4eca5

5
Last change on this file since 9a4eca5 was b9f95225, checked in by Sebastian Huber <sebastian.huber@…>, on 10/08/14 at 08:31:36

posix: Add auto initializaton for rwlock

  • Property mode set to 100644
File size: 16.6 KB
Line 
1/**
2 *  @file
3 *
4 *  This test exercises the POSIX RWLock manager.
5 */
6
7/*
8 *  COPYRIGHT (c) 1989-2012.
9 *  On-Line Applications Research Corporation (OAR).
10 *
11 *  The license and distribution terms for this file may be
12 *  found in the file LICENSE in this distribution or at
13 *  http://www.rtems.org/license/LICENSE.
14 */
15
16#ifdef HAVE_CONFIG_H
17#include "config.h"
18#endif
19
20#include "tmacros.h"
21#include <stdio.h>
22#include <errno.h>
23#include <stdlib.h>
24
25/* #define __USE_XOPEN2K XXX already defined on GNU/Linux */
26#include <pthread.h>
27
28const char rtems_test_name[] = "PSXRWLOCK 1";
29
30/* forward declarations to avoid warnings */
31void *ReadLockThread(void *arg);
32void *WriteLockThread(void *arg);
33int test_main(void);
34
35#if !HAVE_DECL_PTHREAD_RWLOCK_UNLOCK
36/* FIXME: Newlib should provide the decl. */
37extern int pthread_rwlock_unlock(pthread_rwlock_t *rwlock);
38#endif
39
40#define NUMBER_THREADS 2
41pthread_t ThreadIds[NUMBER_THREADS];
42pthread_rwlock_t RWLock;
43
44/*
45 * Test thread to block for read lock and unlock it
46 */
47void *ReadLockThread(void *arg)
48{
49  int status;
50
51  /*
52   * Detach ourselves so we don't wait for a join that won't happen.
53   */
54  pthread_detach( pthread_self() );
55
56  puts( "ReadThread - pthread_rwlock_rdlock(RWLock) blocking -- OK" );
57  status = pthread_rwlock_rdlock(&RWLock);
58  rtems_test_assert( !status );
59  puts( "ReadThread - pthread_rwlock_rdlock(RWLock) unblocked -- OK" );
60
61  status = pthread_rwlock_unlock(&RWLock);
62  rtems_test_assert( !status );
63  return NULL;
64}
65
66/*
67 * Test thread to block for write lock and unlock it
68 */
69void *WriteLockThread(void *arg)
70{
71  int status;
72
73  /*
74   * Detach ourselves so we don't wait for a join that won't happen.
75   */
76  pthread_detach( pthread_self() );
77
78  puts( "WriteThread - pthread_rwlock_wrlock(RWLock) blocking -- OK" );
79  status = pthread_rwlock_wrlock(&RWLock);
80  rtems_test_assert( !status );
81  puts( "WriteThread - pthread_rwlock_wrlock(RWLock) unblocked -- OK" );
82
83  sleep( 2 );
84
85  puts( "WriteThread - pthread_rwlock_unlock(RWLock) -- OK" );
86  status = pthread_rwlock_unlock(&RWLock);
87  if ( status )
88   printf( "status=%s\n", strerror(status) );
89  rtems_test_assert( !status );
90  return NULL;
91}
92
93/*
94 *  main entry point to the test
95 */
96
97#if defined(__rtems__)
98int test_main(void)
99#else
100int main(
101  int    argc,
102  char **argv
103)
104#endif
105{
106  pthread_rwlock_t     rwlock;
107  pthread_rwlock_t     rwlock2;
108  pthread_rwlockattr_t attr;
109  int                  status;
110  int                  p;
111  int                  i;
112  struct timespec      abstime;
113
114  TEST_BEGIN();
115
116  /*************** NULL POINTER CHECKS *****************/
117  puts( "pthread_rwlockattr_init( NULL ) -- EINVAL" );
118  status = pthread_rwlockattr_init( NULL );
119  rtems_test_assert( status == EINVAL );
120
121  puts( "pthread_rwlockattr_setpshared( NULL, private ) -- EINVAL" );
122  status = pthread_rwlockattr_setpshared( NULL, PTHREAD_PROCESS_PRIVATE );
123  rtems_test_assert( status == EINVAL );
124
125  puts( "pthread_rwlockattr_setpshared( NULL, shared ) -- EINVAL" );
126  status = pthread_rwlockattr_setpshared( NULL, PTHREAD_PROCESS_SHARED );
127  rtems_test_assert( status == EINVAL );
128
129  puts( "pthread_rwlockattr_getpshared( NULL, &p ) -- EINVAL" );
130  status = pthread_rwlockattr_getpshared( NULL, &p );
131  rtems_test_assert( status == EINVAL );
132
133  puts( "pthread_rwlockattr_destroy( NULL ) -- EINVAL" );
134  status = pthread_rwlockattr_destroy( NULL );
135  rtems_test_assert( status == EINVAL );
136
137  /*************** NOT INITIALIZED CHECKS *****************/
138  /* cheat visibility */
139  attr.is_initialized = 0;
140  puts( "pthread_rwlockattr_setpshared( &attr, shared ) -- EINVAL" );
141  status = pthread_rwlockattr_setpshared( &attr, PTHREAD_PROCESS_SHARED );
142  rtems_test_assert( status == EINVAL );
143
144  puts( "pthread_rwlockattr_getpshared( &attr, NULL ) -- EINVAL" );
145  status = pthread_rwlockattr_getpshared( &attr, NULL );
146  rtems_test_assert( status == EINVAL );
147
148  puts( "pthread_rwlockattr_destroy( &attr ) -- EINVAL" );
149  status = pthread_rwlockattr_destroy( &attr );
150  rtems_test_assert( status == EINVAL );
151
152  /*************** BAD PSHARED CHECK *****************/
153  puts( "pthread_rwlockattr_setpshared( &attr, private ) -- EINVAL" );
154  status = pthread_rwlockattr_setpshared( &attr, ~PTHREAD_PROCESS_PRIVATE );
155  rtems_test_assert( status == EINVAL );
156
157  /*************** AUTO INITIALIZATION *****************/
158
159  rwlock = PTHREAD_RWLOCK_INITIALIZER;
160  rwlock2 = PTHREAD_RWLOCK_INITIALIZER;
161
162  status = pthread_rwlock_rdlock( &rwlock );
163  rtems_test_assert( status == 0 );
164
165  status = pthread_rwlock_rdlock( &rwlock2 );
166  rtems_test_assert( status == EINVAL );
167
168  status = pthread_rwlock_destroy( &rwlock );
169  rtems_test_assert( status == 0 );
170
171  status = pthread_rwlock_rdlock( &rwlock2 );
172  rtems_test_assert( status == 0 );
173
174  status = pthread_rwlock_destroy( &rwlock );
175  rtems_test_assert( status == 0 );
176
177  rwlock = PTHREAD_RWLOCK_INITIALIZER;
178  rwlock2 = PTHREAD_RWLOCK_INITIALIZER;
179
180  status = pthread_rwlock_rdlock( &rwlock );
181  rtems_test_assert( status == 0 );
182
183  status = pthread_rwlock_destroy( &rwlock2 );
184  rtems_test_assert( status == EINVAL );
185
186  status = pthread_rwlock_destroy( &rwlock );
187  rtems_test_assert( status == 0 );
188
189  status = pthread_rwlock_destroy( &rwlock2 );
190  rtems_test_assert( status == 0 );
191  rtems_test_assert( rwlock2 != PTHREAD_RWLOCK_INITIALIZER );
192
193  /*************** ACTUALLY WORK THIS TIME *****************/
194  puts( "pthread_rwlockattr_init( &attr ) -- OK" );
195  status = pthread_rwlockattr_init( &attr );
196  rtems_test_assert( status == 0 );
197
198  puts( "pthread_rwlockattr_setpshared( &attr, private ) -- OK" );
199  status = pthread_rwlockattr_setpshared( &attr, PTHREAD_PROCESS_PRIVATE );
200  rtems_test_assert( status == 0 );
201
202  puts( "pthread_rwlockattr_getpshared( &attr, &p ) -- OK" );
203  status = pthread_rwlockattr_getpshared( &attr, &p );
204  rtems_test_assert( status == 0 );
205  rtems_test_assert( p == PTHREAD_PROCESS_PRIVATE );
206
207  puts( "pthread_rwlockattr_setpshared( &attr, shared ) -- OK" );
208  status = pthread_rwlockattr_setpshared( &attr, PTHREAD_PROCESS_SHARED );
209  rtems_test_assert( status == 0 );
210
211  puts( "pthread_rwlockattr_getpshared( &attr, &p ) -- OK" );
212  status = pthread_rwlockattr_getpshared( &attr, &p );
213  rtems_test_assert( status == 0 );
214  rtems_test_assert( p == PTHREAD_PROCESS_SHARED );
215
216  /*************** DESTROY/REUSE CHECK *****************/
217  puts( "pthread_rwlockattr_destroy( &attr ) -- OK" );
218  status = pthread_rwlockattr_destroy( &attr );
219  rtems_test_assert( status == 0 );
220
221  puts( "pthread_rwlockattr_getpshared( &attr, &p ) destroyed -- EINVAL" );
222  status = pthread_rwlockattr_getpshared( &attr, &p );
223  rtems_test_assert( status == EINVAL );
224
225  /*************** NULL ARGUMENT CHECKS *****************/
226  abstime.tv_sec = 0;
227  abstime.tv_nsec = 0;
228
229  puts( "pthread_rwlock_init(NULL, &attr) -- EINVAL" );
230  status = pthread_rwlock_init(NULL, &attr);
231  rtems_test_assert( status == EINVAL );
232
233  puts( "pthread_rwlock_destroy(NULL) -- EINVAL" );
234  status = pthread_rwlock_destroy(NULL);
235  rtems_test_assert( status == EINVAL );
236
237  puts( "pthread_rwlock_rdlock(NULL) -- EINVAL" );
238  status = pthread_rwlock_rdlock(NULL);
239  rtems_test_assert( status == EINVAL );
240
241  puts( "pthread_rwlock_timedrdlock( NULL, &abstime) -- EINVAL" );
242  status = pthread_rwlock_timedrdlock( NULL, &abstime);
243  rtems_test_assert( status == EINVAL );
244
245  puts( "pthread_rwlock_timedrdlock( &rwlock, NULL) -- EINVAL" );
246  status = pthread_rwlock_timedrdlock( &rwlock, NULL);
247  rtems_test_assert( status == EINVAL );
248
249  puts( "pthread_rwlock_tryrdlock(NULL) -- EINVAL" );
250  status = pthread_rwlock_tryrdlock(NULL);
251  rtems_test_assert( status == EINVAL );
252
253  puts( "pthread_rwlock_wrlock(NULL) -- EINVAL" );
254  status = pthread_rwlock_wrlock(NULL);
255  rtems_test_assert( status == EINVAL );
256
257  puts( "pthread_rwlock_timedwrlock( NULL, &abstime) -- EINVAL" );
258  status = pthread_rwlock_timedwrlock( NULL, &abstime );
259  rtems_test_assert( status == EINVAL );
260
261  puts( "pthread_rwlock_timedwrlock( &rwlock, NULL) -- EINVAL" );
262  status = pthread_rwlock_timedwrlock( &rwlock, NULL);
263  rtems_test_assert( status == EINVAL );
264
265  puts( "pthread_rwlock_trywrlock(NULL) -- EINVAL" );
266  status = pthread_rwlock_trywrlock(NULL);
267  rtems_test_assert( status == EINVAL );
268
269  puts( "pthread_rwlock_unlock(NULL) -- EINVAL" );
270  status = pthread_rwlock_unlock(NULL);
271  rtems_test_assert( status == EINVAL );
272
273  /*************** BAD ID CHECK *****************/
274  rwlock = 1;
275  /* make a valid abstime */
276  puts( "clock_gettime(CLOCK_REALTIME, &abstime) -- OK" );
277  status = clock_gettime( CLOCK_REALTIME, &abstime );
278  rtems_test_assert( !status );
279  abstime.tv_sec += 5;
280
281  puts( "pthread_rwlock_destroy(BadId) -- EINVAL" );
282  status = pthread_rwlock_destroy(&rwlock);
283  rtems_test_assert( status == EINVAL );
284
285  puts( "pthread_rwlock_rdlock(BadId) -- EINVAL" );
286  status = pthread_rwlock_rdlock(&rwlock);
287  rtems_test_assert( status == EINVAL );
288
289  puts( "pthread_rwlock_timedrdlock(BadId, &abstime) -- EINVAL" );
290  status = pthread_rwlock_timedrdlock( &rwlock, &abstime);
291  rtems_test_assert( status == EINVAL );
292
293  puts( "pthread_rwlock_tryrdlock(BadId) -- EINVAL" );
294  status = pthread_rwlock_tryrdlock(&rwlock);
295  rtems_test_assert( status == EINVAL );
296
297  puts( "pthread_rwlock_wrlock(BadId) -- EINVAL" );
298  status = pthread_rwlock_wrlock(&rwlock);
299  rtems_test_assert( status == EINVAL );
300
301  puts( "pthread_rwlock_timedwrlock(BadId, &abstime) -- EINVAL" );
302  status = pthread_rwlock_timedwrlock( &rwlock, &abstime );
303  rtems_test_assert( status == EINVAL );
304
305  puts( "pthread_rwlock_trywrlock(BadId) -- EINVAL" );
306  status = pthread_rwlock_trywrlock(&rwlock);
307  rtems_test_assert( status == EINVAL );
308
309  puts( "pthread_rwlock_unlock(BadId) -- EINVAL" );
310  status = pthread_rwlock_unlock(&rwlock);
311  rtems_test_assert( status == EINVAL );
312
313  /*************** BAD ABSTIME CHECK *****************/
314
315  /* in the past */
316  abstime.tv_sec = 0;
317  abstime.tv_nsec = 0;
318
319  /* invalid tv_nsec */
320  abstime.tv_sec = 0;
321  abstime.tv_nsec = 0x7fffffffL;
322
323  /* XXX do we need bad time check? */
324
325  /*************** ACTUALLY CREATE ONE CHECK *****************/
326  puts( "pthread_rwlockattr_init( &attr ) -- OK" );
327  status = pthread_rwlockattr_init( &attr );
328  rtems_test_assert( status == 0 );
329
330  puts( "pthread_rwlock_init( &rwlock, &attr ) -- OK" );
331  status = pthread_rwlock_init( &rwlock, &attr );
332  rtems_test_assert( status == 0 );
333  rtems_test_assert( rwlock != 0 );
334
335  puts( "pthread_rwlock_init( &rwlock, &attr ) -- EAGAIN" );
336  status = pthread_rwlock_init( &rwlock, &attr );
337  rtems_test_assert( status == EAGAIN );
338
339  puts( "pthread_rwlock_destroy( &rwlock ) -- OK" );
340  status = pthread_rwlock_destroy( &rwlock );
341  rtems_test_assert( status == 0 );
342
343  /********* CREATE RWLOCK WITH DEFAULT ATTRIBUTES AND DESTROY IT *********/
344  puts( "pthread_rwlock_init( &rwlock, NULL ) -- OK" );
345  status = pthread_rwlock_init( &rwlock, NULL );
346  rtems_test_assert( status == 0 );
347
348  puts( "pthread_rwlock_destroy( &rwlock ) -- OK" );
349  status = pthread_rwlock_destroy( &rwlock );
350  rtems_test_assert( status == 0 );
351
352  /*************** CREATE THREADS AND LET THEM OBTAIN READLOCK ***************/
353  puts( "pthread_rwlock_init( &RWLock, &attr ) -- OK" );
354  status = pthread_rwlock_init( &RWLock, &attr );
355  rtems_test_assert( status == 0 );
356
357  puts( "pthread_rwlock_tryrdlock(RWLock) -- OK" );
358  status = pthread_rwlock_tryrdlock(&RWLock);
359  rtems_test_assert( !status );
360
361  for (i=0 ; i<NUMBER_THREADS ; i++ ) {
362    printf( "Init: pthread_create - thread %d OK\n", i+1 );
363    status = pthread_create(&ThreadIds[i], NULL, ReadLockThread, &ThreadIds[i]);
364    rtems_test_assert( !status );
365
366    sleep(1);
367  }
368
369  puts( "pthread_rwlock_unlock(RWLock) -- OK" );
370  status = pthread_rwlock_unlock(&RWLock);
371  rtems_test_assert( !status );
372
373  sleep(1);
374
375  /*************** CREATE THREADS AND LET THEM OBTAIN READLOCK ***************/
376  puts( "pthread_rwlock_trywrlock(RWLock) -- OK" );
377  status = pthread_rwlock_trywrlock(&RWLock);
378  rtems_test_assert( !status );
379
380  puts( "pthread_rwlock_tryrdlock(&RWLock) -- EBUSY" );
381  status = pthread_rwlock_tryrdlock(&RWLock);
382  rtems_test_assert( status == EBUSY );
383
384  for (i=0 ; i<NUMBER_THREADS ; i++ ) {
385    printf( "Init: pthread_create - thread %d OK\n", i+1 );
386    status = pthread_create(&ThreadIds[i], NULL, ReadLockThread, &ThreadIds[i]);
387    rtems_test_assert( !status );
388
389    sleep(1);
390  }
391
392  /* Attempt delete while threads are blocked */
393  puts( "pthread_rwlock_destroy( &RWLock ) -- EBUSY" );
394  status = pthread_rwlock_destroy( &RWLock );
395  rtems_test_assert( status == EBUSY );
396
397  /* now unlock it so the threads can continue */
398  puts( "pthread_rwlock_unlock(RWLock) -- OK" );
399  status = pthread_rwlock_unlock(&RWLock);
400  rtems_test_assert( !status );
401
402  sleep(2);
403
404  /*************** CREATE THREADS AND LET THEM OBTAIN WRITE LOCK *************/
405  puts( "\npthread_rwlock_trywrlock(RWLock) -- OK" );
406  status = pthread_rwlock_trywrlock(&RWLock);
407  rtems_test_assert( !status );
408
409  puts( "pthread_rwlock_trywrlock(&RWLock) -- EBUSY" );
410  status = pthread_rwlock_trywrlock(&RWLock);
411  rtems_test_assert( status == EBUSY );
412
413  for (i=0 ; i<NUMBER_THREADS ; i++ ) {
414    printf( "Init: pthread_create - thread %d OK\n", i+1 );
415    status =
416      pthread_create(&ThreadIds[i], NULL, WriteLockThread, &ThreadIds[i]);
417    rtems_test_assert( !status );
418
419    sleep(2);
420  }
421
422  puts( "pthread_rwlock_unlock(RWLock) -- OK" );
423  status = pthread_rwlock_unlock(&RWLock);
424  rtems_test_assert( !status );
425
426  sleep(6);
427
428  /*************** CREATE THREADS AND LET THEM OBTAIN WRITE LOCK *************/
429  /***************    THEN ATTEMPT TO OBTAIN A READLOCK          *************/
430 
431  puts( "\npthread_rwlock_tryrdlock(&RWLock) -- OK" );
432  status = pthread_rwlock_tryrdlock(&RWLock);
433  rtems_test_assert( !status );
434
435  printf( "Init: pthread_create - thread reader & writer OK\n" );
436  status = pthread_create(&ThreadIds[0], NULL, WriteLockThread, &ThreadIds[0]);
437  rtems_test_assert( !status );
438
439  sleep(1);
440  status = pthread_create(&ThreadIds[1], NULL, ReadLockThread, &ThreadIds[1]);
441  rtems_test_assert( !status );
442
443  sleep(1);
444
445  puts( "pthread_rwlock_tryrdlock(&RWLock) -- EBUSY" );
446  status = pthread_rwlock_tryrdlock(&RWLock);
447  rtems_test_assert( status == EBUSY );
448
449  puts( "pthread_rwlock_trywrlock(&RWLock) -- EBUSY" );
450  status = pthread_rwlock_trywrlock(&RWLock);
451  rtems_test_assert( status == EBUSY );
452
453  sleep( 5 );
454
455  puts( "pthread_rwlock_unlock(&RWLock) -- OK" );
456  status = pthread_rwlock_unlock(&RWLock);
457  rtems_test_assert( !status );
458
459  sleep( 5 );
460
461  /*************** TIMEOUT ON RWLOCK ***************/
462  puts( "clock_gettime(CLOCK_REALTIME, &abstime) -- OK" );
463  status = clock_gettime( CLOCK_REALTIME, &abstime );
464  rtems_test_assert( !status );
465
466  abstime.tv_sec += 1;
467  puts( "pthread_rwlock_timedwrlock( &RWLock, &abstime) -- OK" );
468  status = pthread_rwlock_timedwrlock( &RWLock, &abstime );
469  rtems_test_assert( status == 0 );
470
471  abstime.tv_sec += 1;
472  puts( "pthread_rwlock_timedrdlock( &RWLock, &abstime) -- ETIMEDOUT" );
473  status = pthread_rwlock_timedrdlock( &RWLock, &abstime );
474  rtems_test_assert( status == ETIMEDOUT );
475
476  abstime.tv_sec -= 1;
477  puts( "pthread_rwlock_timedrdlock( &RWLock, &abstime) -- ETIMEDOUT" );
478  status = pthread_rwlock_timedrdlock( &RWLock, &abstime );
479  rtems_test_assert( status == ETIMEDOUT );
480
481  abstime.tv_sec -= 1;
482  puts( "pthread_rwlock_timedwrlock( &RWLock, &abstime) -- ETIMEDOUT" );
483  status = pthread_rwlock_timedwrlock( &RWLock, &abstime );
484  rtems_test_assert( status == ETIMEDOUT );
485
486  /*************** OBTAIN RWLOCK WITH ABSTIME IN PAST ***************/
487  status = pthread_rwlock_unlock(&RWLock);
488  rtems_test_assert( !status );
489
490  abstime.tv_sec -= 1;
491  puts( "pthread_rwlock_timedrdlock( &RWLock, &abstime) -- in past -- OK" );
492  status = pthread_rwlock_timedrdlock( &RWLock, &abstime );
493  rtems_test_assert( status == 0 );
494
495  /*************** OBTAIN RWLOCK FOR WRITE WITH ABSTIME IN PAST ***************/
496  status = pthread_rwlock_unlock(&RWLock);
497  rtems_test_assert( !status );
498
499  abstime.tv_sec -= 1;
500  puts( "pthread_rwlock_timedwrlock( &RWLock, &abstime) -- in past -- OK" );
501  status = pthread_rwlock_timedwrlock( &RWLock, &abstime );
502  rtems_test_assert( status == 0 );
503
504  /*************** DESTROY RWLOCK ***************/
505  puts( "pthread_rwlock_destroy( &RWLock ) -- OK" );
506  status = pthread_rwlock_destroy( &RWLock );
507  rtems_test_assert( status == 0 );
508
509  /*************** OBTAIN A LOCK AND THEN RELEASE IT TWICE ***************/
510
511  puts( "pthread_rwlock_init( &rwlock, NULL ) -- OK" );
512  status = pthread_rwlock_init( &rwlock, NULL );
513  rtems_test_assert( status == 0 );
514  rtems_test_assert( rwlock != 0 );
515
516  puts( "pthread_rwlock_unlock ( &rwlock ) -- OK" );
517  status = pthread_rwlock_unlock( &rwlock );
518  rtems_test_assert( status == 0 );
519
520  puts( "pthread_rwlock_unlock ( &rwlock ) -- OK" );
521  status = pthread_rwlock_unlock( &rwlock );
522  rtems_test_assert( status == 0 );
523
524  /*************** END OF TEST *****************/
525  TEST_END();
526  exit(0);
527}
Note: See TracBrowser for help on using the repository browser.