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  * Copyright (C) 2022 embedded brains GmbH & Co. KG
0008  *
0009  * Redistribution and use in source and binary forms, with or without
0010  * modification, are permitted provided that the following conditions
0011  * are met:
0012  * 1. Redistributions of source code must retain the above copyright
0013  *    notice, this list of conditions and the following disclaimer.
0014  * 2. Redistributions in binary form must reproduce the above copyright
0015  *    notice, this list of conditions and the following disclaimer in the
0016  *    documentation and/or other materials provided with the distribution.
0017  *
0018  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
0019  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
0020  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
0021  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
0022  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
0023  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
0024  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
0025  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
0026  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
0027  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
0028  * POSSIBILITY OF SUCH DAMAGE.
0029  */
0030 
0031 #ifdef HAVE_CONFIG_H
0032 #include "config.h"
0033 #endif
0034 
0035 #define CONFIGURE_INIT
0036 #include "system.h"
0037 #include <errno.h>
0038 
0039 const char rtems_test_name[] = "PSX 8";
0040 
0041 static void *async_join_thread( void *arg )
0042 {
0043   pthread_t *th;
0044   int        eno;
0045   int        type;
0046 
0047   th = arg;
0048 
0049   type = PTHREAD_CANCEL_ASYNCHRONOUS;
0050   eno = pthread_setcanceltype( type, &type );
0051   rtems_test_assert( eno == 0 );
0052   rtems_test_assert( type == PTHREAD_CANCEL_DEFERRED );
0053 
0054   (void) pthread_join( *th, NULL );
0055   rtems_test_assert( 0 );
0056 }
0057 
0058 static void test_join_deadlock( void )
0059 {
0060   pthread_t td;
0061   pthread_t self;
0062   int       eno;
0063   void     *value;
0064 
0065   self = pthread_self();
0066 
0067   eno = pthread_create( &td, NULL, async_join_thread, &self );
0068   rtems_test_assert( eno == 0 );
0069 
0070   sched_yield();
0071 
0072   eno = pthread_join( td, NULL );
0073   rtems_test_assert( eno == EDEADLK );
0074 
0075   eno = pthread_cancel( td );
0076   rtems_test_assert( eno == 0 );
0077 
0078   value = NULL;
0079   eno = pthread_join( td, &value );
0080   rtems_test_assert( eno == 0 );
0081   rtems_test_assert( value == PTHREAD_CANCELED );
0082 }
0083 
0084 typedef struct {
0085   pthread_t protected_join;
0086   pthread_t deleter;
0087   rtems_status_code delete_status;
0088 } delete_deadlock_context;
0089 
0090 static void *protected_join_thread( void *arg )
0091 {
0092   delete_deadlock_context *ctx;
0093   int                      state;
0094   int                      eno;
0095   void                    *value;
0096 
0097   ctx = arg;
0098 
0099   state = PTHREAD_CANCEL_DISABLE;
0100   eno = pthread_setcancelstate( state, &state );
0101   rtems_test_assert( eno == 0 );
0102   rtems_test_assert( state == PTHREAD_CANCEL_ENABLE );
0103 
0104   value = NULL;
0105   eno = pthread_join( ctx->deleter, &value );
0106   rtems_test_assert( eno == 0 );
0107   rtems_test_assert( value == &ctx->deleter );
0108 
0109   state = PTHREAD_CANCEL_ENABLE;
0110   eno = pthread_setcancelstate( state, &state );
0111   rtems_test_assert( eno == 0 );
0112   rtems_test_assert( state == PTHREAD_CANCEL_DISABLE );
0113 
0114   pthread_testcancel();
0115   rtems_test_assert( 0 );
0116 }
0117 
0118 static void *deleter_thread( void *arg )
0119 {
0120   delete_deadlock_context *ctx;
0121 
0122   ctx = arg;
0123   ctx->delete_status = rtems_task_delete( ctx->protected_join );
0124   return &ctx->deleter;
0125 }
0126 
0127 static void test_delete_deadlock( void )
0128 {
0129   delete_deadlock_context ctx;
0130   int                     eno;
0131   void                   *value;
0132 
0133   ctx.delete_status = RTEMS_NOT_IMPLEMENTED;
0134 
0135   eno = pthread_create(
0136     &ctx.protected_join,
0137     NULL,
0138     protected_join_thread,
0139     &ctx
0140   );
0141   rtems_test_assert( eno == 0 );
0142 
0143   eno = pthread_create( &ctx.deleter, NULL, deleter_thread, &ctx );
0144   rtems_test_assert( eno == 0 );
0145 
0146   value = NULL;
0147   eno = pthread_join( ctx.protected_join, &value );
0148   rtems_test_assert( eno == 0 );
0149   rtems_test_assert( value == PTHREAD_CANCELED );
0150 
0151   rtems_test_assert( ctx.delete_status == RTEMS_INCORRECT_STATE );
0152 }
0153 
0154 void *POSIX_Init(
0155   void *argument
0156 )
0157 {
0158   int    status;
0159   void  *return_pointer;
0160 
0161   TEST_BEGIN();
0162 
0163   /* set the time of day, and print our buffer in multiple ways */
0164 
0165   set_time( TM_FRIDAY, TM_MAY, 24, 96, 11, 5, 0 );
0166 
0167   /* get id of this thread */
0168 
0169   Init_id = pthread_self();
0170   printf( "Init's ID is 0x%08" PRIxpthread_t "\n", Init_id );
0171 
0172   test_join_deadlock();
0173   test_delete_deadlock();
0174 
0175   puts( "Init: pthread_detach - ESRCH (invalid id)" );
0176   status = pthread_detach( (pthread_t) -1 );
0177   rtems_test_assert( status == ESRCH );
0178 
0179   /* detach this thread */
0180 
0181   puts( "Init: pthread_detach self" );
0182   status = pthread_detach( pthread_self() );
0183   rtems_test_assert( !status );
0184 
0185   /* create thread */
0186 
0187   status = pthread_create( &Task1_id, NULL, Task_1, NULL );
0188   rtems_test_assert( !status );
0189 
0190   puts( "Init: pthread_join - ESRCH (invalid id)" );
0191   status = pthread_join( (pthread_t) -1, &return_pointer );
0192   rtems_test_assert( status == ESRCH );
0193 
0194   puts( "Init: pthread_join - SUCCESSFUL" );
0195   status = pthread_join( Task1_id, &return_pointer );
0196 
0197   puts( "Init: returned from pthread_join through return" );
0198   if ( status )
0199     printf( "status = %d\n", status );
0200   rtems_test_assert( !status );
0201 
0202   if ( return_pointer == &Task1_id )
0203     puts( "Init: pthread_join returned correct pointer" );
0204   else
0205     printf(
0206       "Init: pthread_join returned incorrect pointer (%p != %p)\n",
0207       return_pointer,
0208       &Task1_id
0209     );
0210 
0211   puts( "Init: creating two pthreads" );
0212   status = pthread_create( &Task2_id, NULL, Task_2, NULL );
0213   rtems_test_assert( !status );
0214 
0215   status = pthread_create( &Task3_id, NULL, Task_3, NULL );
0216   rtems_test_assert( !status );
0217 
0218   puts( "Init: pthread_join - SUCCESSFUL" );
0219   status = pthread_join( Task2_id, &return_pointer );
0220   /* assert is below comment */
0221 
0222   puts( "Init: returned from pthread_join through pthread_exit" );
0223   if ( status )
0224     printf( "status = %d\n", status );
0225   rtems_test_assert( !status );
0226 
0227   if ( return_pointer == &Task2_id )
0228     puts( "Init: pthread_join returned correct pointer" );
0229   else
0230     printf(
0231       "Init: pthread_join returned incorrect pointer (%p != %p)\n",
0232       return_pointer,
0233       &Task2_id
0234     );
0235 
0236   puts( "Init: exitting" );
0237   return NULL;
0238 }