summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2016-04-18 06:23:27 +0200
committerSebastian Huber <sebastian.huber@embedded-brains.de>2016-04-21 07:29:38 +0200
commit90f1265e5dffe0f834ee9c55640a34fd90be8f12 (patch)
tree93be90c5b980b2be8d07eac95a9a50c539888cfa
parentscore: Close barrier object before flush (diff)
downloadrtems-90f1265e5dffe0f834ee9c55640a34fd90be8f12.tar.bz2
score: Fix _CORE_semaphore_Flush()
Use proper CORE_semaphore_Status for _CORE_semaphore_Flush() and _CORE_semaphore_Destroy() operations. Close #2696.
-rw-r--r--cpukit/posix/include/rtems/posix/semaphoreimpl.h1
-rw-r--r--cpukit/posix/src/semaphorecreatesupp.c12
-rw-r--r--cpukit/posix/src/semaphoredeletesupp.c2
-rw-r--r--cpukit/posix/src/semaphoretranslatereturncode.c2
-rw-r--r--cpukit/rtems/src/semdelete.c4
-rw-r--r--cpukit/rtems/src/semflush.c1
-rw-r--r--cpukit/score/include/rtems/score/coresemimpl.h24
-rw-r--r--testsuites/psxtests/psxsem01/init.c52
8 files changed, 76 insertions, 22 deletions
diff --git a/cpukit/posix/include/rtems/posix/semaphoreimpl.h b/cpukit/posix/include/rtems/posix/semaphoreimpl.h
index 8608e6f33d..41bfdad65a 100644
--- a/cpukit/posix/include/rtems/posix/semaphoreimpl.h
+++ b/cpukit/posix/include/rtems/posix/semaphoreimpl.h
@@ -58,7 +58,6 @@ RTEMS_INLINE_ROUTINE void _POSIX_Semaphore_Free (
POSIX_Semaphore_Control *the_semaphore
)
{
- _CORE_semaphore_Destroy( &the_semaphore->Semaphore );
_Objects_Free( &_POSIX_Semaphore_Information, &the_semaphore->Object );
}
diff --git a/cpukit/posix/src/semaphorecreatesupp.c b/cpukit/posix/src/semaphorecreatesupp.c
index 9a24e0a724..79db8888d8 100644
--- a/cpukit/posix/src/semaphorecreatesupp.c
+++ b/cpukit/posix/src/semaphorecreatesupp.c
@@ -54,11 +54,6 @@ int _POSIX_Semaphore_Create_support(
if (pshared != 0)
rtems_set_errno_and_return_minus_one( ENOSYS );
- the_semaphore = _POSIX_Semaphore_Allocate_unprotected();
- if ( !the_semaphore ) {
- rtems_set_errno_and_return_minus_one( ENOSPC );
- }
-
/*
* Make a copy of the user's string for name just in case it was
* dynamically constructed.
@@ -66,13 +61,18 @@ int _POSIX_Semaphore_Create_support(
if ( name_arg != NULL ) {
name = _Workspace_String_duplicate( name_arg, name_len );
if ( !name ) {
- _POSIX_Semaphore_Free( the_semaphore );
rtems_set_errno_and_return_minus_one( ENOMEM );
}
} else {
name = NULL;
}
+ the_semaphore = _POSIX_Semaphore_Allocate_unprotected();
+ if ( !the_semaphore ) {
+ _Workspace_Free( name );
+ rtems_set_errno_and_return_minus_one( ENOSPC );
+ }
+
the_semaphore->process_shared = pshared;
if ( name ) {
diff --git a/cpukit/posix/src/semaphoredeletesupp.c b/cpukit/posix/src/semaphoredeletesupp.c
index 650cdcdcdd..4394674699 100644
--- a/cpukit/posix/src/semaphoredeletesupp.c
+++ b/cpukit/posix/src/semaphoredeletesupp.c
@@ -36,7 +36,7 @@ void _POSIX_Semaphore_Delete(
{
if ( !the_semaphore->linked && !the_semaphore->open_count ) {
_Objects_Close( &_POSIX_Semaphore_Information, &the_semaphore->Object );
- _CORE_semaphore_Flush( &the_semaphore->Semaphore, -1, NULL, 0 );
+ _CORE_semaphore_Destroy( &the_semaphore->Semaphore, NULL, 0 );
_POSIX_Semaphore_Free( the_semaphore );
}
}
diff --git a/cpukit/posix/src/semaphoretranslatereturncode.c b/cpukit/posix/src/semaphoretranslatereturncode.c
index 37e7d0724b..d7b99eaf67 100644
--- a/cpukit/posix/src/semaphoretranslatereturncode.c
+++ b/cpukit/posix/src/semaphoretranslatereturncode.c
@@ -25,7 +25,7 @@
const int _POSIX_Semaphore_Return_codes[CORE_SEMAPHORE_STATUS_LAST + 1] = {
0, /* CORE_SEMAPHORE_STATUS_SUCCESSFUL */
EAGAIN, /* CORE_SEMAPHORE_STATUS_UNSATISFIED_NOWAIT */
- EAGAIN, /* CORE_SEMAPHORE_WAS_DELETED */
+ EINVAL, /* CORE_SEMAPHORE_WAS_DELETED */
ETIMEDOUT, /* CORE_SEMAPHORE_TIMEOUT */
/* The next error can not occur since we set the maximum
* count to the largest value the count can hold.
diff --git a/cpukit/rtems/src/semdelete.c b/cpukit/rtems/src/semdelete.c
index 6a83d25390..e3b8058df6 100644
--- a/cpukit/rtems/src/semdelete.c
+++ b/cpukit/rtems/src/semdelete.c
@@ -73,13 +73,11 @@ rtems_status_code rtems_semaphore_delete(
);
_CORE_mutex_Destroy( &the_semaphore->Core_control.mutex );
} else {
- _CORE_semaphore_Flush(
+ _CORE_semaphore_Destroy(
&the_semaphore->Core_control.semaphore,
- CORE_SEMAPHORE_WAS_DELETED,
_Semaphore_MP_Send_object_was_deleted,
id
);
- _CORE_semaphore_Destroy( &the_semaphore->Core_control.semaphore );
}
_Objects_Close( &_Semaphore_Information, &the_semaphore->Object );
diff --git a/cpukit/rtems/src/semflush.c b/cpukit/rtems/src/semflush.c
index ea06883379..64386b03c1 100644
--- a/cpukit/rtems/src/semflush.c
+++ b/cpukit/rtems/src/semflush.c
@@ -60,7 +60,6 @@ rtems_status_code rtems_semaphore_flush(
} else {
_CORE_semaphore_Flush(
&the_semaphore->Core_control.semaphore,
- CORE_SEMAPHORE_STATUS_UNSATISFIED_NOWAIT,
_Semaphore_MP_Send_object_was_deleted,
id
);
diff --git a/cpukit/score/include/rtems/score/coresemimpl.h b/cpukit/score/include/rtems/score/coresemimpl.h
index 79d907c6b4..e0e278843e 100644
--- a/cpukit/score/include/rtems/score/coresemimpl.h
+++ b/cpukit/score/include/rtems/score/coresemimpl.h
@@ -86,12 +86,21 @@ void _CORE_semaphore_Initialize(
uint32_t initial_value
);
-RTEMS_INLINE_ROUTINE void _CORE_semaphore_Destroy(
- CORE_semaphore_Control *the_semaphore
-)
-{
- _Thread_queue_Destroy( &the_semaphore->Wait_queue );
-}
+#define _CORE_semaphore_Destroy( \
+ the_semaphore, \
+ mp_callout, \
+ mp_id \
+) \
+ do { \
+ _Thread_queue_Flush( \
+ &( the_semaphore )->Wait_queue, \
+ ( the_semaphore )->operations, \
+ CORE_SEMAPHORE_WAS_DELETED, \
+ mp_callout, \
+ mp_id \
+ ); \
+ _Thread_queue_Destroy( &( the_semaphore )->Wait_queue ); \
+ } while ( 0 )
RTEMS_INLINE_ROUTINE CORE_semaphore_Status _CORE_semaphore_Do_surrender(
CORE_semaphore_Control *the_semaphore,
@@ -180,14 +189,13 @@ RTEMS_INLINE_ROUTINE CORE_semaphore_Status _CORE_semaphore_Do_surrender(
/* Must be a macro due to the multiprocessing dependent parameters */
#define _CORE_semaphore_Flush( \
the_semaphore, \
- status, \
mp_callout, \
mp_id \
) \
_Thread_queue_Flush( \
&( the_semaphore )->Wait_queue, \
( the_semaphore )->operations, \
- status, \
+ CORE_SEMAPHORE_STATUS_UNSATISFIED_NOWAIT, \
mp_callout, \
mp_id \
)
diff --git a/testsuites/psxtests/psxsem01/init.c b/testsuites/psxtests/psxsem01/init.c
index c1752f3a35..24f6d96465 100644
--- a/testsuites/psxtests/psxsem01/init.c
+++ b/testsuites/psxtests/psxsem01/init.c
@@ -27,6 +27,55 @@ void *POSIX_Init(void *argument);
#define MAX_SEMS 10
+static void *sem_wait_task(void *arg)
+{
+ sem_t *sem;
+ int rv;
+
+ sem = 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 );
+
+ return NULL;
+}
+
+static void test_sem_wait_during_delete(void)
+{
+ sem_t sem;
+ int rv;
+ pthread_t th;
+ int eno;
+ int val;
+
+ rv = sem_init( &sem, 0, 1 );
+ rtems_test_assert( rv == 0 );
+
+ 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_destroy( &sem );
+ rtems_test_assert( rv == 0 );
+
+ eno = pthread_join( th, NULL );
+ rtems_test_assert( eno == 0 );
+}
+
void *POSIX_Init(
void *argument
)
@@ -295,6 +344,7 @@ void *POSIX_Init(
fatal_posix_service_status( errno, ENOENT, "sem_unlink errno ENOENT");
rtems_test_assert( (status == -1) && (errno == ENOENT) );
+ test_sem_wait_during_delete();
/* Try adding in unlinking before closing... (can we still open?) */
@@ -312,7 +362,7 @@ void *POSIX_Init(
#define CONFIGURE_INITIAL_EXTENSIONS RTEMS_TEST_INITIAL_EXTENSION
-#define CONFIGURE_MAXIMUM_POSIX_THREADS 1
+#define CONFIGURE_MAXIMUM_POSIX_THREADS 2
#define CONFIGURE_MAXIMUM_POSIX_SEMAPHORES MAX_SEMS
#define CONFIGURE_POSIX_INIT_THREAD_TABLE