source: rtems/testsuites/psxtests/psxrwlock01/test.c @ c499856

4.115
Last change on this file since c499856 was c499856, checked in by Chris Johns <chrisj@…>, on 03/20/14 at 21:10:47

Change all references of rtems.com to rtems.org.

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