File indexing completed on 2025-05-11 08:24:40
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 #ifdef HAVE_CONFIG_H
0030 #include "config.h"
0031 #endif
0032
0033 #include <sched.h>
0034 #include <semaphore.h>
0035 #include <errno.h>
0036 #include <fcntl.h>
0037 #include <limits.h>
0038 #include <time.h>
0039 #include <tmacros.h>
0040 #include <pmacros.h>
0041 #include "test_support.h"
0042
0043 const char rtems_test_name[] = "PSXSEM 1";
0044
0045
0046 void *POSIX_Init(void *argument);
0047
0048 #define MAX_SEMS 10
0049
0050 static void *sem_wait_task(void *arg)
0051 {
0052 sem_t *sem;
0053 int rv;
0054
0055 sem = arg;
0056
0057 rv = sem_wait( sem );
0058 rtems_test_assert( rv == 0 );
0059
0060 rv = sem_wait( sem );
0061 rtems_test_assert( rv == 0 );
0062
0063 return NULL;
0064 }
0065
0066 static void test_sem_wait_during_delete(void)
0067 {
0068 sem_t sem;
0069 int rv;
0070 pthread_t th;
0071 int eno;
0072 int val;
0073
0074 rv = sem_init( &sem, 0, 1 );
0075 rtems_test_assert( rv == 0 );
0076
0077 eno = pthread_create( &th, NULL, sem_wait_task, &sem );
0078 rtems_test_assert( eno == 0 );
0079
0080 rv = sem_getvalue( &sem, &val );
0081 rtems_test_assert( rv == 0 );
0082 rtems_test_assert( val == 1 );
0083
0084 sched_yield();
0085
0086 rv = sem_getvalue( &sem, &val );
0087 rtems_test_assert( rv == 0 );
0088 rtems_test_assert( val == 0 );
0089
0090 errno = 0;
0091 rv = sem_destroy( &sem );
0092 rtems_test_assert( rv == -1 );
0093 rtems_test_assert( errno == EBUSY );
0094
0095 rv = sem_post( &sem );
0096 rtems_test_assert( rv == 0 );
0097
0098 eno = pthread_join( th, NULL );
0099 rtems_test_assert( eno == 0 );
0100
0101 rv = sem_destroy( &sem );
0102 rtems_test_assert( rv == 0 );
0103 }
0104
0105 static void test_named_sem_wait_during_delete(void)
0106 {
0107 sem_t *sem;
0108 sem_t *sem2;
0109 int rv;
0110 pthread_t th;
0111 int eno;
0112 int val;
0113
0114 sem = sem_open( "sem", O_CREAT | O_EXCL, 0777, 1 );
0115 rtems_test_assert( sem != SEM_FAILED );
0116
0117 sem2 = sem_open( "sem", 0 );
0118 rtems_test_assert( sem2 != SEM_FAILED );
0119 rtems_test_assert( sem == sem2 );
0120
0121 eno = pthread_create( &th, NULL, sem_wait_task, sem );
0122 rtems_test_assert( eno == 0 );
0123
0124 rv = sem_getvalue( sem, &val );
0125 rtems_test_assert( rv == 0 );
0126 rtems_test_assert( val == 1 );
0127
0128 sched_yield();
0129
0130 rv = sem_getvalue( sem, &val );
0131 rtems_test_assert( rv == 0 );
0132 rtems_test_assert( val == 0 );
0133
0134 rv = sem_close( sem2 );
0135 rtems_test_assert( rv == 0 );
0136
0137 errno = 0;
0138 rv = sem_close( sem );
0139 rtems_test_assert( rv == -1 );
0140 rtems_test_assert( errno == EBUSY );
0141
0142 rv = sem_post( sem );
0143 rtems_test_assert( rv == 0 );
0144
0145 eno = pthread_join( th, NULL );
0146 rtems_test_assert( eno == 0 );
0147
0148 rv = sem_close( sem );
0149 rtems_test_assert( rv == 0 );
0150
0151 rv = sem_unlink( "sem" );
0152 rtems_test_assert( rv == 0 );
0153 }
0154
0155 static void test_sem_post_overflow(void)
0156 {
0157 sem_t sem;
0158 int rv;
0159 int val;
0160
0161 rv = sem_init( &sem, 0, SEM_VALUE_MAX );
0162 rtems_test_assert( rv == 0 );
0163
0164 rv = sem_getvalue( &sem, &val );
0165 rtems_test_assert( rv == 0 );
0166 rtems_test_assert( val == (int) SEM_VALUE_MAX );
0167
0168 errno = 0;
0169 rv = sem_post( &sem );
0170 rtems_test_assert( rv == -1 );
0171 rtems_test_assert( errno == EOVERFLOW );
0172
0173 rv = sem_getvalue( &sem, &val );
0174 rtems_test_assert( rv == 0 );
0175 rtems_test_assert( val == (int) SEM_VALUE_MAX );
0176
0177 rv = sem_wait( &sem );
0178 rtems_test_assert( rv == 0 );
0179
0180 rv = sem_post( &sem );
0181 rtems_test_assert( rv == 0 );
0182
0183 rv = sem_destroy( &sem );
0184 rtems_test_assert( rv == 0 );
0185 }
0186
0187 static void test_sem_init_too_large_inital_value(void)
0188 {
0189 sem_t sem;
0190 sem_t *sem2;
0191 int rv;
0192
0193 errno = 0;
0194 rv = sem_init( &sem, 0, (unsigned int) SEM_VALUE_MAX + 1 );
0195 rtems_test_assert( rv == -1 );
0196 rtems_test_assert( errno == EINVAL );
0197
0198 errno = 0;
0199 sem2 = sem_open(
0200 "sem",
0201 O_CREAT | O_EXCL,
0202 0777,
0203 (unsigned int) SEM_VALUE_MAX + 1
0204 );
0205 rtems_test_assert( sem2 == SEM_FAILED );
0206 rtems_test_assert( errno == EINVAL );
0207 }
0208
0209 static void test_sem_null(void)
0210 {
0211 int rv;
0212 int val;
0213 struct timespec to;
0214
0215
0216 rtems_test_assert( NULL == SEM_FAILED );
0217
0218 errno = 0;
0219 rv = sem_init( NULL, 0, 0 );
0220 rtems_test_assert( rv == -1 );
0221 rtems_test_assert( errno == EINVAL );
0222
0223 errno = 0;
0224 rv = sem_wait( NULL );
0225 rtems_test_assert( rv == -1 );
0226 rtems_test_assert( errno == EINVAL );
0227
0228 errno = 0;
0229 rv = sem_post( NULL );
0230 rtems_test_assert( rv == -1 );
0231 rtems_test_assert( errno == EINVAL );
0232
0233 errno = 0;
0234 rv = sem_wait( NULL );
0235 rtems_test_assert( rv == -1 );
0236 rtems_test_assert( errno == EINVAL );
0237
0238 errno = 0;
0239 rv = sem_trywait( NULL );
0240 rtems_test_assert( rv == -1 );
0241 rtems_test_assert( errno == EINVAL );
0242
0243 to.tv_sec = 1;
0244 to.tv_nsec = 1;
0245 errno = 0;
0246 rv = sem_timedwait( NULL, &to );
0247 rtems_test_assert( rv == -1 );
0248 rtems_test_assert( errno == EINVAL );
0249
0250 errno = 0;
0251 rv = sem_getvalue( NULL, &val );
0252 rtems_test_assert( rv == -1 );
0253 rtems_test_assert( errno == EINVAL );
0254
0255 errno = 0;
0256 rv = sem_destroy( NULL );
0257 rtems_test_assert( rv == -1 );
0258 rtems_test_assert( errno == EINVAL );
0259
0260 errno = 0;
0261 rv = sem_close( NULL );
0262 rtems_test_assert( rv == -1 );
0263 rtems_test_assert( errno == EINVAL );
0264 }
0265
0266 static void test_sem_not_initialized(void)
0267 {
0268 sem_t sem;
0269 int rv;
0270 int val;
0271 struct timespec to;
0272
0273 memset( &sem, 0xff, sizeof( sem ) );
0274
0275 errno = 0;
0276 rv = sem_wait( &sem );
0277 rtems_test_assert( rv == -1 );
0278 rtems_test_assert( errno == EINVAL );
0279
0280 errno = 0;
0281 rv = sem_post( &sem );
0282 rtems_test_assert( rv == -1 );
0283 rtems_test_assert( errno == EINVAL );
0284
0285 errno = 0;
0286 rv = sem_wait( &sem );
0287 rtems_test_assert( rv == -1 );
0288 rtems_test_assert( errno == EINVAL );
0289
0290 errno = 0;
0291 rv = sem_trywait( &sem );
0292 rtems_test_assert( rv == -1 );
0293 rtems_test_assert( errno == EINVAL );
0294
0295 to.tv_sec = 1;
0296 to.tv_nsec = 1;
0297 errno = 0;
0298 rv = sem_timedwait( &sem, &to );
0299 rtems_test_assert( rv == -1 );
0300 rtems_test_assert( errno == EINVAL );
0301
0302 errno = 0;
0303 rv = sem_getvalue( &sem, &val );
0304 rtems_test_assert( rv == -1 );
0305 rtems_test_assert( errno == EINVAL );
0306
0307 errno = 0;
0308 rv = sem_destroy( &sem );
0309 rtems_test_assert( rv == -1 );
0310 rtems_test_assert( errno == EINVAL );
0311
0312 errno = 0;
0313 rv = sem_close( &sem );
0314 rtems_test_assert( rv == -1 );
0315 rtems_test_assert( errno == EINVAL );
0316 }
0317
0318 static void test_sem_invalid_copy(void)
0319 {
0320 sem_t sem;
0321 sem_t sem2;
0322 int rv;
0323 int val;
0324
0325 rv = sem_init( &sem, 0, 0 );
0326 rtems_test_assert( rv == 0 );
0327
0328 val = 1;
0329 rv = sem_getvalue( &sem, &val );
0330 rtems_test_assert( rv == 0 );
0331 rtems_test_assert( val == 0 );
0332
0333 memcpy( &sem2, &sem, sizeof( sem2 ) );
0334
0335 errno = 0;
0336 rv = sem_getvalue( &sem2, &val );
0337 rtems_test_assert( rv == -1 );
0338 rtems_test_assert( errno == EINVAL );
0339
0340 rv = sem_destroy( &sem );
0341 rtems_test_assert( rv == 0 );
0342
0343 errno = 0;
0344 rv = sem_getvalue( &sem, &val );
0345 rtems_test_assert( rv == -1 );
0346 rtems_test_assert( errno == EINVAL );
0347 }
0348
0349 void *POSIX_Init(
0350 void *argument
0351 )
0352 {
0353 int status;
0354 int value;
0355 int i;
0356 sem_t sems[MAX_SEMS];
0357 sem_t sem2;
0358 sem_t *n_sem1;
0359 sem_t *n_sem2;
0360 struct timespec waittime;
0361 char failure_msg[80];
0362
0363 TEST_BEGIN();
0364
0365 puts( "Init: sem_init - SUCCESSFUL" );
0366 status = sem_init(&sem2, 1, 1);
0367 fatal_posix_service_status( status, 0, "sem_init with pshared != 0");
0368
0369 puts( "Init: sem_destroy - SUCCESSFUL" );
0370 status = sem_destroy(&sem2);
0371 fatal_posix_service_status( status, 0, "sem_destroy");
0372
0373 puts( "Init: sem_init - UNSUCCESSFUL (EINVAL)" );
0374 status = sem_init(NULL, 0, 1);
0375 fatal_posix_service_status( status, -1, "sem_init error return status");
0376 fatal_posix_service_status( errno, EINVAL, "sem_init errorno EINVAL" );
0377
0378 puts( "Init: sem_init - SUCCESSFUL" );
0379 for (i = 0; i < MAX_SEMS; i++) {
0380 status = sem_init(&sems[i], 0, i);
0381 sprintf(failure_msg, "sem_init %d", i );
0382 fatal_posix_service_status( status, 0, failure_msg);
0383 }
0384
0385 puts( "Init: sem_init - SUCCESSFUL" );
0386 status = sem_init(&sem2, 0, 1);
0387 fatal_posix_service_status( status, 0, "sem_init");
0388
0389 puts( "Init: sem_destroy - SUCCESSFUL" );
0390 status = sem_destroy(&sem2);
0391 fatal_posix_service_status( status, 0, "sem_destroy");
0392
0393 puts( "Init: sem_getvalue - SUCCESSFUL ");
0394 for (i = 0; i < MAX_SEMS; i++) {
0395 status = sem_getvalue(&sems[i], &value);
0396 sprintf( failure_msg, "sem_getvalue %d", i );
0397 fatal_posix_service_status( status, 0, failure_msg );
0398 fatal_posix_service_status( value, i, "sem_getvalue correct value" );
0399 }
0400 puts( "Init: sem_getvalue - UNSUCCESSFUL ");
0401 status = sem_getvalue(SEM_FAILED, &value);
0402 fatal_posix_service_status( status, -1, "sem_getvalue error return status");
0403 fatal_posix_service_status( errno, EINVAL, "sem_getvalue errno EINVAL");
0404
0405 puts( "Init: sem_destroy - SUCCESSFUL" );
0406 status = sem_destroy(&sems[0]);
0407 fatal_posix_service_status( status, 0, "sem_destroy semaphore 0");
0408
0409 puts( "Init: sem_destroy - UNSUCCESSFUL (EINVAL)" );
0410 status = sem_destroy(SEM_FAILED);
0411 fatal_posix_service_status( status, -1, "sem_destroy error return status");
0412 fatal_posix_service_status( errno, EINVAL, "sem_destroy errno EINVAL");
0413
0414 puts( "Init: sem_wait - SUCCESSFUL" );
0415 status = sem_wait(&sems[1]);
0416 fatal_posix_service_status( status, 0, "sem_wait semaphore 1");
0417
0418
0419 puts( "Init: sem_wait - UNSUCCESSFUL (EINVAL)" );
0420 status = sem_wait(SEM_FAILED);
0421 fatal_posix_service_status( status, -1, "sem_wait error return status");
0422 fatal_posix_service_status( errno, EINVAL, "sem_wait errno EINVAL");
0423
0424 puts( "Init: sem_post - SUCCESSFUL" );
0425 status = sem_post(&sems[1]);
0426 fatal_posix_service_status( status, 0, "sem_post semaphore 1");
0427
0428
0429 puts( "Init: sem_wait - SUCCESSFUL (after a sem_post)" );
0430 status = sem_wait(&sems[1]);
0431 fatal_posix_service_status( status, 0, "sem_wait semaphore 1");
0432
0433
0434 puts( "Init: sem_trywait - SUCCESSFUL" );
0435 status = sem_trywait(&sems[2]);
0436 fatal_posix_service_status( status, 0, "sem_trywait semaphore 2");
0437
0438
0439 puts( "Init: sem_trywait - UNSUCCESSFUL (EAGAIN)" );
0440 status = sem_trywait(&sems[1]);
0441 fatal_posix_service_status( status, -1, "sem_trywait error return status");
0442 fatal_posix_service_status( errno, EAGAIN, "sem_trywait errno EAGAIN");
0443
0444
0445 puts( "Init: sem_trywait - UNSUCCESSFUL (EINVAL)" );
0446 status = sem_trywait(SEM_FAILED);
0447 fatal_posix_service_status( status, -1, "sem_trywait error return status");
0448 fatal_posix_service_status( errno, EINVAL, "sem_trywait errno EINVAL");
0449
0450 #if 0
0451 status = sem_post(&sems[2]);
0452 fatal_posix_service_status( status, 0, "sem_post semaphore 2");
0453
0454 #else
0455
0456 #endif
0457
0458 puts( "Init: sem_timedwait - SUCCESSFUL" );
0459 waittime.tv_sec = time(NULL) + 1;
0460 waittime.tv_nsec = 100;
0461 status = sem_timedwait(&sems[2], &waittime);
0462 fatal_posix_service_status( status, 0, "sem_timedwait semaphore 2");
0463
0464
0465 puts( "Init: sem_timedwait - UNSUCCESSFUL (ETIMEDOUT)" );
0466 status = sem_timedwait(&sems[2], &waittime);
0467 fatal_posix_service_status( status, -1, "sem_timedwait error return status");
0468 fatal_posix_service_status(
0469 errno, ETIMEDOUT, "sem_timedwait errno ETIMEDOUT");
0470
0471
0472
0473
0474
0475
0476 #if 1
0477 puts( "Init: sem_timedwait - UNSUCCESSFUL (EINVAL) -- skipping" );
0478 #else
0479 puts( "Init: sem_timedwait - UNSUCCESSFUL (EINVAL)" );
0480 waittime.tv_sec = 0;
0481 waittime.tv_nsec = 0x7FFFFFFF;
0482 status = sem_timedwait(&sems[2], &waittime);
0483 fatal_posix_service_status( status, -1, "sem_timedwait error return status");
0484 fatal_posix_service_status( errno, EINVAL, "sem_init errno EINVAL");
0485 #endif
0486
0487 puts( "Init: sem_post - UNSUCCESSFUL (EINVAL)" );
0488 status = sem_post(SEM_FAILED);
0489 fatal_posix_service_status( status, -1, "sem_post error return status");
0490 fatal_posix_service_status( errno, EINVAL, "sem_post errno EINVAL");
0491
0492 puts( "Init: sem_destroy - SUCCESSFUL" );
0493 for (i = 1; i < MAX_SEMS; i++) {
0494 status = sem_destroy(&sems[i]);
0495 sprintf( failure_msg, "sem_destroy %d", i );
0496 fatal_posix_service_status( status, 0, failure_msg );
0497 }
0498
0499
0500
0501
0502
0503
0504
0505 puts( "Init: sem_open - UNSUCCESSFUL (ENAMETOOLONG)" );
0506 n_sem1 = sem_open(Get_Too_Long_Name(), O_CREAT, 0777, 1 );
0507 fatal_posix_sem( n_sem1, "sem_open error return status" );
0508 fatal_posix_service_status(
0509 errno, ENAMETOOLONG, "sem_open errorno ENAMETOOLONG" );
0510
0511 puts( "Init: sem_open - sem1 SUCCESSFUL" );
0512 n_sem1 = sem_open( "sem1",O_CREAT, 0777, 1 );
0513 rtems_test_assert( n_sem1 != SEM_FAILED );
0514
0515 puts( "Init: sem_destroy - named sem1 - EINVAL" );
0516 status = sem_destroy(n_sem1);
0517 fatal_posix_service_status( status, -1, "sem_destroy named semaphore");
0518 fatal_posix_service_status( errno, EINVAL, "sem_destroy named semaphore");
0519
0520 puts( "Init: sem_open - Create an Existing sem (EEXIST)" );
0521 n_sem2 = sem_open("sem1", O_CREAT | O_EXCL, 0777, 1);
0522 fatal_posix_sem( n_sem2, "sem_open error return status" );
0523 fatal_posix_service_status( errno, EEXIST, "sem_open errno EEXIST");
0524
0525 puts( "Init: sem_open - Open new sem without create flag (ENOENT)" );
0526 n_sem2 = sem_open("sem3", O_EXCL, 0777, 1);
0527 fatal_posix_sem( n_sem2, "sem_open error return status" );
0528 fatal_posix_service_status( errno, ENOENT, "sem_open errno EEXIST");
0529
0530
0531
0532
0533
0534
0535
0536
0537
0538
0539
0540
0541 puts( "Init: sem_wait on sem1" );
0542 status = sem_wait(n_sem1);
0543 fatal_posix_service_status( status, 0, "sem_wait opened semaphore");
0544
0545
0546
0547
0548
0549 puts( "Init: sem_open - Open an existing sem ( same id )" );
0550 n_sem2 = sem_open("sem1", 0 );
0551 rtems_test_assert( n_sem2 == n_sem1 );
0552
0553
0554
0555
0556
0557
0558 puts( "Init: sem_unlink - sem1 SUCCESSFUL" );
0559 status = sem_unlink( "sem1" );
0560 fatal_posix_service_status( status, 0, "sem_unlink locked semaphore");
0561
0562 puts( "Init: sem_open - Reopen sem1 SUCCESSFUL with a different id" );
0563 n_sem2 = sem_open( "sem1", O_CREAT | O_EXCL, 0777, 1);
0564 rtems_test_assert( n_sem2 != SEM_FAILED );
0565 rtems_test_assert( n_sem2 != n_sem1 );
0566
0567
0568
0569
0570
0571 puts( "Init: sem_close (1) - SUCCESSFUL" );
0572 status = sem_close( n_sem1 );
0573 fatal_posix_service_status( status, 0, "sem_close semaphore");
0574
0575
0576
0577
0578
0579
0580 puts( "Init: sem_close (2) - SUCCESSFUL" );
0581 status = sem_close( n_sem2 );
0582 fatal_posix_service_status( status, 0, "sem_close semaphore");
0583
0584 puts( "Init: sem_unlink - sem1 (2) SUCCESSFUL" );
0585 status = sem_unlink( "sem1" );
0586 fatal_posix_service_status( status, 0, "sem_unlink locked semaphore");
0587
0588 puts( "Init: sem_close - UNSUCCESSFUL (EINVAL)" );
0589 status = sem_close(n_sem2);
0590 fatal_posix_service_status( status, -1, "sem_close error return status");
0591 fatal_posix_service_status( errno, EINVAL, "sem_close errno EINVAL");
0592
0593 puts( "Init: sem_unlink - UNSUCCESSFUL (ENOENT)" );
0594 status = sem_unlink("sem1");
0595 fatal_posix_service_status( status, -1, "sem_unlink error return status");
0596 fatal_posix_service_status( errno, ENOENT, "sem_close errno EINVAL");
0597
0598
0599
0600
0601
0602
0603 puts( "Init: sem_unlink (NULL) - EINVAL" );
0604 status = sem_unlink( NULL );
0605 fatal_posix_service_status( status, -1, "sem_unlink error return status");
0606 fatal_posix_service_status( errno, EINVAL, "sem_unlink errno value");
0607
0608 puts( "Init: sem_unlink (\"\") - ENOENT" );
0609 status = sem_unlink( "" );
0610 fatal_posix_service_status( status, -1, "sem_unlink error return status");
0611 fatal_posix_service_status( errno, ENOENT, "sem_unlink errno value");
0612
0613
0614
0615
0616
0617
0618 puts( "Init: sem_unlink - UNSUCCESSFUL (ENOENT)" );
0619 status = sem_unlink("sem2");
0620 fatal_posix_service_status( status, -1, "sem_unlink error return status");
0621 fatal_posix_service_status( errno, ENOENT, "sem_unlink errno ENOENT");
0622 rtems_test_assert( (status == -1) && (errno == ENOENT) );
0623
0624 test_named_sem_wait_during_delete();
0625 test_sem_wait_during_delete();
0626 test_sem_post_overflow();
0627 test_sem_init_too_large_inital_value();
0628 test_sem_null();
0629 test_sem_not_initialized();
0630 test_sem_invalid_copy();
0631
0632
0633
0634 TEST_END();
0635 rtems_test_exit(0);
0636
0637 return NULL;
0638 }
0639
0640
0641 #define CONFIGURE_APPLICATION_NEEDS_SIMPLE_CONSOLE_DRIVER
0642 #define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
0643
0644 #define CONFIGURE_POSIX_INIT_THREAD_TABLE
0645
0646 #define CONFIGURE_INITIAL_EXTENSIONS RTEMS_TEST_INITIAL_EXTENSION
0647
0648 #define CONFIGURE_MAXIMUM_POSIX_THREADS 2
0649 #define CONFIGURE_MAXIMUM_POSIX_SEMAPHORES 2
0650
0651 #define CONFIGURE_POSIX_INIT_THREAD_TABLE
0652 #define CONFIGURE_POSIX_INIT_THREAD_STACK_SIZE \
0653 (RTEMS_MINIMUM_STACK_SIZE * 4)
0654
0655 #define CONFIGURE_INIT
0656 #include <rtems/confdefs.h>