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  *  This test exercises the POSIX Barrier manager.
0005  *
0006  *  COPYRIGHT (c) 1989-2009.
0007  *  On-Line Applications Research Corporation (OAR).
0008  *
0009  *  Copyright (c) 2017 embedded brains GmbH & Co. KG
0010  *
0011  * Redistribution and use in source and binary forms, with or without
0012  * modification, are permitted provided that the following conditions
0013  * are met:
0014  * 1. Redistributions of source code must retain the above copyright
0015  *    notice, this list of conditions and the following disclaimer.
0016  * 2. Redistributions in binary form must reproduce the above copyright
0017  *    notice, this list of conditions and the following disclaimer in the
0018  *    documentation and/or other materials provided with the distribution.
0019  *
0020  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
0021  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
0022  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
0023  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
0024  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
0025  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
0026  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
0027  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
0028  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
0029  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
0030  * POSSIBILITY OF SUCH DAMAGE.
0031  */
0032 
0033 #ifdef HAVE_CONFIG_H
0034 #include "config.h"
0035 #endif
0036 
0037 #include <stdio.h>
0038 #include <errno.h>
0039 #include <stdlib.h>
0040 #include <string.h>
0041 
0042 /* #define __USE_XOPEN2K XXX already defined on GNU/Linux */
0043 #include <pthread.h>
0044 
0045 #include "tmacros.h"
0046 
0047 const char rtems_test_name[] = "PSXBARRIER 1";
0048 
0049 static void test_barrier_null( void )
0050 {
0051   int eno;
0052 
0053   eno = pthread_barrier_init( NULL, NULL, 1 );
0054   rtems_test_assert( eno == EINVAL );
0055 
0056   eno = pthread_barrier_wait( NULL );
0057   rtems_test_assert( eno == EINVAL );
0058 
0059   eno = pthread_barrier_destroy( NULL );
0060   rtems_test_assert( eno == EINVAL );
0061 }
0062 
0063 static void test_barrier_not_initialized( void )
0064 {
0065   pthread_barrier_t bar;
0066   int eno;
0067 
0068   memset( &bar, 0xff, sizeof( bar ) );
0069 
0070   eno = pthread_barrier_wait(& bar) ;
0071   rtems_test_assert( eno == EINVAL );
0072 
0073   eno = pthread_barrier_destroy( &bar );
0074   rtems_test_assert( eno == EINVAL );
0075 }
0076 
0077 static void test_barrier_invalid_copy( void )
0078 {
0079   pthread_barrier_t bar;
0080   pthread_barrier_t bar2;
0081   int eno;
0082 
0083   eno = pthread_barrier_init( &bar, NULL, 1 );
0084   rtems_test_assert( eno == 0 );
0085 
0086   memcpy( &bar2, &bar, sizeof( bar2 ) );
0087 
0088   eno = pthread_barrier_wait( &bar2 );
0089   rtems_test_assert( eno == EINVAL );
0090 
0091   eno = pthread_barrier_destroy( &bar2 );
0092   rtems_test_assert( eno == EINVAL );
0093 
0094   eno = pthread_barrier_destroy( &bar );
0095   rtems_test_assert( eno == 0 );
0096 }
0097 
0098 #define NUMBER_THREADS 2
0099 pthread_t ThreadIds[NUMBER_THREADS];
0100 pthread_barrier_t Barrier;
0101 void *BarrierThread(void *arg);
0102 
0103 void *BarrierThread(void *arg)
0104 {
0105   pthread_t id = *(pthread_t *) arg;
0106   int       status;
0107 
0108   printf( "pthread_barrier_wait( &Barrier ) for thread 0x%08" PRIxpthread_t "\n", id );
0109   status = pthread_barrier_wait( &Barrier );
0110   printf( "pthread_barrier_wait - 0x%08" PRIxpthread_t " released\n", id );
0111   rtems_test_assert( (status == 0) || (status == PTHREAD_BARRIER_SERIAL_THREAD) );
0112 
0113   return NULL;
0114 }
0115 
0116 /*
0117  *  main entry point to the test
0118  */
0119 
0120 #if defined(__rtems__)
0121 int test_main(void);
0122 
0123 int test_main(void)
0124 #else
0125 int main(
0126   int    argc,
0127   char **argv
0128 )
0129 #endif
0130 {
0131   pthread_barrier_t    *bad_barrier = NULL;
0132   pthread_barrier_t     barrier;
0133   pthread_barrierattr_t attr;
0134   int                   status;
0135   int                   p;
0136   int                   i;
0137 
0138   TEST_BEGIN();
0139 
0140   /*************** NULL POINTER CHECKS *****************/
0141   puts( "pthread_barrierattr_init( NULL ) -- EINVAL" );
0142   status = pthread_barrierattr_init( NULL );
0143   rtems_test_assert( status == EINVAL );
0144 
0145   puts( "pthread_barrierattr_setpshared( NULL, private ) -- EINVAL" );
0146   status = pthread_barrierattr_setpshared( NULL, PTHREAD_PROCESS_PRIVATE );
0147   rtems_test_assert( status == EINVAL );
0148 
0149   puts( "pthread_barrierattr_setpshared( NULL, shared ) -- EINVAL" );
0150   status = pthread_barrierattr_setpshared( NULL, PTHREAD_PROCESS_SHARED );
0151   rtems_test_assert( status == EINVAL );
0152 
0153   puts( "pthread_barrierattr_getpshared( NULL, &p ) -- EINVAL" );
0154   status = pthread_barrierattr_getpshared( NULL, &p );
0155   rtems_test_assert( status == EINVAL );
0156 
0157   puts( "pthread_barrierattr_destroy( NULL ) -- EINVAL" );
0158   status = pthread_barrierattr_destroy( NULL );
0159   rtems_test_assert( status == EINVAL );
0160 
0161   /*************** NOT INITIALIZED CHECKS *****************/
0162   /* cheat visibility */
0163   attr.is_initialized = 0;
0164   puts( "pthread_barrierattr_setpshared( &attr, shared ) -- EINVAL" );
0165   status = pthread_barrierattr_setpshared( &attr, PTHREAD_PROCESS_SHARED );
0166   rtems_test_assert( status == EINVAL );
0167 
0168   puts( "pthread_barrierattr_getpshared( &attr, NULL ) -- EINVAL" );
0169   status = pthread_barrierattr_getpshared( &attr, NULL );
0170   rtems_test_assert( status == EINVAL );
0171 
0172   puts( "pthread_barrierattr_destroy( &attr ) -- EINVAL" );
0173   status = pthread_barrierattr_destroy( &attr );
0174   rtems_test_assert( status == EINVAL );
0175 
0176 
0177   /*************** ACTUALLY WORK THIS TIME *****************/
0178 
0179   puts( "pthread_barrierattr_init( &attr ) -- OK" );
0180   status = pthread_barrierattr_init( &attr );
0181   rtems_test_assert( status == 0 );
0182 
0183   puts( "pthread_barrierattr_setpshared( &attr, private ) -- OK" );
0184   status = pthread_barrierattr_setpshared( &attr, PTHREAD_PROCESS_PRIVATE );
0185   rtems_test_assert( status == 0 );
0186 
0187   puts( "pthread_barrierattr_getpshared( &attr, &p ) -- OK" );
0188   status = pthread_barrierattr_getpshared( &attr, &p );
0189   rtems_test_assert( status == 0 );
0190   rtems_test_assert( p == PTHREAD_PROCESS_PRIVATE );
0191 
0192   puts( "pthread_barrierattr_setpshared( &attr, shared ) -- OK" );
0193   status = pthread_barrierattr_setpshared( &attr, PTHREAD_PROCESS_SHARED );
0194   rtems_test_assert( status == 0 );
0195 
0196   puts( "pthread_barrierattr_getpshared( &attr, &p ) -- OK" );
0197   status = pthread_barrierattr_getpshared( &attr, &p );
0198   rtems_test_assert( status == 0 );
0199   rtems_test_assert( p == PTHREAD_PROCESS_SHARED );
0200 
0201   /*************** BAD PSHARED CHECK *****************/
0202   puts( "pthread_barrierattr_setpshared( &attr, private ) -- EINVAL" );
0203   status = pthread_barrierattr_setpshared( &attr, ~PTHREAD_PROCESS_PRIVATE );
0204   rtems_test_assert( status == EINVAL );
0205 
0206   /*************** DESTROY/REUSE CHECK *****************/
0207   puts( "pthread_barrierattr_destroy( &attr ) -- OK" );
0208   status = pthread_barrierattr_destroy( &attr );
0209   rtems_test_assert( status == 0 );
0210 
0211   puts( "pthread_barrierattr_getpshared( &attr, &p ) destroyed -- EINVAL" );
0212   status = pthread_barrierattr_getpshared( &attr, &p );
0213   rtems_test_assert( status == EINVAL );
0214 
0215   /*************** pthread_barrier_init ERROR CHECKs *********/
0216   /* NULL barrier argument */
0217   puts( "pthread_barrier_init( NULL, NULL, 2 ) -- EINVAL" );
0218   status = pthread_barrier_init( NULL, NULL, 2 );
0219   rtems_test_assert( status == EINVAL );
0220 
0221   /* uninitialized attr argument */
0222   puts( "pthread_barrier_init( &barrier, &attr, 2 ) -- EINVAL" );
0223   status = pthread_barrier_init( &barrier, &attr, 2 );
0224   rtems_test_assert( status == EINVAL );
0225 
0226   /* zero count argument */
0227   puts( "pthread_barrierattr_init( &attr ) -- OK" );
0228   status = pthread_barrierattr_init( &attr );
0229   rtems_test_assert( status == 0 );
0230 
0231   puts( "pthread_barrier_init( &barrier, &attr, 0 ) -- EINVAL" );
0232   status = pthread_barrier_init( &barrier, &attr, 0 );
0233   rtems_test_assert( status == EINVAL );
0234 
0235   puts( "pthread_barrier_init( &barrier, &attr, 1 ) -- EINVAL" );
0236   attr.process_shared = -1;
0237   status = pthread_barrier_init( &barrier, &attr, 1 );
0238   rtems_test_assert( status == EINVAL );
0239 
0240   puts( "pthread_barrierattr_setpshared( &attr, shared ) -- OK" );
0241   status = pthread_barrierattr_setpshared( &attr, PTHREAD_PROCESS_SHARED );
0242   rtems_test_assert( status == 0 );
0243 
0244   puts( "pthread_barrier_init( &barrier, &attr, 1 ) -- OK" );
0245   status = pthread_barrier_init( &barrier, &attr, 1 );
0246   rtems_test_assert( status == 0 );
0247 
0248   puts( "pthread_barrier_destroy( &barrier ) -- OK" );
0249   status = pthread_barrier_destroy( &barrier );
0250   rtems_test_assert( status == 0 );
0251 
0252   puts( "pthread_barrierattr_destroy( &attr ) -- OK" );
0253   status = pthread_barrierattr_destroy( &attr );
0254   rtems_test_assert( status == 0 );
0255 
0256   /*************** pthread_barrier_destroy ERROR CHECKs *********/
0257   /* NULL barrier argument */
0258   puts( "pthread_barrier_destroy( NULL ) -- EINVAL" );
0259   status = pthread_barrier_destroy( NULL );
0260   rtems_test_assert( status == EINVAL );
0261 
0262   puts( "pthread_barrier_destroy( bad_barrier ) -- EINVAL" );
0263   status = pthread_barrier_destroy( bad_barrier );
0264   rtems_test_assert( status == EINVAL );
0265 
0266   /*************** pthread_barrier_wait ERROR CHECKs *********/
0267   /* NULL barrier argument */
0268   puts( "pthread_barrier_wait( NULL ) -- EINVAL" );
0269   status = pthread_barrier_wait( NULL );
0270   rtems_test_assert( status == EINVAL );
0271 
0272   puts( "pthread_barrier_wait( bad_barrier ) -- EINVAL" );
0273   status = pthread_barrier_wait( bad_barrier );
0274   rtems_test_assert( status == EINVAL );
0275 
0276   /*************** ACTUALLY CREATE ONE CHECK *****************/
0277   puts( "pthread_barrierattr_init( &attr ) -- OK" );
0278   status = pthread_barrierattr_init( &attr );
0279   rtems_test_assert( status == 0 );
0280 
0281   puts( "pthread_barrier_init( &barrier, &attr, 2 ) -- OK" );
0282   status = pthread_barrier_init( &barrier, &attr, 2 );
0283   rtems_test_assert( status == 0 );
0284 
0285   puts( "pthread_barrier_destroy( &barrier ) -- OK" );
0286   status = pthread_barrier_destroy( &barrier );
0287   rtems_test_assert( status == 0 );
0288 
0289   /*************** CREATE THREADS AND LET THEM RELEASE *****************/
0290   puts( "pthread_barrier_init( &Barrier, &attr, NUMBER_THREADS ) -- OK" );
0291   status = pthread_barrier_init( &Barrier, &attr, NUMBER_THREADS );
0292   rtems_test_assert( status == 0 );
0293 
0294   for (i=0 ; i<NUMBER_THREADS ; i++ ) {
0295 
0296     /* check for unable to destroy while threads waiting */
0297     if (i == NUMBER_THREADS - 1) {
0298       puts( "pthread_barrier_destroy( &Barrier ) -- EBUSY" );
0299       status = pthread_barrier_destroy( &Barrier );
0300       rtems_test_assert( status == EBUSY );
0301     }
0302 
0303     /* create a thread to block on the barrier */
0304     printf( "Init: pthread_create - thread %d OK\n", i+1 );
0305     status = pthread_create(&ThreadIds[i], NULL, BarrierThread, &ThreadIds[i]);
0306     rtems_test_assert( !status );
0307 
0308     sleep(1);
0309   }
0310 
0311   test_barrier_null();
0312   test_barrier_not_initialized();
0313   test_barrier_invalid_copy();
0314 
0315   /*************** END OF TEST *****************/
0316   TEST_END();
0317   exit(0);
0318 }