From c090db7405b72ce6d0b726c0a39fb1c1aebab7ea Mon Sep 17 00:00:00 2001 From: Sebastian Huber Date: Tue, 12 Sep 2017 08:09:16 +0200 Subject: posix: Implement self-contained POSIX semaphores For semaphore object pointer and object validation see POSIX_SEMAPHORE_VALIDATE_OBJECT(). Destruction or close of a busy semaphore returns an error status. The object is not flushed. POSIX semaphores are now available in all configurations and no longer depend on --enable-posix. Update #2514. Update #3116. --- testsuites/psxtests/psxcancel/init.c | 1 - testsuites/psxtests/psxeintr_join/init.c | 1 - testsuites/psxtests/psxsem01/init.c | 241 +++++++++++++++++++++++++++++-- testsuites/psxtmtests/psxtmsem02/init.c | 1 - testsuites/psxtmtests/psxtmsem03/init.c | 1 - testsuites/psxtmtests/psxtmsem04/init.c | 1 - testsuites/psxtmtests/psxtmsem05/init.c | 1 - testsuites/sptests/spthreadq01/init.c | 18 --- 8 files changed, 227 insertions(+), 38 deletions(-) (limited to 'testsuites') diff --git a/testsuites/psxtests/psxcancel/init.c b/testsuites/psxtests/psxcancel/init.c index 90f474971d..c4c442b668 100644 --- a/testsuites/psxtests/psxcancel/init.c +++ b/testsuites/psxtests/psxcancel/init.c @@ -263,7 +263,6 @@ static void resourceSnapshotCheck( void ) #define CONFIGURE_INITIAL_EXTENSIONS RTEMS_TEST_INITIAL_EXTENSION #define CONFIGURE_MAXIMUM_POSIX_THREADS 2 -#define CONFIGURE_MAXIMUM_POSIX_SEMAPHORES 2 #define CONFIGURE_POSIX_INIT_THREAD_TABLE diff --git a/testsuites/psxtests/psxeintr_join/init.c b/testsuites/psxtests/psxeintr_join/init.c index 7fe0da73cd..f0810b50a5 100644 --- a/testsuites/psxtests/psxeintr_join/init.c +++ b/testsuites/psxtests/psxeintr_join/init.c @@ -130,7 +130,6 @@ void *POSIX_Init( void *arg ) #define CONFIGURE_INITIAL_EXTENSIONS RTEMS_TEST_INITIAL_EXTENSION #define CONFIGURE_MAXIMUM_POSIX_THREADS 2 -#define CONFIGURE_MAXIMUM_POSIX_SEMAPHORES 1 #define CONFIGURE_INIT #include diff --git a/testsuites/psxtests/psxsem01/init.c b/testsuites/psxtests/psxsem01/init.c index 9ba8935292..ae0b390a7c 100644 --- a/testsuites/psxtests/psxsem01/init.c +++ b/testsuites/psxtests/psxsem01/init.c @@ -38,10 +38,8 @@ static void *sem_wait_task(void *arg) rv = sem_wait( sem ); rtems_test_assert( rv == 0 ); - errno = 0; rv = sem_wait( sem ); - rtems_test_assert( rv == -1 ); - rtems_test_assert( errno == EINVAL ); + rtems_test_assert( rv == 0 ); return NULL; } @@ -70,11 +68,69 @@ static void test_sem_wait_during_delete(void) rtems_test_assert( rv == 0 ); rtems_test_assert( val == 0 ); + errno = 0; + rv = sem_destroy( &sem ); + rtems_test_assert( rv == -1 ); + rtems_test_assert( errno == EBUSY ); + + rv = sem_post( &sem ); + rtems_test_assert( rv == 0 ); + + eno = pthread_join( th, NULL ); + rtems_test_assert( eno == 0 ); + rv = sem_destroy( &sem ); rtems_test_assert( rv == 0 ); +} + +static void test_named_sem_wait_during_delete(void) +{ + sem_t *sem; + sem_t *sem2; + int rv; + pthread_t th; + int eno; + int val; + + sem = sem_open( "sem", O_CREAT | O_EXCL, 0777, 1 ); + rtems_test_assert( sem != SEM_FAILED ); + + sem2 = sem_open( "sem", 0 ); + rtems_test_assert( sem2 != SEM_FAILED ); + rtems_test_assert( sem == sem2 ); + + eno = pthread_create( &th, NULL, sem_wait_task, sem ); + rtems_test_assert( eno == 0 ); + + rv = sem_getvalue( sem, &val ); + rtems_test_assert( rv == 0 ); + rtems_test_assert( val == 1 ); + + sched_yield(); + + rv = sem_getvalue( sem, &val ); + rtems_test_assert( rv == 0 ); + rtems_test_assert( val == 0 ); + + rv = sem_close( sem2 ); + rtems_test_assert( rv == 0 ); + + errno = 0; + rv = sem_close( sem ); + rtems_test_assert( rv == -1 ); + rtems_test_assert( errno == EBUSY ); + + rv = sem_post( sem ); + rtems_test_assert( rv == 0 ); eno = pthread_join( th, NULL ); rtems_test_assert( eno == 0 ); + + rv = sem_close( sem ); + rtems_test_assert( rv == 0 ); + + rv = sem_unlink( "sem" ); + rtems_test_assert( rv == 0 ); } static void test_sem_post_overflow(void) @@ -110,12 +166,162 @@ static void test_sem_post_overflow(void) } static void test_sem_init_too_large_inital_value(void) +{ + sem_t sem; + sem_t *sem2; + int rv; + + errno = 0; + rv = sem_init( &sem, 0, (unsigned int) SEM_VALUE_MAX + 1 ); + rtems_test_assert( rv == -1 ); + rtems_test_assert( errno == EINVAL ); + + errno = 0; + sem2 = sem_open( + "sem", + O_CREAT | O_EXCL, + 0777, + (unsigned int) SEM_VALUE_MAX + 1 + ); + rtems_test_assert( sem2 == SEM_FAILED ); + rtems_test_assert( errno == EINVAL ); +} + +static void test_sem_null(void) +{ + int rv; + int val; + struct timespec to; + + rtems_test_assert( NULL == SEM_FAILED ); + + errno = 0; + rv = sem_init( NULL, 0, 0 ); + rtems_test_assert( rv == -1 ); + rtems_test_assert( errno == EINVAL ); + + errno = 0; + rv = sem_wait( NULL ); + rtems_test_assert( rv == -1 ); + rtems_test_assert( errno == EINVAL ); + + errno = 0; + rv = sem_post( NULL ); + rtems_test_assert( rv == -1 ); + rtems_test_assert( errno == EINVAL ); + + errno = 0; + rv = sem_wait( NULL ); + rtems_test_assert( rv == -1 ); + rtems_test_assert( errno == EINVAL ); + + errno = 0; + rv = sem_trywait( NULL ); + rtems_test_assert( rv == -1 ); + rtems_test_assert( errno == EINVAL ); + + to.tv_sec = 1; + to.tv_nsec = 1; + errno = 0; + rv = sem_timedwait( NULL, &to ); + rtems_test_assert( rv == -1 ); + rtems_test_assert( errno == EINVAL ); + + errno = 0; + rv = sem_getvalue( NULL, &val ); + rtems_test_assert( rv == -1 ); + rtems_test_assert( errno == EINVAL ); + + errno = 0; + rv = sem_destroy( NULL ); + rtems_test_assert( rv == -1 ); + rtems_test_assert( errno == EINVAL ); + + errno = 0; + rv = sem_close( NULL ); + rtems_test_assert( rv == -1 ); + rtems_test_assert( errno == EINVAL ); +} + +static void test_sem_not_initialized(void) { sem_t sem; + int rv; + int val; + struct timespec to; + + memset( &sem, 0xff, sizeof( sem ) ); + + errno = 0; + rv = sem_wait( &sem ); + rtems_test_assert( rv == -1 ); + rtems_test_assert( errno == EINVAL ); + + errno = 0; + rv = sem_post( &sem ); + rtems_test_assert( rv == -1 ); + rtems_test_assert( errno == EINVAL ); + + errno = 0; + rv = sem_wait( &sem ); + rtems_test_assert( rv == -1 ); + rtems_test_assert( errno == EINVAL ); + + errno = 0; + rv = sem_trywait( &sem ); + rtems_test_assert( rv == -1 ); + rtems_test_assert( errno == EINVAL ); + + to.tv_sec = 1; + to.tv_nsec = 1; + errno = 0; + rv = sem_timedwait( &sem, &to ); + rtems_test_assert( rv == -1 ); + rtems_test_assert( errno == EINVAL ); + + errno = 0; + rv = sem_getvalue( &sem, &val ); + rtems_test_assert( rv == -1 ); + rtems_test_assert( errno == EINVAL ); + + errno = 0; + rv = sem_destroy( &sem ); + rtems_test_assert( rv == -1 ); + rtems_test_assert( errno == EINVAL ); + + errno = 0; + rv = sem_close( &sem ); + rtems_test_assert( rv == -1 ); + rtems_test_assert( errno == EINVAL ); +} + +static void test_sem_invalid_copy(void) +{ + sem_t sem; + sem_t sem2; int rv; + int val; + + rv = sem_init( &sem, 0, 0 ); + rtems_test_assert( rv == 0 ); + + val = 1; + rv = sem_getvalue( &sem, &val ); + rtems_test_assert( rv == 0 ); + rtems_test_assert( val == 0 ); + + memcpy( &sem2, &sem, sizeof( sem2 ) ); errno = 0; - rv = sem_init( &sem, 0, (unsigned int) SEM_VALUE_MAX + 1 ); + rv = sem_getvalue( &sem2, &val ); + rtems_test_assert( rv == -1 ); + rtems_test_assert( errno == EINVAL ); + + rv = sem_destroy( &sem ); + rtems_test_assert( rv == 0 ); + + errno = 0; + rv = sem_getvalue( &sem, &val ); rtems_test_assert( rv == -1 ); rtems_test_assert( errno == EINVAL ); } @@ -155,10 +361,14 @@ void *POSIX_Init( sprintf(failure_msg, "sem_init %d", i ); fatal_posix_service_status( status, 0, failure_msg); } - puts( "Init: sem_init - UNSUCCESSFUL (ENOSPC)" ); + + puts( "Init: sem_init - SUCCESSFUL" ); status = sem_init(&sem2, 0, 1); - fatal_posix_service_status( status, -1, "sem_init error return status"); - fatal_posix_service_status( errno, ENOSPC, "sem_init errorno ENOSPC" ); + fatal_posix_service_status( status, 0, "sem_init"); + + puts( "Init: sem_destroy - SUCCESSFUL" ); + status = sem_destroy(&sem2); + fatal_posix_service_status( status, 0, "sem_destroy"); puts( "Init: sem_getvalue - SUCCESSFUL "); for (i = 0; i < MAX_SEMS; i++) { @@ -168,8 +378,7 @@ void *POSIX_Init( fatal_posix_service_status( value, i, "sem_getvalue correct value" ); } puts( "Init: sem_getvalue - UNSUCCESSFUL "); - sem2 = 0; - status = sem_getvalue(&sem2, &value); + status = sem_getvalue(SEM_FAILED, &value); fatal_posix_service_status( status, -1, "sem_getvalue error return status"); fatal_posix_service_status( errno, EINVAL, "sem_getvalue errno EINVAL"); @@ -178,7 +387,7 @@ void *POSIX_Init( fatal_posix_service_status( status, 0, "sem_destroy semaphore 0"); puts( "Init: sem_destroy - UNSUCCESSFUL (EINVAL)" ); - status = sem_destroy(&sem2); + status = sem_destroy(SEM_FAILED); fatal_posix_service_status( status, -1, "sem_destroy error return status"); fatal_posix_service_status( errno, EINVAL, "sem_destroy errno EINVAL"); @@ -188,7 +397,7 @@ void *POSIX_Init( /* sem[1].count = 0 */ puts( "Init: sem_wait - UNSUCCESSFUL (EINVAL)" ); - status = sem_wait(&sem2); + status = sem_wait(SEM_FAILED); fatal_posix_service_status( status, -1, "sem_wait error return status"); fatal_posix_service_status( errno, EINVAL, "sem_wait errno EINVAL"); @@ -214,7 +423,7 @@ void *POSIX_Init( /* sem[1].count = 0 */ puts( "Init: sem_trywait - UNSUCCESSFUL (EINVAL)" ); - status = sem_trywait(&sem2); + status = sem_trywait(SEM_FAILED); fatal_posix_service_status( status, -1, "sem_trywait error return status"); fatal_posix_service_status( errno, EINVAL, "sem_trywait errno EINVAL"); @@ -256,7 +465,7 @@ void *POSIX_Init( #endif puts( "Init: sem_post - UNSUCCESSFUL (EINVAL)" ); - status = sem_post(&sem2); + status = sem_post(SEM_FAILED); fatal_posix_service_status( status, -1, "sem_post error return status"); fatal_posix_service_status( errno, EINVAL, "sem_post errno EINVAL"); @@ -392,9 +601,13 @@ void *POSIX_Init( fatal_posix_service_status( errno, ENOENT, "sem_unlink errno ENOENT"); rtems_test_assert( (status == -1) && (errno == ENOENT) ); + test_named_sem_wait_during_delete(); test_sem_wait_during_delete(); test_sem_post_overflow(); test_sem_init_too_large_inital_value(); + test_sem_null(); + test_sem_not_initialized(); + test_sem_invalid_copy(); /* Try adding in unlinking before closing... (can we still open?) */ @@ -413,7 +626,7 @@ void *POSIX_Init( #define CONFIGURE_INITIAL_EXTENSIONS RTEMS_TEST_INITIAL_EXTENSION #define CONFIGURE_MAXIMUM_POSIX_THREADS 2 -#define CONFIGURE_MAXIMUM_POSIX_SEMAPHORES MAX_SEMS +#define CONFIGURE_MAXIMUM_POSIX_SEMAPHORES 2 #define CONFIGURE_POSIX_INIT_THREAD_TABLE #define CONFIGURE_POSIX_INIT_THREAD_STACK_SIZE \ diff --git a/testsuites/psxtmtests/psxtmsem02/init.c b/testsuites/psxtmtests/psxtmsem02/init.c index 4629ac5f4c..3c2f34a20b 100644 --- a/testsuites/psxtmtests/psxtmsem02/init.c +++ b/testsuites/psxtmtests/psxtmsem02/init.c @@ -159,7 +159,6 @@ void *POSIX_Init(void *argument) #define CONFIGURE_APPLICATION_NEEDS_TIMER_DRIVER #define CONFIGURE_MAXIMUM_POSIX_THREADS 1 -#define CONFIGURE_MAXIMUM_POSIX_SEMAPHORES 2 #define CONFIGURE_POSIX_INIT_THREAD_TABLE #define CONFIGURE_INIT diff --git a/testsuites/psxtmtests/psxtmsem03/init.c b/testsuites/psxtmtests/psxtmsem03/init.c index 585b88d6cd..687c8c6343 100644 --- a/testsuites/psxtmtests/psxtmsem03/init.c +++ b/testsuites/psxtmtests/psxtmsem03/init.c @@ -124,7 +124,6 @@ void *POSIX_Init( #define CONFIGURE_APPLICATION_NEEDS_TIMER_DRIVER #define CONFIGURE_MAXIMUM_POSIX_THREADS OPERATION_COUNT + 2 -#define CONFIGURE_MAXIMUM_POSIX_SEMAPHORES MAX_SEMS #define CONFIGURE_POSIX_INIT_THREAD_TABLE #define CONFIGURE_INIT diff --git a/testsuites/psxtmtests/psxtmsem04/init.c b/testsuites/psxtmtests/psxtmsem04/init.c index 5cebc9daa0..540f0a3b97 100644 --- a/testsuites/psxtmtests/psxtmsem04/init.c +++ b/testsuites/psxtmtests/psxtmsem04/init.c @@ -99,7 +99,6 @@ void *POSIX_Init(void *argument) #define CONFIGURE_APPLICATION_NEEDS_TIMER_DRIVER #define CONFIGURE_MAXIMUM_POSIX_THREADS 2 -#define CONFIGURE_MAXIMUM_POSIX_SEMAPHORES MAX_SEMS #define CONFIGURE_POSIX_INIT_THREAD_TABLE #define CONFIGURE_INIT diff --git a/testsuites/psxtmtests/psxtmsem05/init.c b/testsuites/psxtmtests/psxtmsem05/init.c index 12594c4e99..07b96b2024 100644 --- a/testsuites/psxtmtests/psxtmsem05/init.c +++ b/testsuites/psxtmtests/psxtmsem05/init.c @@ -159,7 +159,6 @@ void *POSIX_Init( #define CONFIGURE_APPLICATION_NEEDS_TIMER_DRIVER #define CONFIGURE_MAXIMUM_POSIX_THREADS OPERATION_COUNT + 2 -#define CONFIGURE_MAXIMUM_POSIX_SEMAPHORES MAX_SEMS #define CONFIGURE_POSIX_INIT_THREAD_TABLE #define CONFIGURE_INIT diff --git a/testsuites/sptests/spthreadq01/init.c b/testsuites/sptests/spthreadq01/init.c index 8f02e4d650..2b994e5d68 100644 --- a/testsuites/sptests/spthreadq01/init.c +++ b/testsuites/sptests/spthreadq01/init.c @@ -40,7 +40,6 @@ typedef struct { rtems_id mq; rtems_id br; #if defined(RTEMS_POSIX_API) - sem_t psem; pthread_mutex_t pmtx; pthread_cond_t pcv; pthread_rwlock_t prw; @@ -120,12 +119,6 @@ static void posix_worker(test_context *ctx) int eno; char buf[1]; - wake_up_master(ctx); - rtems_test_assert(get_wait_id(ctx) == ctx->psem); - - rv = sem_post(&ctx->psem); - rtems_test_assert(rv == 0); - eno = pthread_mutex_lock(&ctx->pmtx); rtems_test_assert(eno == 0); @@ -217,13 +210,9 @@ static void test_classic_init(test_context *ctx) static void test_posix_init(test_context *ctx) { #if defined(RTEMS_POSIX_API) - int rv; int eno; struct mq_attr attr; - rv = sem_init(&ctx->psem, 0, 0); - rtems_test_assert(rv == 0); - eno = pthread_mutex_init(&ctx->pmtx, NULL); rtems_test_assert(eno == 0); @@ -306,7 +295,6 @@ static void test_classic_obj(test_context *ctx) static void test_posix_obj(test_context *ctx) { #if defined(RTEMS_POSIX_API) - int rv; int eno; char buf[1]; unsigned prio; @@ -314,11 +302,6 @@ static void test_posix_obj(test_context *ctx) wait_for_worker(ctx); - rv = sem_wait(&ctx->psem); - rtems_test_assert(rv == 0); - - wait_for_worker(ctx); - eno = pthread_mutex_lock(&ctx->pmtx); rtems_test_assert(eno == 0); @@ -377,7 +360,6 @@ static rtems_task Init( #define CONFIGURE_MAXIMUM_BARRIERS 1 #if defined(RTEMS_POSIX_API) - #define CONFIGURE_MAXIMUM_POSIX_SEMAPHORES 1 #define CONFIGURE_MAXIMUM_POSIX_MUTEXES 1 #define CONFIGURE_MAXIMUM_POSIX_CONDITION_VARIABLES 1 #define CONFIGURE_MAXIMUM_POSIX_RWLOCKS 1 -- cgit v1.2.3