source: rtems/testsuites/psxtests/psxrwlock01/test.c @ 698c2e50

4.115
Last change on this file since 698c2e50 was 698c2e50, checked in by Sebastian Huber <sebastian.huber@…>, on 03/25/14 at 07:06:16

tests/psxtests: Use <rtems/test.h>

  • Property mode set to 100644
File size: 15.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_rwlockattr_t attr;
108  int                  status;
109  int                  p;
110  int                  i;
111  struct timespec      abstime;
112
113  TEST_BEGIN();
114
115  /*************** NULL POINTER CHECKS *****************/
116  puts( "pthread_rwlockattr_init( NULL ) -- EINVAL" );
117  status = pthread_rwlockattr_init( NULL );
118  rtems_test_assert( status == EINVAL );
119
120  puts( "pthread_rwlockattr_setpshared( NULL, private ) -- EINVAL" );
121  status = pthread_rwlockattr_setpshared( NULL, PTHREAD_PROCESS_PRIVATE );
122  rtems_test_assert( status == EINVAL );
123
124  puts( "pthread_rwlockattr_setpshared( NULL, shared ) -- EINVAL" );
125  status = pthread_rwlockattr_setpshared( NULL, PTHREAD_PROCESS_SHARED );
126  rtems_test_assert( status == EINVAL );
127
128  puts( "pthread_rwlockattr_getpshared( NULL, &p ) -- EINVAL" );
129  status = pthread_rwlockattr_getpshared( NULL, &p );
130  rtems_test_assert( status == EINVAL );
131
132  puts( "pthread_rwlockattr_destroy( NULL ) -- EINVAL" );
133  status = pthread_rwlockattr_destroy( NULL );
134  rtems_test_assert( status == EINVAL );
135
136  /*************** NOT INITIALIZED CHECKS *****************/
137  /* cheat visibility */
138  attr.is_initialized = 0;
139  puts( "pthread_rwlockattr_setpshared( &attr, shared ) -- EINVAL" );
140  status = pthread_rwlockattr_setpshared( &attr, PTHREAD_PROCESS_SHARED );
141  rtems_test_assert( status == EINVAL );
142
143  puts( "pthread_rwlockattr_getpshared( &attr, NULL ) -- EINVAL" );
144  status = pthread_rwlockattr_getpshared( &attr, NULL );
145  rtems_test_assert( status == EINVAL );
146
147  puts( "pthread_rwlockattr_destroy( &attr ) -- EINVAL" );
148  status = pthread_rwlockattr_destroy( &attr );
149  rtems_test_assert( status == EINVAL );
150
151  /*************** BAD PSHARED CHECK *****************/
152  puts( "pthread_rwlockattr_setpshared( &attr, private ) -- EINVAL" );
153  status = pthread_rwlockattr_setpshared( &attr, ~PTHREAD_PROCESS_PRIVATE );
154  rtems_test_assert( status == EINVAL );
155
156  /*************** ACTUALLY WORK THIS TIME *****************/
157  puts( "pthread_rwlockattr_init( &attr ) -- OK" );
158  status = pthread_rwlockattr_init( &attr );
159  rtems_test_assert( status == 0 );
160
161  puts( "pthread_rwlockattr_setpshared( &attr, private ) -- OK" );
162  status = pthread_rwlockattr_setpshared( &attr, PTHREAD_PROCESS_PRIVATE );
163  rtems_test_assert( status == 0 );
164
165  puts( "pthread_rwlockattr_getpshared( &attr, &p ) -- OK" );
166  status = pthread_rwlockattr_getpshared( &attr, &p );
167  rtems_test_assert( status == 0 );
168  rtems_test_assert( p == PTHREAD_PROCESS_PRIVATE );
169
170  puts( "pthread_rwlockattr_setpshared( &attr, shared ) -- OK" );
171  status = pthread_rwlockattr_setpshared( &attr, PTHREAD_PROCESS_SHARED );
172  rtems_test_assert( status == 0 );
173
174  puts( "pthread_rwlockattr_getpshared( &attr, &p ) -- OK" );
175  status = pthread_rwlockattr_getpshared( &attr, &p );
176  rtems_test_assert( status == 0 );
177  rtems_test_assert( p == PTHREAD_PROCESS_SHARED );
178
179  /*************** DESTROY/REUSE CHECK *****************/
180  puts( "pthread_rwlockattr_destroy( &attr ) -- OK" );
181  status = pthread_rwlockattr_destroy( &attr );
182  rtems_test_assert( status == 0 );
183
184  puts( "pthread_rwlockattr_getpshared( &attr, &p ) destroyed -- EINVAL" );
185  status = pthread_rwlockattr_getpshared( &attr, &p );
186  rtems_test_assert( status == EINVAL );
187
188  /*************** NULL ARGUMENT CHECKS *****************/
189  abstime.tv_sec = 0;
190  abstime.tv_nsec = 0;
191
192  puts( "pthread_rwlock_init(NULL, &attr) -- EINVAL" );
193  status = pthread_rwlock_init(NULL, &attr);
194  rtems_test_assert( status == EINVAL );
195
196  puts( "pthread_rwlock_destroy(NULL) -- EINVAL" );
197  status = pthread_rwlock_destroy(NULL);
198  rtems_test_assert( status == EINVAL );
199
200  puts( "pthread_rwlock_rdlock(NULL) -- EINVAL" );
201  status = pthread_rwlock_rdlock(NULL);
202  rtems_test_assert( status == EINVAL );
203
204  puts( "pthread_rwlock_timedrdlock( NULL, &abstime) -- EINVAL" );
205  status = pthread_rwlock_timedrdlock( NULL, &abstime);
206  rtems_test_assert( status == EINVAL );
207
208  puts( "pthread_rwlock_timedrdlock( &rwlock, NULL) -- EINVAL" );
209  status = pthread_rwlock_timedrdlock( &rwlock, NULL);
210  rtems_test_assert( status == EINVAL );
211
212  puts( "pthread_rwlock_tryrdlock(NULL) -- EINVAL" );
213  status = pthread_rwlock_tryrdlock(NULL);
214  rtems_test_assert( status == EINVAL );
215
216  puts( "pthread_rwlock_wrlock(NULL) -- EINVAL" );
217  status = pthread_rwlock_wrlock(NULL);
218  rtems_test_assert( status == EINVAL );
219
220  puts( "pthread_rwlock_timedwrlock( NULL, &abstime) -- EINVAL" );
221  status = pthread_rwlock_timedwrlock( NULL, &abstime );
222  rtems_test_assert( status == EINVAL );
223
224  puts( "pthread_rwlock_timedwrlock( &rwlock, NULL) -- EINVAL" );
225  status = pthread_rwlock_timedwrlock( &rwlock, NULL);
226  rtems_test_assert( status == EINVAL );
227
228  puts( "pthread_rwlock_trywrlock(NULL) -- EINVAL" );
229  status = pthread_rwlock_trywrlock(NULL);
230  rtems_test_assert( status == EINVAL );
231
232  puts( "pthread_rwlock_unlock(NULL) -- EINVAL" );
233  status = pthread_rwlock_unlock(NULL);
234  rtems_test_assert( status == EINVAL );
235
236  /*************** BAD ID CHECK *****************/
237  rwlock = 1;
238  /* make a valid abstime */
239  puts( "clock_gettime(CLOCK_REALTIME, &abstime) -- OK" );
240  status = clock_gettime( CLOCK_REALTIME, &abstime );
241  rtems_test_assert( !status );
242  abstime.tv_sec += 5;
243
244  puts( "pthread_rwlock_destroy(BadId) -- EINVAL" );
245  status = pthread_rwlock_destroy(&rwlock);
246  rtems_test_assert( status == EINVAL );
247
248  puts( "pthread_rwlock_rdlock(BadId) -- EINVAL" );
249  status = pthread_rwlock_rdlock(&rwlock);
250  rtems_test_assert( status == EINVAL );
251
252  puts( "pthread_rwlock_timedrdlock(BadId, &abstime) -- EINVAL" );
253  status = pthread_rwlock_timedrdlock( &rwlock, &abstime);
254  rtems_test_assert( status == EINVAL );
255
256  puts( "pthread_rwlock_tryrdlock(BadId) -- EINVAL" );
257  status = pthread_rwlock_tryrdlock(&rwlock);
258  rtems_test_assert( status == EINVAL );
259
260  puts( "pthread_rwlock_wrlock(BadId) -- EINVAL" );
261  status = pthread_rwlock_wrlock(&rwlock);
262  rtems_test_assert( status == EINVAL );
263
264  puts( "pthread_rwlock_timedwrlock(BadId, &abstime) -- EINVAL" );
265  status = pthread_rwlock_timedwrlock( &rwlock, &abstime );
266  rtems_test_assert( status == EINVAL );
267
268  puts( "pthread_rwlock_trywrlock(BadId) -- EINVAL" );
269  status = pthread_rwlock_trywrlock(&rwlock);
270  rtems_test_assert( status == EINVAL );
271
272  puts( "pthread_rwlock_unlock(BadId) -- EINVAL" );
273  status = pthread_rwlock_unlock(&rwlock);
274  rtems_test_assert( status == EINVAL );
275
276  /*************** BAD ABSTIME CHECK *****************/
277
278  /* in the past */
279  abstime.tv_sec = 0;
280  abstime.tv_nsec = 0;
281
282  /* invalid tv_nsec */
283  abstime.tv_sec = 0;
284  abstime.tv_nsec = 0x7fffffffL;
285
286  /* XXX do we need bad time check? */
287
288  /*************** ACTUALLY CREATE ONE CHECK *****************/
289  puts( "pthread_rwlockattr_init( &attr ) -- OK" );
290  status = pthread_rwlockattr_init( &attr );
291  rtems_test_assert( status == 0 );
292
293  puts( "pthread_rwlock_init( &rwlock, &attr ) -- OK" );
294  status = pthread_rwlock_init( &rwlock, &attr );
295  rtems_test_assert( status == 0 );
296  rtems_test_assert( rwlock != 0 );
297
298  puts( "pthread_rwlock_init( &rwlock, &attr ) -- EAGAIN" );
299  status = pthread_rwlock_init( &rwlock, &attr );
300  rtems_test_assert( status == EAGAIN );
301
302  puts( "pthread_rwlock_destroy( &rwlock ) -- OK" );
303  status = pthread_rwlock_destroy( &rwlock );
304  rtems_test_assert( status == 0 );
305
306  /********* CREATE RWLOCK WITH DEFAULT ATTRIBUTES AND DESTROY IT *********/
307  puts( "pthread_rwlock_init( &rwlock, NULL ) -- OK" );
308  status = pthread_rwlock_init( &rwlock, NULL );
309  rtems_test_assert( status == 0 );
310
311  puts( "pthread_rwlock_destroy( &rwlock ) -- OK" );
312  status = pthread_rwlock_destroy( &rwlock );
313  rtems_test_assert( status == 0 );
314
315  /*************** CREATE THREADS AND LET THEM OBTAIN READLOCK ***************/
316  puts( "pthread_rwlock_init( &RWLock, &attr ) -- OK" );
317  status = pthread_rwlock_init( &RWLock, &attr );
318  rtems_test_assert( status == 0 );
319
320  puts( "pthread_rwlock_tryrdlock(RWLock) -- OK" );
321  status = pthread_rwlock_tryrdlock(&RWLock);
322  rtems_test_assert( !status );
323
324  for (i=0 ; i<NUMBER_THREADS ; i++ ) {
325    printf( "Init: pthread_create - thread %d OK\n", i+1 );
326    status = pthread_create(&ThreadIds[i], NULL, ReadLockThread, &ThreadIds[i]);
327    rtems_test_assert( !status );
328
329    sleep(1);
330  }
331
332  puts( "pthread_rwlock_unlock(RWLock) -- OK" );
333  status = pthread_rwlock_unlock(&RWLock);
334  rtems_test_assert( !status );
335
336  sleep(1);
337
338  /*************** CREATE THREADS AND LET THEM OBTAIN READLOCK ***************/
339  puts( "pthread_rwlock_trywrlock(RWLock) -- OK" );
340  status = pthread_rwlock_trywrlock(&RWLock);
341  rtems_test_assert( !status );
342
343  puts( "pthread_rwlock_tryrdlock(&RWLock) -- EBUSY" );
344  status = pthread_rwlock_tryrdlock(&RWLock);
345  rtems_test_assert( status == EBUSY );
346
347  for (i=0 ; i<NUMBER_THREADS ; i++ ) {
348    printf( "Init: pthread_create - thread %d OK\n", i+1 );
349    status = pthread_create(&ThreadIds[i], NULL, ReadLockThread, &ThreadIds[i]);
350    rtems_test_assert( !status );
351
352    sleep(1);
353  }
354
355  /* Attempt delete while threads are blocked */
356  puts( "pthread_rwlock_destroy( &RWLock ) -- EBUSY" );
357  status = pthread_rwlock_destroy( &RWLock );
358  rtems_test_assert( status == EBUSY );
359
360  /* now unlock it so the threads can continue */
361  puts( "pthread_rwlock_unlock(RWLock) -- OK" );
362  status = pthread_rwlock_unlock(&RWLock);
363  rtems_test_assert( !status );
364
365  sleep(2);
366
367  /*************** CREATE THREADS AND LET THEM OBTAIN WRITE LOCK *************/
368  puts( "\npthread_rwlock_trywrlock(RWLock) -- OK" );
369  status = pthread_rwlock_trywrlock(&RWLock);
370  rtems_test_assert( !status );
371
372  puts( "pthread_rwlock_trywrlock(&RWLock) -- EBUSY" );
373  status = pthread_rwlock_trywrlock(&RWLock);
374  rtems_test_assert( status == EBUSY );
375
376  for (i=0 ; i<NUMBER_THREADS ; i++ ) {
377    printf( "Init: pthread_create - thread %d OK\n", i+1 );
378    status =
379      pthread_create(&ThreadIds[i], NULL, WriteLockThread, &ThreadIds[i]);
380    rtems_test_assert( !status );
381
382    sleep(2);
383  }
384
385  puts( "pthread_rwlock_unlock(RWLock) -- OK" );
386  status = pthread_rwlock_unlock(&RWLock);
387  rtems_test_assert( !status );
388
389  sleep(6);
390
391  /*************** CREATE THREADS AND LET THEM OBTAIN WRITE LOCK *************/
392  /***************    THEN ATTEMPT TO OBTAIN A READLOCK          *************/
393 
394  puts( "\npthread_rwlock_tryrdlock(&RWLock) -- OK" );
395  status = pthread_rwlock_tryrdlock(&RWLock);
396  rtems_test_assert( !status );
397
398  printf( "Init: pthread_create - thread reader & writer OK\n" );
399  status = pthread_create(&ThreadIds[0], NULL, WriteLockThread, &ThreadIds[0]);
400  rtems_test_assert( !status );
401
402  sleep(1);
403  status = pthread_create(&ThreadIds[1], NULL, ReadLockThread, &ThreadIds[1]);
404  rtems_test_assert( !status );
405
406  sleep(1);
407
408  puts( "pthread_rwlock_tryrdlock(&RWLock) -- EBUSY" );
409  status = pthread_rwlock_tryrdlock(&RWLock);
410  rtems_test_assert( status == EBUSY );
411
412  puts( "pthread_rwlock_trywrlock(&RWLock) -- EBUSY" );
413  status = pthread_rwlock_trywrlock(&RWLock);
414  rtems_test_assert( status == EBUSY );
415
416  sleep( 5 );
417
418  puts( "pthread_rwlock_unlock(&RWLock) -- OK" );
419  status = pthread_rwlock_unlock(&RWLock);
420  rtems_test_assert( !status );
421
422  sleep( 5 );
423
424  /*************** TIMEOUT ON RWLOCK ***************/
425  puts( "clock_gettime(CLOCK_REALTIME, &abstime) -- OK" );
426  status = clock_gettime( CLOCK_REALTIME, &abstime );
427  rtems_test_assert( !status );
428
429  abstime.tv_sec += 1;
430  puts( "pthread_rwlock_timedwrlock( &RWLock, &abstime) -- OK" );
431  status = pthread_rwlock_timedwrlock( &RWLock, &abstime );
432  rtems_test_assert( status == 0 );
433
434  abstime.tv_sec += 1;
435  puts( "pthread_rwlock_timedrdlock( &RWLock, &abstime) -- ETIMEDOUT" );
436  status = pthread_rwlock_timedrdlock( &RWLock, &abstime );
437  rtems_test_assert( status == ETIMEDOUT );
438
439  abstime.tv_sec -= 1;
440  puts( "pthread_rwlock_timedrdlock( &RWLock, &abstime) -- ETIMEDOUT" );
441  status = pthread_rwlock_timedrdlock( &RWLock, &abstime );
442  rtems_test_assert( status == ETIMEDOUT );
443
444  abstime.tv_sec -= 1;
445  puts( "pthread_rwlock_timedwrlock( &RWLock, &abstime) -- ETIMEDOUT" );
446  status = pthread_rwlock_timedwrlock( &RWLock, &abstime );
447  rtems_test_assert( status == ETIMEDOUT );
448
449  /*************** OBTAIN RWLOCK WITH ABSTIME IN PAST ***************/
450  status = pthread_rwlock_unlock(&RWLock);
451  rtems_test_assert( !status );
452
453  abstime.tv_sec -= 1;
454  puts( "pthread_rwlock_timedrdlock( &RWLock, &abstime) -- in past -- OK" );
455  status = pthread_rwlock_timedrdlock( &RWLock, &abstime );
456  rtems_test_assert( status == 0 );
457
458  /*************** OBTAIN RWLOCK FOR WRITE WITH ABSTIME IN PAST ***************/
459  status = pthread_rwlock_unlock(&RWLock);
460  rtems_test_assert( !status );
461
462  abstime.tv_sec -= 1;
463  puts( "pthread_rwlock_timedwrlock( &RWLock, &abstime) -- in past -- OK" );
464  status = pthread_rwlock_timedwrlock( &RWLock, &abstime );
465  rtems_test_assert( status == 0 );
466
467  /*************** DESTROY RWLOCK ***************/
468  puts( "pthread_rwlock_destroy( &RWLock ) -- OK" );
469  status = pthread_rwlock_destroy( &RWLock );
470  rtems_test_assert( status == 0 );
471
472  /*************** OBTAIN A LOCK AND THEN RELEASE IT TWICE ***************/
473
474  puts( "pthread_rwlock_init( &rwlock, NULL ) -- OK" );
475  status = pthread_rwlock_init( &rwlock, NULL );
476  rtems_test_assert( status == 0 );
477  rtems_test_assert( rwlock != 0 );
478
479  puts( "pthread_rwlock_unlock ( &rwlock ) -- OK" );
480  status = pthread_rwlock_unlock( &rwlock );
481  rtems_test_assert( status == 0 );
482
483  puts( "pthread_rwlock_unlock ( &rwlock ) -- OK" );
484  status = pthread_rwlock_unlock( &rwlock );
485  rtems_test_assert( status == 0 );
486
487  /*************** END OF TEST *****************/
488  TEST_END();
489  exit(0);
490}
Note: See TracBrowser for help on using the repository browser.