Back to home page

LXR

 
 

    


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

0001 /* SPDX-License-Identifier: BSD-2-Clause */
0002 
0003 /*
0004  *  COPYRIGHT (c) 1989-2009.
0005  *  On-Line Applications Research Corporation (OAR).
0006  *
0007  * Redistribution and use in source and binary forms, with or without
0008  * modification, are permitted provided that the following conditions
0009  * are met:
0010  * 1. Redistributions of source code must retain the above copyright
0011  *    notice, this list of conditions and the following disclaimer.
0012  * 2. Redistributions in binary form must reproduce the above copyright
0013  *    notice, this list of conditions and the following disclaimer in the
0014  *    documentation and/or other materials provided with the distribution.
0015  *
0016  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
0017  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
0018  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
0019  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
0020  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
0021  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
0022  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
0023  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
0024  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
0025  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
0026  * POSSIBILITY OF SUCH DAMAGE.
0027  */
0028 
0029 #ifdef HAVE_CONFIG_H
0030 #include "config.h"
0031 #endif
0032 
0033 #define CONFIGURE_INIT
0034 #include "system.h"
0035 #include <sched.h>
0036 
0037 const char rtems_test_name[] = "PSX 10";
0038 
0039 static void test_cond_null( void )
0040 {
0041   pthread_mutex_t mtx = PTHREAD_MUTEX_INITIALIZER;
0042   int eno;
0043   struct timespec to;
0044 
0045   eno = pthread_cond_init( NULL, NULL );
0046   rtems_test_assert( eno == EINVAL );
0047 
0048   eno = pthread_mutex_lock( &mtx );
0049   rtems_test_assert( eno == 0 );
0050 
0051   eno = pthread_cond_wait( NULL, &mtx );
0052   rtems_test_assert( eno == EINVAL );
0053 
0054   to.tv_sec = 1;
0055   to.tv_nsec = 1;
0056   eno = pthread_cond_timedwait( NULL, &mtx, &to );
0057   rtems_test_assert( eno == EINVAL );
0058 
0059   eno = pthread_mutex_unlock( &mtx );
0060   rtems_test_assert( eno == 0 );
0061 
0062   eno = pthread_cond_signal( NULL );
0063   rtems_test_assert( eno == EINVAL );
0064 
0065   eno = pthread_cond_broadcast( NULL );
0066   rtems_test_assert( eno == EINVAL );
0067 
0068   eno = pthread_cond_destroy( NULL );
0069   rtems_test_assert( eno == EINVAL );
0070 
0071   eno = pthread_mutex_destroy( &mtx );
0072   rtems_test_assert( eno == 0 );
0073 }
0074 
0075 static void test_cond_not_initialized( void )
0076 {
0077   pthread_mutex_t mtx = PTHREAD_MUTEX_INITIALIZER;
0078   pthread_cond_t cond;
0079   int eno;
0080   struct timespec to;
0081 
0082   memset( &cond, 0xff, sizeof( cond ) );
0083 
0084   eno = pthread_mutex_lock( &mtx );
0085   rtems_test_assert( eno == 0 );
0086 
0087   eno = pthread_cond_wait( &cond, &mtx );
0088   rtems_test_assert( eno == EINVAL );
0089 
0090   to.tv_sec = 1;
0091   to.tv_nsec = 1;
0092   eno = pthread_cond_timedwait( &cond, &mtx, &to );
0093   rtems_test_assert( eno == EINVAL );
0094 
0095   eno = pthread_mutex_unlock( &mtx );
0096   rtems_test_assert( eno == 0 );
0097 
0098   eno = pthread_cond_signal( &cond );
0099   rtems_test_assert( eno == EINVAL );
0100 
0101   eno = pthread_cond_broadcast( &cond );
0102   rtems_test_assert( eno == EINVAL );
0103 
0104   eno = pthread_cond_destroy( &cond );
0105   rtems_test_assert( eno == EINVAL );
0106 
0107   eno = pthread_mutex_destroy( &mtx );
0108   rtems_test_assert( eno == 0 );
0109 }
0110 
0111 static void test_cond_invalid_copy( void )
0112 {
0113   pthread_mutex_t mtx = PTHREAD_MUTEX_INITIALIZER;
0114   pthread_cond_t cond;
0115   pthread_cond_t cond2;
0116   int eno;
0117   struct timespec to;
0118 
0119   eno = pthread_cond_init( &cond, NULL );
0120   rtems_test_assert( eno == 0 );
0121 
0122   memcpy( &cond2, &cond, sizeof( cond2 ) );
0123 
0124   eno = pthread_mutex_lock( &mtx );
0125   rtems_test_assert( eno == 0 );
0126 
0127   eno = pthread_cond_wait( &cond2, &mtx );
0128   rtems_test_assert( eno == EINVAL );
0129 
0130   to.tv_sec = 1;
0131   to.tv_nsec = 1;
0132   eno = pthread_cond_timedwait( &cond2, &mtx, &to );
0133   rtems_test_assert( eno == EINVAL );
0134 
0135   eno = pthread_mutex_unlock( &mtx );
0136   rtems_test_assert( eno == 0 );
0137 
0138   eno = pthread_cond_signal( &cond2 );
0139   rtems_test_assert( eno == EINVAL );
0140 
0141   eno = pthread_cond_broadcast( &cond2 );
0142   rtems_test_assert( eno == EINVAL );
0143 
0144   eno = pthread_cond_destroy( &cond2 );
0145   rtems_test_assert( eno == EINVAL );
0146 
0147   eno = pthread_cond_destroy( &cond );
0148   rtems_test_assert( eno == 0 );
0149 
0150   eno = pthread_mutex_destroy( &mtx );
0151   rtems_test_assert( eno == 0 );
0152 }
0153 
0154 void *POSIX_Init(
0155   void *argument
0156 )
0157 {
0158   int                 status;
0159   pthread_condattr_t  attr;
0160   pthread_condattr_t  attr_error;
0161   int                 pshared;
0162   pthread_cond_t      cond;
0163   struct timespec     timeout;
0164 
0165   TEST_BEGIN();
0166 
0167   test_cond_null();
0168   test_cond_not_initialized();
0169   test_cond_invalid_copy();
0170 
0171   puts( "Init: pthread_condattr_init" );
0172   status = pthread_condattr_init( &attr );
0173   rtems_test_assert( !status );
0174 
0175   puts( "Init: pthread_condattr_init - EINVAL (attribute invalid)" );
0176   status = pthread_condattr_init( NULL );
0177   if ( status != EINVAL )
0178     printf( "status = %d\n", status );
0179   rtems_test_assert( status == EINVAL );
0180 
0181   puts( "Init: pthread_condattr_destroy" );
0182   status = pthread_condattr_destroy( &attr );
0183   rtems_test_assert( !status );
0184 
0185   puts( "Init: pthread_condattr_destroy - EINVAL (attribute invalid)" );
0186   status = pthread_condattr_destroy( NULL );
0187   if ( status != EINVAL )
0188     printf( "status = %d\n", status );
0189   rtems_test_assert( status == EINVAL );
0190 
0191   puts( "Init: pthread_condattr_init" );
0192   status = pthread_condattr_init( &attr );
0193   rtems_test_assert( !status );
0194 
0195   puts( "Init: pthread_condattr_setpshared - PTHREAD_PROCESS_SHARED" );
0196   status = pthread_condattr_setpshared( &attr, PTHREAD_PROCESS_SHARED );
0197   rtems_test_assert( !status );
0198 
0199   puts( "Init: pthread_condattr_setpshared - PTHREAD_PROCESS_PRIVATE" );
0200   status = pthread_condattr_setpshared( &attr, PTHREAD_PROCESS_PRIVATE );
0201   rtems_test_assert( !status );
0202 
0203   status = pthread_condattr_setpshared( NULL, PTHREAD_PROCESS_PRIVATE );
0204   if ( status != EINVAL )
0205     printf( "status = %d\n", status );
0206   rtems_test_assert( status == EINVAL );
0207   puts( "Init: pthread_condattr_setpshared - EINVAL (attribute invalid)" );
0208 
0209   status = pthread_condattr_setpshared( &attr, 0x7FFF );
0210   if ( status != EINVAL )
0211     printf( "status = %d\n", status );
0212   rtems_test_assert( status == EINVAL );
0213   puts( "Init: pthread_condattr_setpshared - EINVAL (pshared invalid)" );
0214 
0215   status = pthread_condattr_getpshared( &attr, &pshared );
0216   rtems_test_assert( !status );
0217   printf( "Init: pthread_condattr_getpshared - %d\n", pshared );
0218 
0219   status = pthread_condattr_getpshared( NULL, &pshared );
0220   if ( status != EINVAL )
0221     printf( "status = %d\n", status );
0222   rtems_test_assert( status == EINVAL );
0223   puts( "Init: pthread_condattr_getpshared - EINVAL (attribute invalid)" );
0224 
0225   puts( "Init: pthread_cond_init - NULL attr" );
0226   status = pthread_cond_init( &cond, NULL );
0227   rtems_test_assert( !status );
0228 
0229 /* error for attribute not initialized */
0230 
0231   attr_error.is_initialized = FALSE;
0232   status = pthread_cond_init( &cond, &attr_error );
0233   if ( status != EINVAL )
0234     printf( "status = %d\n", status );
0235   rtems_test_assert( status == EINVAL );
0236   puts( "Init: pthread_cond_init - EINVAL (attr not initialized)" );
0237 
0238 /* error for bad condition variable passed */
0239 
0240   status = pthread_cond_destroy( NULL );
0241   if ( status != EINVAL )
0242     printf( "status = %d\n", status );
0243   rtems_test_assert( status == EINVAL );
0244   puts( "Init: pthread_cond_destroy - EINVAL (cond invalid)" );
0245 
0246 /* pshared tests */
0247 
0248   puts( "Init: pthread_cond_init - EINVAL (invalid pshared)" );
0249   attr.process_shared = -1;
0250   status = pthread_cond_init( &cond, &attr );
0251   rtems_test_assert( status == EINVAL );
0252 
0253   puts( "Init: pthread_condattr_setpshared - PTHREAD_PROCESS_SHARED" );
0254   status = pthread_condattr_setpshared( &attr, PTHREAD_PROCESS_SHARED );
0255   rtems_test_assert( status == 0 );
0256 
0257   puts( "Init: pthread_cond_init - OK" );
0258   status = pthread_cond_init( &cond, &attr );
0259   rtems_test_assert( status == 0 );
0260 
0261   puts( "Init: pthread_cond_destroy - OK" );
0262   status = pthread_cond_destroy( &cond );
0263   rtems_test_assert( status == 0 );
0264 
0265 /* initiailize the attribute for the rest of the test */
0266 
0267   puts( "Init: pthread_cond_init - attr" );
0268   status = pthread_cond_init( &Cond1_id, &attr );
0269   rtems_test_assert( !status );
0270 
0271 /* signal task1 with a condition variable */
0272 
0273   empty_line();
0274 
0275   status = pthread_create( &Task_id, NULL, Task_1, NULL );
0276   rtems_test_assert( !status );
0277 
0278 /* switch to task1 to allow it to wait for a condition variable */
0279 
0280   puts( "Init: sleep to switch to Task_1" );
0281   sleep( 1 );
0282 
0283   status = pthread_cond_destroy( &Cond1_id );
0284   if ( status != EBUSY )
0285     printf( "status = %d\n", status );
0286   rtems_test_assert( status == EBUSY );
0287   puts( "Init: pthread_cond_destroy - EBUSY (task1 waiting)" );
0288 
0289   puts( "Init: pthread_cond_signal" );
0290   status = pthread_cond_signal( &Cond1_id );
0291   rtems_test_assert( !status );
0292 
0293   empty_line();
0294 
0295   status = pthread_create( &Task2_id, NULL, Task_2, NULL );
0296   rtems_test_assert( !status );
0297 
0298 /* switch to task1 and task2 to allow them to wait for broadcast signal */
0299 
0300   puts( "Init: sleep - switch to Task_1 and Task_2" );
0301   sleep( 1 );
0302 
0303 /* broadcast a condition variable to task1 and task2 */
0304 
0305   puts( "Init: pthread_cond_broadcast" );
0306   status = pthread_cond_broadcast( &Cond1_id );
0307   rtems_test_assert( !status );
0308 
0309   puts( "Init: sleep - switch to Task_1" );
0310   sleep( 0 );
0311 
0312 /* timedwait case - timeout */
0313 
0314   status = pthread_mutex_lock( &Mutex_id );
0315   rtems_test_assert( !status );
0316 
0317 /* set timeout to 3 seconds */
0318 
0319   status = clock_gettime( CLOCK_REALTIME, &timeout );
0320   rtems_test_assert( !status );
0321   timeout.tv_sec += 3;
0322   timeout.tv_nsec = 0;
0323 
0324   puts( "Init: pthread_cond_timedwait for 3 seconds" );
0325   status = pthread_cond_timedwait( &Cond1_id, &Mutex_id, &timeout );
0326   if ( status != ETIMEDOUT )
0327     printf( "status = %d\n", status );
0328   rtems_test_assert( status == ETIMEDOUT );
0329   puts( "Init: pthread_cond_timedwait - ETIMEDOUT - (mutex not acquired)" );
0330 
0331   status = pthread_mutex_unlock( &Mutex_id );
0332   rtems_test_assert( !status );
0333 
0334 /* remaining error messages */
0335 
0336   empty_line();
0337 
0338 /* errors for bad variable passed */
0339 
0340   status = pthread_cond_signal( NULL );
0341   if ( status != EINVAL )
0342     printf( "status = %d\n", status );
0343   rtems_test_assert( status == EINVAL );
0344   puts( "Init: pthread_cond_signal - EINVAL (cond invalid)" );
0345 
0346   status = pthread_cond_broadcast( NULL );
0347   if ( status != EINVAL )
0348     printf( "status = %d\n", status );
0349   rtems_test_assert( status == EINVAL );
0350   puts( "Init: pthread_cond_broadcast - EINVAL (cond invalid)" );
0351 
0352 /* acquire mutex so errors will occur */
0353 
0354   status = pthread_mutex_lock( &Mutex_id );
0355   rtems_test_assert( !status );
0356 
0357   status = pthread_cond_wait( NULL, &Mutex_id );
0358   if ( status != EINVAL )
0359     printf( "status = %d\n", status );
0360   rtems_test_assert( status == EINVAL );
0361   puts( "Init: pthread_cond_wait - EINVAL (cond invalid)" );
0362 
0363   status = pthread_cond_timedwait( NULL, &Mutex_id, &timeout );
0364   if ( status != EINVAL )
0365     printf( "status = %d\n", status );
0366   rtems_test_assert( status == EINVAL );
0367   puts( "Init: pthread_cond_timedwait - EINVAL (cond invalid)" );
0368 
0369   status = pthread_cond_wait( &Cond1_id, NULL );
0370   if ( status != EINVAL )
0371     printf( "status = %d\n", status );
0372   rtems_test_assert( status == EINVAL );
0373   puts( "Init: pthread_cond_wait - EINVAL (mutex invalid)" );
0374 
0375   status = pthread_cond_timedwait( &Cond1_id, NULL, &timeout );
0376   if ( status != EINVAL )
0377     printf( "status = %d\n", status );
0378   rtems_test_assert( status == EINVAL );
0379   puts( "Init: pthread_cond_timedwait - EINVAL (mutex invalid)" );
0380 
0381   status = pthread_cond_timedwait( &Cond1_id, &Mutex_id, NULL );
0382   if ( status != EINVAL )
0383     printf( "status = %d\n", status );
0384   rtems_test_assert( status == EINVAL );
0385   puts( "Init: pthread_cond_timedwait - EINVAL (abstime NULL)" );
0386 
0387   status = clock_gettime( CLOCK_REALTIME, &timeout );
0388   rtems_test_assert( !status );
0389   timeout.tv_sec -= 1;
0390   status = pthread_cond_timedwait( &Cond1_id, &Mutex_id, &timeout );
0391   if ( status != ETIMEDOUT )
0392     printf( "status = %d\n", status );
0393   rtems_test_assert( status == ETIMEDOUT );
0394   puts( "Init: pthread_cond_timedwait - ETIMEDOUT (abstime->tv_sec < current time)" );
0395   status = pthread_mutex_unlock( &Mutex_id );
0396   rtems_test_assert( !status );
0397 
0398   status = pthread_mutex_lock( &Mutex_id );
0399   rtems_test_assert( !status );
0400 
0401   /* ensure we do not catch a 0 nanosecond boundary */
0402   do {
0403     status = clock_gettime( CLOCK_REALTIME, &timeout );
0404     rtems_test_assert( !status );
0405     timeout.tv_nsec -= 1;
0406   } while ( timeout.tv_nsec < 0);
0407 
0408   status = pthread_cond_timedwait( &Cond1_id, &Mutex_id, &timeout );
0409   if ( status != ETIMEDOUT )
0410     printf( "status = %d\n", status );
0411   rtems_test_assert( status == ETIMEDOUT );
0412   puts( "Init: pthread_cond_timedwait - ETIMEDOUT (abstime->tv_nsec < current time)" );
0413   status = pthread_mutex_unlock( &Mutex_id );
0414   rtems_test_assert( !status );
0415 
0416 /* wait and timedwait without mutex */
0417 
0418 /* XXX - this case is commented out in the code pending review
0419  *
0420  *   status = pthread_cond_wait( &Cond1_id, &Mutex_id );
0421  *   if ( status != EINVAL )
0422  *     printf( "status = %d\n", status );
0423  *   rtems_test_assert( status == EINVAL );
0424  */
0425   puts( "Init: pthread_cond_wait - EINVAL (mutex not locked before call)" );
0426 
0427 /* XXX - this case is commented out in the code pending review
0428  *
0429  *  status = clock_gettime( CLOCK_REALTIME, &timeout );
0430  *  rtems_test_assert( !status );
0431  *  timeout.tv_sec += 1;
0432  *  status = pthread_cond_timedwait( &Cond1_id, &Mutex_id, &timeout );
0433  *  if ( status != EINVAL )
0434  *    printf( "status = %d\n", status );
0435  *  rtems_test_assert( status == EINVAL );
0436  */
0437   puts( "Init: pthread_cond_timedwait - EINVAL (mutex not locked before call)");
0438 
0439   empty_line();
0440 
0441   status = pthread_create( &Task3_id, NULL, Task_3, NULL );
0442   rtems_test_assert( !status );
0443 
0444 /* switch to task3 to allow it to wait for broadcast signal */
0445 
0446   puts( "Init: sleep - switch to Task_3" );
0447   sleep( 1 );
0448 
0449 /* destroy the mutex so Task3 can not acguire at the end of Wait_support */
0450 
0451   status = pthread_mutex_destroy( &Mutex_id );
0452   rtems_test_assert( !status );
0453 
0454 /* signal a condition variable to task3 */
0455 
0456   puts( "Init: pthread_cond_signal" );
0457   status = pthread_cond_signal( &Cond1_id );
0458 
0459   puts( "Init: sleep - switch to Task_3" );
0460   sleep( 1 );
0461 
0462   TEST_END();
0463   rtems_test_exit( 0 );
0464 
0465   return NULL; /* just so the compiler thinks we returned something */
0466 }