Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:24:40

0001 /* SPDX-License-Identifier: BSD-2-Clause */
0002 
0003 /**
0004  *  @file
0005  *
0006  *  This test exercises the POSIX RWLock manager.
0007  */
0008 
0009 /*
0010  *  COPYRIGHT (c) 1989-2012.
0011  *  On-Line Applications Research Corporation (OAR).
0012  *
0013  * Redistribution and use in source and binary forms, with or without
0014  * modification, are permitted provided that the following conditions
0015  * are met:
0016  * 1. Redistributions of source code must retain the above copyright
0017  *    notice, this list of conditions and the following disclaimer.
0018  * 2. Redistributions in binary form must reproduce the above copyright
0019  *    notice, this list of conditions and the following disclaimer in the
0020  *    documentation and/or other materials provided with the distribution.
0021  *
0022  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
0023  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
0024  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
0025  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
0026  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
0027  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
0028  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
0029  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
0030  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
0031  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
0032  * POSSIBILITY OF SUCH DAMAGE.
0033  */
0034 
0035 #ifdef HAVE_CONFIG_H
0036 #include "config.h"
0037 #endif
0038 
0039 #include "tmacros.h"
0040 #include <stdio.h>
0041 #include <errno.h>
0042 #include <stdlib.h>
0043 
0044 /* #define __USE_XOPEN2K XXX already defined on GNU/Linux */
0045 #include <pthread.h>
0046 
0047 const char rtems_test_name[] = "PSXRWLOCK 1";
0048 
0049 /* forward declarations to avoid warnings */
0050 void *ReadLockThread(void *arg);
0051 void *WriteLockThread(void *arg);
0052 int test_main(void);
0053 
0054 #define NUMBER_THREADS 2
0055 pthread_t ThreadIds[NUMBER_THREADS];
0056 pthread_rwlock_t RWLock;
0057 
0058 /*
0059  * Test thread to block for read lock and unlock it
0060  */
0061 void *ReadLockThread(void *arg)
0062 {
0063   int status;
0064 
0065   /*
0066    * Detach ourselves so we don't wait for a join that won't happen.
0067    */
0068   pthread_detach( pthread_self() );
0069 
0070   puts( "ReadThread - pthread_rwlock_rdlock(RWLock) blocking -- OK" );
0071   status = pthread_rwlock_rdlock(&RWLock);
0072   rtems_test_assert( !status );
0073   puts( "ReadThread - pthread_rwlock_rdlock(RWLock) unblocked -- OK" );
0074 
0075   status = pthread_rwlock_unlock(&RWLock);
0076   rtems_test_assert( !status );
0077   return NULL;
0078 }
0079 
0080 /*
0081  * Test thread to block for write lock and unlock it
0082  */
0083 void *WriteLockThread(void *arg)
0084 {
0085   int status;
0086 
0087   /*
0088    * Detach ourselves so we don't wait for a join that won't happen.
0089    */
0090   pthread_detach( pthread_self() );
0091 
0092   puts( "WriteThread - pthread_rwlock_wrlock(RWLock) blocking -- OK" );
0093   status = pthread_rwlock_wrlock(&RWLock);
0094   rtems_test_assert( !status );
0095   puts( "WriteThread - pthread_rwlock_wrlock(RWLock) unblocked -- OK" );
0096 
0097   sleep( 2 );
0098 
0099   puts( "WriteThread - pthread_rwlock_unlock(RWLock) -- OK" );
0100   status = pthread_rwlock_unlock(&RWLock);
0101   if ( status )
0102    printf( "status=%s\n", strerror(status) );
0103   rtems_test_assert( !status );
0104   return NULL;
0105 }
0106 
0107 static void test_rwlock_pshared_init(void)
0108 {
0109   pthread_rwlock_t rwlock;
0110   pthread_rwlockattr_t attr;
0111   int eno;
0112 
0113   eno = pthread_rwlockattr_init(&attr);
0114   rtems_test_assert(eno == 0);
0115 
0116   eno = pthread_rwlockattr_setpshared(&attr, PTHREAD_PROCESS_PRIVATE);
0117   rtems_test_assert(eno == 0);
0118 
0119   eno = pthread_rwlock_init(&rwlock, &attr);
0120   rtems_test_assert(eno == 0);
0121 
0122   eno = pthread_rwlock_destroy(&rwlock);
0123   rtems_test_assert(eno == 0);
0124 
0125   eno = pthread_rwlockattr_setpshared(&attr, PTHREAD_PROCESS_SHARED);
0126   rtems_test_assert(eno == 0);
0127 
0128   eno = pthread_rwlock_init(&rwlock, &attr);
0129   rtems_test_assert(eno == 0);
0130 
0131   eno = pthread_rwlock_destroy(&rwlock);
0132   rtems_test_assert(eno == 0);
0133 
0134   attr.process_shared = -1;
0135 
0136   eno = pthread_rwlock_init(&rwlock, &attr);
0137   rtems_test_assert(eno == EINVAL);
0138 
0139   eno = pthread_rwlockattr_destroy(&attr);
0140   rtems_test_assert(eno == 0);
0141 }
0142 
0143 static void test_rwlock_null( void )
0144 {
0145   struct timespec to;
0146   int eno;
0147 
0148   eno = pthread_rwlock_destroy( NULL );
0149   rtems_test_assert( eno == EINVAL );
0150 
0151   eno = pthread_rwlock_init( NULL, NULL );
0152   rtems_test_assert( eno == EINVAL );
0153 
0154   eno = pthread_rwlock_rdlock( NULL );
0155   rtems_test_assert( eno == EINVAL );
0156 
0157   to.tv_sec = 1;
0158   to.tv_nsec = 1;
0159   eno = pthread_rwlock_timedrdlock( NULL, &to );
0160   rtems_test_assert( eno == EINVAL );
0161 
0162   to.tv_sec = 1;
0163   to.tv_nsec = 1;
0164   eno = pthread_rwlock_timedwrlock( NULL, &to );
0165   rtems_test_assert( eno == EINVAL );
0166 
0167   eno = pthread_rwlock_tryrdlock( NULL );
0168   rtems_test_assert( eno == EINVAL );
0169 
0170   eno = pthread_rwlock_trywrlock( NULL );
0171   rtems_test_assert( eno == EINVAL );
0172 
0173   eno = pthread_rwlock_unlock( NULL );
0174   rtems_test_assert( eno == EINVAL );
0175 
0176   eno = pthread_rwlock_wrlock( NULL );
0177   rtems_test_assert( eno == EINVAL );
0178 }
0179 
0180 static void test_rwlock_not_initialized( void )
0181 {
0182   pthread_rwlock_t rw;
0183   struct timespec to;
0184   int eno;
0185 
0186   memset( &rw, 0xff, sizeof( rw ) );
0187 
0188   eno = pthread_rwlock_destroy( &rw );
0189   rtems_test_assert( eno == EINVAL );
0190 
0191   eno = pthread_rwlock_rdlock( &rw );
0192   rtems_test_assert( eno == EINVAL );
0193 
0194   to.tv_sec = 1;
0195   to.tv_nsec = 1;
0196   eno = pthread_rwlock_timedrdlock( &rw, &to );
0197   rtems_test_assert( eno == EINVAL );
0198 
0199   to.tv_sec = 1;
0200   to.tv_nsec = 1;
0201   eno = pthread_rwlock_timedwrlock( &rw, &to );
0202   rtems_test_assert( eno == EINVAL );
0203 
0204   eno = pthread_rwlock_tryrdlock( &rw );
0205   rtems_test_assert( eno == EINVAL );
0206 
0207   eno = pthread_rwlock_trywrlock( &rw );
0208   rtems_test_assert( eno == EINVAL );
0209 
0210   eno = pthread_rwlock_unlock( &rw );
0211   rtems_test_assert( eno == EINVAL );
0212 
0213   eno = pthread_rwlock_wrlock( &rw );
0214   rtems_test_assert( eno == EINVAL );
0215 }
0216 
0217 static void test_rwlock_invalid_copy( void )
0218 {
0219   pthread_rwlock_t rw;
0220   pthread_rwlock_t rw2;
0221   struct timespec to;
0222   int eno;
0223 
0224   eno = pthread_rwlock_init( &rw, NULL );
0225   rtems_test_assert( eno == 0 );
0226 
0227   memcpy( &rw2, &rw, sizeof( rw2 ) );
0228 
0229   eno = pthread_rwlock_destroy( &rw2 );
0230   rtems_test_assert( eno == EINVAL );
0231 
0232   eno = pthread_rwlock_rdlock( &rw2 );
0233   rtems_test_assert( eno == EINVAL );
0234 
0235   to.tv_sec = 1;
0236   to.tv_nsec = 1;
0237   eno = pthread_rwlock_timedrdlock( &rw2, &to );
0238   rtems_test_assert( eno == EINVAL );
0239 
0240   to.tv_sec = 1;
0241   to.tv_nsec = 1;
0242   eno = pthread_rwlock_timedwrlock( &rw2, &to );
0243   rtems_test_assert( eno == EINVAL );
0244 
0245   eno = pthread_rwlock_tryrdlock( &rw2 );
0246   rtems_test_assert( eno == EINVAL );
0247 
0248   eno = pthread_rwlock_trywrlock( &rw2 );
0249   rtems_test_assert( eno == EINVAL );
0250 
0251   eno = pthread_rwlock_unlock( &rw2 );
0252   rtems_test_assert( eno == EINVAL );
0253 
0254   eno = pthread_rwlock_wrlock( &rw2 );
0255   rtems_test_assert( eno == EINVAL );
0256 
0257   eno = pthread_rwlock_destroy( &rw );
0258   rtems_test_assert( eno == 0 );
0259 }
0260 
0261 static void test_rwlock_auto_initialization( void )
0262 {
0263   struct timespec to;
0264   int eno;
0265 
0266   {
0267     static pthread_rwlock_t rw = PTHREAD_RWLOCK_INITIALIZER;
0268 
0269     eno = pthread_rwlock_destroy( &rw );
0270     rtems_test_assert( eno == 0 );
0271 
0272     eno = pthread_rwlock_destroy( &rw );
0273     rtems_test_assert( eno == EINVAL );
0274   }
0275 
0276   {
0277     static pthread_rwlock_t rw = PTHREAD_RWLOCK_INITIALIZER;
0278 
0279     eno = pthread_rwlock_rdlock( &rw );
0280     rtems_test_assert( eno == 0 );
0281 
0282     eno = pthread_rwlock_unlock( &rw );
0283     rtems_test_assert( eno == 0 );
0284 
0285     eno = pthread_rwlock_destroy( &rw );
0286     rtems_test_assert( eno == 0 );
0287   }
0288 
0289   {
0290     static pthread_rwlock_t rw = PTHREAD_RWLOCK_INITIALIZER;
0291 
0292     to.tv_sec = 1;
0293     to.tv_nsec = 1;
0294     eno = pthread_rwlock_timedrdlock( &rw, &to );
0295     rtems_test_assert( eno == 0 );
0296   }
0297 
0298   {
0299     static pthread_rwlock_t rw = PTHREAD_RWLOCK_INITIALIZER;
0300 
0301     to.tv_sec = 1;
0302     to.tv_nsec = 1;
0303     eno = pthread_rwlock_timedwrlock( &rw, &to );
0304     rtems_test_assert( eno == 0 );
0305   }
0306 
0307   {
0308     static pthread_rwlock_t rw = PTHREAD_RWLOCK_INITIALIZER;
0309 
0310     eno = pthread_rwlock_tryrdlock( &rw );
0311     rtems_test_assert( eno == 0 );
0312   }
0313 
0314   {
0315     static pthread_rwlock_t rw = PTHREAD_RWLOCK_INITIALIZER;
0316 
0317     eno = pthread_rwlock_trywrlock( &rw );
0318     rtems_test_assert( eno == 0 );
0319   }
0320 
0321   {
0322     static pthread_rwlock_t rw = PTHREAD_RWLOCK_INITIALIZER;
0323 
0324     eno = pthread_rwlock_unlock( &rw );
0325     rtems_test_assert( eno == 0 );
0326   }
0327 
0328   {
0329     static pthread_rwlock_t rw = PTHREAD_RWLOCK_INITIALIZER;
0330 
0331     eno = pthread_rwlock_wrlock( &rw );
0332     rtems_test_assert( eno == 0 );
0333   }
0334 }
0335 
0336 /*
0337  *  main entry point to the test
0338  */
0339 
0340 #if defined(__rtems__)
0341 int test_main(void)
0342 #else
0343 int main(
0344   int    argc,
0345   char **argv
0346 )
0347 #endif
0348 {
0349   pthread_rwlock_t     rwlock;
0350   pthread_rwlockattr_t attr;
0351   int                  status;
0352   int                  p;
0353   int                  i;
0354   struct timespec      abstime;
0355 
0356   TEST_BEGIN();
0357 
0358   test_rwlock_pshared_init();
0359   test_rwlock_null();
0360   test_rwlock_not_initialized();
0361   test_rwlock_invalid_copy();
0362   test_rwlock_auto_initialization();
0363 
0364   /*************** NULL POINTER CHECKS *****************/
0365   puts( "pthread_rwlockattr_init( NULL ) -- EINVAL" );
0366   status = pthread_rwlockattr_init( NULL );
0367   rtems_test_assert( status == EINVAL );
0368 
0369   puts( "pthread_rwlockattr_setpshared( NULL, private ) -- EINVAL" );
0370   status = pthread_rwlockattr_setpshared( NULL, PTHREAD_PROCESS_PRIVATE );
0371   rtems_test_assert( status == EINVAL );
0372 
0373   puts( "pthread_rwlockattr_setpshared( NULL, shared ) -- EINVAL" );
0374   status = pthread_rwlockattr_setpshared( NULL, PTHREAD_PROCESS_SHARED );
0375   rtems_test_assert( status == EINVAL );
0376 
0377   puts( "pthread_rwlockattr_getpshared( NULL, &p ) -- EINVAL" );
0378   status = pthread_rwlockattr_getpshared( NULL, &p );
0379   rtems_test_assert( status == EINVAL );
0380 
0381   puts( "pthread_rwlockattr_destroy( NULL ) -- EINVAL" );
0382   status = pthread_rwlockattr_destroy( NULL );
0383   rtems_test_assert( status == EINVAL );
0384 
0385   /*************** NOT INITIALIZED CHECKS *****************/
0386   /* cheat visibility */
0387   attr.is_initialized = 0;
0388   puts( "pthread_rwlockattr_setpshared( &attr, shared ) -- EINVAL" );
0389   status = pthread_rwlockattr_setpshared( &attr, PTHREAD_PROCESS_SHARED );
0390   rtems_test_assert( status == EINVAL );
0391 
0392   puts( "pthread_rwlockattr_getpshared( &attr, NULL ) -- EINVAL" );
0393   status = pthread_rwlockattr_getpshared( &attr, NULL );
0394   rtems_test_assert( status == EINVAL );
0395 
0396   puts( "pthread_rwlockattr_destroy( &attr ) -- EINVAL" );
0397   status = pthread_rwlockattr_destroy( &attr );
0398   rtems_test_assert( status == EINVAL );
0399 
0400   /*************** BAD PSHARED CHECK *****************/
0401   puts( "pthread_rwlockattr_setpshared( &attr, private ) -- EINVAL" );
0402   status = pthread_rwlockattr_setpshared( &attr, ~PTHREAD_PROCESS_PRIVATE );
0403   rtems_test_assert( status == EINVAL );
0404 
0405   /*************** ACTUALLY WORK THIS TIME *****************/
0406   puts( "pthread_rwlockattr_init( &attr ) -- OK" );
0407   status = pthread_rwlockattr_init( &attr );
0408   rtems_test_assert( status == 0 );
0409 
0410   puts( "pthread_rwlockattr_setpshared( &attr, private ) -- OK" );
0411   status = pthread_rwlockattr_setpshared( &attr, PTHREAD_PROCESS_PRIVATE );
0412   rtems_test_assert( status == 0 );
0413 
0414   puts( "pthread_rwlockattr_getpshared( &attr, &p ) -- OK" );
0415   status = pthread_rwlockattr_getpshared( &attr, &p );
0416   rtems_test_assert( status == 0 );
0417   rtems_test_assert( p == PTHREAD_PROCESS_PRIVATE );
0418 
0419   puts( "pthread_rwlockattr_setpshared( &attr, shared ) -- OK" );
0420   status = pthread_rwlockattr_setpshared( &attr, PTHREAD_PROCESS_SHARED );
0421   rtems_test_assert( status == 0 );
0422 
0423   puts( "pthread_rwlockattr_getpshared( &attr, &p ) -- OK" );
0424   status = pthread_rwlockattr_getpshared( &attr, &p );
0425   rtems_test_assert( status == 0 );
0426   rtems_test_assert( p == PTHREAD_PROCESS_SHARED );
0427 
0428   /*************** DESTROY/REUSE CHECK *****************/
0429   puts( "pthread_rwlockattr_destroy( &attr ) -- OK" );
0430   status = pthread_rwlockattr_destroy( &attr );
0431   rtems_test_assert( status == 0 );
0432 
0433   puts( "pthread_rwlockattr_getpshared( &attr, &p ) destroyed -- EINVAL" );
0434   status = pthread_rwlockattr_getpshared( &attr, &p );
0435   rtems_test_assert( status == EINVAL );
0436 
0437   /*************** NULL ARGUMENT CHECKS *****************/
0438   abstime.tv_sec = 0;
0439   abstime.tv_nsec = 0;
0440 
0441   puts( "pthread_rwlock_init(NULL, &attr) -- EINVAL" );
0442   status = pthread_rwlock_init(NULL, &attr);
0443   rtems_test_assert( status == EINVAL );
0444 
0445   puts( "pthread_rwlock_destroy(NULL) -- EINVAL" );
0446   status = pthread_rwlock_destroy(NULL);
0447   rtems_test_assert( status == EINVAL );
0448 
0449   puts( "pthread_rwlock_rdlock(NULL) -- EINVAL" );
0450   status = pthread_rwlock_rdlock(NULL);
0451   rtems_test_assert( status == EINVAL );
0452 
0453   puts( "pthread_rwlock_timedrdlock( NULL, &abstime) -- EINVAL" );
0454   status = pthread_rwlock_timedrdlock( NULL, &abstime);
0455   rtems_test_assert( status == EINVAL );
0456 
0457   puts( "pthread_rwlock_tryrdlock(NULL) -- EINVAL" );
0458   status = pthread_rwlock_tryrdlock(NULL);
0459   rtems_test_assert( status == EINVAL );
0460 
0461   puts( "pthread_rwlock_wrlock(NULL) -- EINVAL" );
0462   status = pthread_rwlock_wrlock(NULL);
0463   rtems_test_assert( status == EINVAL );
0464 
0465   puts( "pthread_rwlock_timedwrlock( NULL, &abstime) -- EINVAL" );
0466   status = pthread_rwlock_timedwrlock( NULL, &abstime );
0467   rtems_test_assert( status == EINVAL );
0468 
0469   puts( "pthread_rwlock_trywrlock(NULL) -- EINVAL" );
0470   status = pthread_rwlock_trywrlock(NULL);
0471   rtems_test_assert( status == EINVAL );
0472 
0473   puts( "pthread_rwlock_unlock(NULL) -- EINVAL" );
0474   status = pthread_rwlock_unlock(NULL);
0475   rtems_test_assert( status == EINVAL );
0476 
0477   status = pthread_rwlock_init( &rwlock, NULL );
0478   rtems_test_assert( status == 0 );
0479 
0480   status = pthread_rwlock_wrlock( &rwlock );
0481   rtems_test_assert( status == 0 );
0482 
0483   puts( "pthread_rwlock_timedrdlock( &rwlock, NULL) -- EINVAL" );
0484   status = pthread_rwlock_timedrdlock( &rwlock, NULL);
0485   rtems_test_assert( status == EINVAL );
0486 
0487   puts( "pthread_rwlock_timedwrlock( &rwlock, NULL) -- EINVAL" );
0488   status = pthread_rwlock_timedwrlock( &rwlock, NULL);
0489   rtems_test_assert( status == EINVAL );
0490 
0491   status = pthread_rwlock_unlock( &rwlock );
0492   rtems_test_assert( status == 0 );
0493 
0494   status = pthread_rwlock_destroy( &rwlock );
0495   rtems_test_assert( status == 0 );
0496 
0497   /*************** BAD ID CHECK *****************/
0498   /* make a valid abstime */
0499   puts( "clock_gettime(CLOCK_REALTIME, &abstime) -- OK" );
0500   status = clock_gettime( CLOCK_REALTIME, &abstime );
0501   rtems_test_assert( !status );
0502   abstime.tv_sec += 5;
0503 
0504   puts( "pthread_rwlock_destroy(BadId) -- EINVAL" );
0505   status = pthread_rwlock_destroy(NULL);
0506   rtems_test_assert( status == EINVAL );
0507 
0508   puts( "pthread_rwlock_rdlock(BadId) -- EINVAL" );
0509   status = pthread_rwlock_rdlock(NULL);
0510   rtems_test_assert( status == EINVAL );
0511 
0512   puts( "pthread_rwlock_timedrdlock(BadId, &abstime) -- EINVAL" );
0513   status = pthread_rwlock_timedrdlock( NULL, &abstime);
0514   rtems_test_assert( status == EINVAL );
0515 
0516   puts( "pthread_rwlock_tryrdlock(BadId) -- EINVAL" );
0517   status = pthread_rwlock_tryrdlock(NULL);
0518   rtems_test_assert( status == EINVAL );
0519 
0520   puts( "pthread_rwlock_wrlock(BadId) -- EINVAL" );
0521   status = pthread_rwlock_wrlock(NULL);
0522   rtems_test_assert( status == EINVAL );
0523 
0524   puts( "pthread_rwlock_timedwrlock(BadId, &abstime) -- EINVAL" );
0525   status = pthread_rwlock_timedwrlock( NULL, &abstime );
0526   rtems_test_assert( status == EINVAL );
0527 
0528   puts( "pthread_rwlock_trywrlock(BadId) -- EINVAL" );
0529   status = pthread_rwlock_trywrlock(NULL);
0530   rtems_test_assert( status == EINVAL );
0531 
0532   puts( "pthread_rwlock_unlock(BadId) -- EINVAL" );
0533   status = pthread_rwlock_unlock(NULL);
0534   rtems_test_assert( status == EINVAL );
0535 
0536   /*************** BAD ABSTIME CHECK *****************/
0537 
0538   /* in the past */
0539   abstime.tv_sec = 0;
0540   abstime.tv_nsec = 0;
0541 
0542   /* invalid tv_nsec */
0543   abstime.tv_sec = 0;
0544   abstime.tv_nsec = 0x7fffffffL;
0545 
0546   /* XXX do we need bad time check? */
0547 
0548   /*************** ACTUALLY CREATE ONE CHECK *****************/
0549   puts( "pthread_rwlockattr_init( &attr ) -- OK" );
0550   status = pthread_rwlockattr_init( &attr );
0551   rtems_test_assert( status == 0 );
0552 
0553   puts( "pthread_rwlock_init( &rwlock, &attr ) -- OK" );
0554   status = pthread_rwlock_init( &rwlock, &attr );
0555   rtems_test_assert( status == 0 );
0556 
0557   puts( "pthread_rwlock_destroy( &rwlock ) -- OK" );
0558   status = pthread_rwlock_destroy( &rwlock );
0559   rtems_test_assert( status == 0 );
0560 
0561   /********* CREATE RWLOCK WITH DEFAULT ATTRIBUTES AND DESTROY IT *********/
0562   puts( "pthread_rwlock_init( &rwlock, NULL ) -- OK" );
0563   status = pthread_rwlock_init( &rwlock, NULL );
0564   rtems_test_assert( status == 0 );
0565 
0566   puts( "pthread_rwlock_destroy( &rwlock ) -- OK" );
0567   status = pthread_rwlock_destroy( &rwlock );
0568   rtems_test_assert( status == 0 );
0569 
0570   /*************** CREATE THREADS AND LET THEM OBTAIN READLOCK ***************/
0571   puts( "pthread_rwlock_init( &RWLock, &attr ) -- OK" );
0572   status = pthread_rwlock_init( &RWLock, &attr );
0573   rtems_test_assert( status == 0 );
0574 
0575   puts( "pthread_rwlock_tryrdlock(RWLock) -- OK" );
0576   status = pthread_rwlock_tryrdlock(&RWLock);
0577   rtems_test_assert( !status );
0578 
0579   for (i=0 ; i<NUMBER_THREADS ; i++ ) {
0580     printf( "Init: pthread_create - thread %d OK\n", i+1 );
0581     status = pthread_create(&ThreadIds[i], NULL, ReadLockThread, &ThreadIds[i]);
0582     rtems_test_assert( !status );
0583 
0584     sleep(1);
0585   }
0586 
0587   puts( "pthread_rwlock_unlock(RWLock) -- OK" );
0588   status = pthread_rwlock_unlock(&RWLock);
0589   rtems_test_assert( !status );
0590 
0591   sleep(1);
0592 
0593   /*************** CREATE THREADS AND LET THEM OBTAIN READLOCK ***************/
0594   puts( "pthread_rwlock_trywrlock(RWLock) -- OK" );
0595   status = pthread_rwlock_trywrlock(&RWLock);
0596   rtems_test_assert( !status );
0597 
0598   puts( "pthread_rwlock_tryrdlock(&RWLock) -- EBUSY" );
0599   status = pthread_rwlock_tryrdlock(&RWLock);
0600   rtems_test_assert( status == EBUSY );
0601 
0602   for (i=0 ; i<NUMBER_THREADS ; i++ ) {
0603     printf( "Init: pthread_create - thread %d OK\n", i+1 );
0604     status = pthread_create(&ThreadIds[i], NULL, ReadLockThread, &ThreadIds[i]);
0605     rtems_test_assert( !status );
0606 
0607     sleep(1);
0608   }
0609 
0610   /* Attempt delete while threads are blocked */
0611   puts( "pthread_rwlock_destroy( &RWLock ) -- EBUSY" );
0612   status = pthread_rwlock_destroy( &RWLock );
0613   rtems_test_assert( status == EBUSY );
0614 
0615   /* now unlock it so the threads can continue */
0616   puts( "pthread_rwlock_unlock(RWLock) -- OK" );
0617   status = pthread_rwlock_unlock(&RWLock);
0618   rtems_test_assert( !status );
0619 
0620   sleep(2);
0621 
0622   /*************** CREATE THREADS AND LET THEM OBTAIN WRITE LOCK *************/
0623   puts( "\npthread_rwlock_trywrlock(RWLock) -- OK" );
0624   status = pthread_rwlock_trywrlock(&RWLock);
0625   rtems_test_assert( !status );
0626 
0627   puts( "pthread_rwlock_trywrlock(&RWLock) -- EBUSY" );
0628   status = pthread_rwlock_trywrlock(&RWLock);
0629   rtems_test_assert( status == EBUSY );
0630 
0631   for (i=0 ; i<NUMBER_THREADS ; i++ ) {
0632     printf( "Init: pthread_create - thread %d OK\n", i+1 );
0633     status =
0634       pthread_create(&ThreadIds[i], NULL, WriteLockThread, &ThreadIds[i]);
0635     rtems_test_assert( !status );
0636 
0637     sleep(2);
0638   }
0639 
0640   puts( "pthread_rwlock_unlock(RWLock) -- OK" );
0641   status = pthread_rwlock_unlock(&RWLock);
0642   rtems_test_assert( !status );
0643 
0644   sleep(6);
0645 
0646   /*************** CREATE THREADS AND LET THEM OBTAIN WRITE LOCK *************/
0647   /***************    THEN ATTEMPT TO OBTAIN A READLOCK          *************/
0648  
0649   puts( "\npthread_rwlock_tryrdlock(&RWLock) -- OK" );
0650   status = pthread_rwlock_tryrdlock(&RWLock);
0651   rtems_test_assert( !status );
0652 
0653   printf( "Init: pthread_create - thread reader & writer OK\n" );
0654   status = pthread_create(&ThreadIds[0], NULL, WriteLockThread, &ThreadIds[0]);
0655   rtems_test_assert( !status );
0656 
0657   sleep(1);
0658   status = pthread_create(&ThreadIds[1], NULL, ReadLockThread, &ThreadIds[1]);
0659   rtems_test_assert( !status );
0660 
0661   sleep(1);
0662 
0663   puts( "pthread_rwlock_tryrdlock(&RWLock) -- EBUSY" );
0664   status = pthread_rwlock_tryrdlock(&RWLock);
0665   rtems_test_assert( status == EBUSY );
0666 
0667   puts( "pthread_rwlock_trywrlock(&RWLock) -- EBUSY" );
0668   status = pthread_rwlock_trywrlock(&RWLock);
0669   rtems_test_assert( status == EBUSY );
0670 
0671   sleep( 5 );
0672 
0673   puts( "pthread_rwlock_unlock(&RWLock) -- OK" );
0674   status = pthread_rwlock_unlock(&RWLock);
0675   rtems_test_assert( !status );
0676 
0677   sleep( 5 );
0678 
0679   /*************** TIMEOUT ON RWLOCK ***************/
0680   puts( "clock_gettime(CLOCK_REALTIME, &abstime) -- OK" );
0681   status = clock_gettime( CLOCK_REALTIME, &abstime );
0682   rtems_test_assert( !status );
0683 
0684   abstime.tv_sec += 1;
0685   puts( "pthread_rwlock_timedwrlock( &RWLock, &abstime) -- OK" );
0686   status = pthread_rwlock_timedwrlock( &RWLock, &abstime );
0687   rtems_test_assert( status == 0 );
0688 
0689   abstime.tv_sec += 1;
0690   puts( "pthread_rwlock_timedrdlock( &RWLock, &abstime) -- ETIMEDOUT" );
0691   status = pthread_rwlock_timedrdlock( &RWLock, &abstime );
0692   rtems_test_assert( status == ETIMEDOUT );
0693 
0694   abstime.tv_sec -= 1;
0695   puts( "pthread_rwlock_timedrdlock( &RWLock, &abstime) -- ETIMEDOUT" );
0696   status = pthread_rwlock_timedrdlock( &RWLock, &abstime );
0697   rtems_test_assert( status == ETIMEDOUT );
0698 
0699   abstime.tv_sec -= 1;
0700   puts( "pthread_rwlock_timedwrlock( &RWLock, &abstime) -- ETIMEDOUT" );
0701   status = pthread_rwlock_timedwrlock( &RWLock, &abstime );
0702   rtems_test_assert( status == ETIMEDOUT );
0703 
0704   /*************** OBTAIN RWLOCK WITH ABSTIME IN PAST ***************/
0705   status = pthread_rwlock_unlock(&RWLock);
0706   rtems_test_assert( !status );
0707 
0708   abstime.tv_sec -= 1;
0709   puts( "pthread_rwlock_timedrdlock( &RWLock, &abstime) -- in past -- OK" );
0710   status = pthread_rwlock_timedrdlock( &RWLock, &abstime );
0711   rtems_test_assert( status == 0 );
0712 
0713   /*************** OBTAIN RWLOCK FOR WRITE WITH ABSTIME IN PAST ***************/
0714   status = pthread_rwlock_unlock(&RWLock);
0715   rtems_test_assert( !status );
0716 
0717   abstime.tv_sec -= 1;
0718   puts( "pthread_rwlock_timedwrlock( &RWLock, &abstime) -- in past -- OK" );
0719   status = pthread_rwlock_timedwrlock( &RWLock, &abstime );
0720   rtems_test_assert( status == 0 );
0721 
0722   /*************** DESTROY RWLOCK ***************/
0723   puts( "pthread_rwlock_destroy( &RWLock ) -- OK" );
0724   status = pthread_rwlock_destroy( &RWLock );
0725   rtems_test_assert( status == 0 );
0726 
0727   /*************** OBTAIN A LOCK AND THEN RELEASE IT TWICE ***************/
0728 
0729   puts( "pthread_rwlock_init( &rwlock, NULL ) -- OK" );
0730   status = pthread_rwlock_init( &rwlock, NULL );
0731   rtems_test_assert( status == 0 );
0732 
0733   puts( "pthread_rwlock_unlock ( &rwlock ) -- OK" );
0734   status = pthread_rwlock_unlock( &rwlock );
0735   rtems_test_assert( status == 0 );
0736 
0737   puts( "pthread_rwlock_unlock ( &rwlock ) -- OK" );
0738   status = pthread_rwlock_unlock( &rwlock );
0739   rtems_test_assert( status == 0 );
0740 
0741   /*************** END OF TEST *****************/
0742   TEST_END();
0743   exit(0);
0744 }