File indexing completed on 2025-05-11 08:24:36
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
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
0164
0165 set_time( TM_FRIDAY, TM_MAY, 24, 96, 11, 5, 0 );
0166
0167
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
0180
0181 puts( "Init: pthread_detach self" );
0182 status = pthread_detach( pthread_self() );
0183 rtems_test_assert( !status );
0184
0185
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
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 }