Fix semaphore post overflow status

Close #2720.
This commit is contained in:
Sebastian Huber
2016-05-25 14:23:48 +02:00
parent dbedcf93f0
commit 39bcf7417e
9 changed files with 86 additions and 11 deletions

View File

@@ -27,8 +27,5 @@ const int _POSIX_Semaphore_Return_codes[CORE_SEMAPHORE_STATUS_LAST + 1] = {
EAGAIN, /* CORE_SEMAPHORE_STATUS_UNSATISFIED_NOWAIT */ EAGAIN, /* CORE_SEMAPHORE_STATUS_UNSATISFIED_NOWAIT */
EINVAL, /* CORE_SEMAPHORE_WAS_DELETED */ EINVAL, /* CORE_SEMAPHORE_WAS_DELETED */
ETIMEDOUT, /* CORE_SEMAPHORE_TIMEOUT */ ETIMEDOUT, /* CORE_SEMAPHORE_TIMEOUT */
/* The next error can not occur since we set the maximum EOVERFLOW /* CORE_SEMAPHORE_MAXIMUM_COUNT_EXCEEDED */
* count to the largest value the count can hold.
*/
ENOSYS, /* CORE_SEMAPHORE_MAXIMUM_COUNT_EXCEEDED */
}; };

View File

@@ -19,6 +19,7 @@
#endif #endif
#include <semaphore.h> #include <semaphore.h>
#include <limits.h>
#include <rtems/posix/semaphoreimpl.h> #include <rtems/posix/semaphoreimpl.h>
@@ -28,6 +29,7 @@ int sem_post(
{ {
POSIX_Semaphore_Control *the_semaphore; POSIX_Semaphore_Control *the_semaphore;
Thread_queue_Context queue_context; Thread_queue_Context queue_context;
CORE_semaphore_Status status;
the_semaphore = _POSIX_Semaphore_Get( sem, &queue_context ); the_semaphore = _POSIX_Semaphore_Get( sem, &queue_context );
@@ -35,9 +37,17 @@ int sem_post(
rtems_set_errno_and_return_minus_one( EINVAL ); rtems_set_errno_and_return_minus_one( EINVAL );
} }
_CORE_semaphore_Surrender( status = _CORE_semaphore_Surrender(
&the_semaphore->Semaphore, &the_semaphore->Semaphore,
SEM_VALUE_MAX,
&queue_context &queue_context
); );
if ( status == CORE_SEMAPHORE_STATUS_SUCCESSFUL ) {
return 0; return 0;
}
rtems_set_errno_and_return_minus_one(
_POSIX_Semaphore_Translate_core_semaphore_return_code( status )
);
} }

View File

@@ -68,6 +68,7 @@ rtems_status_code rtems_semaphore_release( rtems_id id )
} else { } else {
semaphore_status = _CORE_semaphore_Surrender( semaphore_status = _CORE_semaphore_Surrender(
&the_semaphore->Core_control.semaphore, &the_semaphore->Core_control.semaphore,
UINT32_MAX,
&queue_context &queue_context
); );
return _Semaphore_Translate_core_semaphore_return_code( semaphore_status ); return _Semaphore_Translate_core_semaphore_return_code( semaphore_status );

View File

@@ -37,5 +37,5 @@ const rtems_status_code _Semaphore_Translate_core_semaphore_return_code_[] = {
RTEMS_UNSATISFIED, /* CORE_SEMAPHORE_STATUS_UNSATISFIED_NOWAIT */ RTEMS_UNSATISFIED, /* CORE_SEMAPHORE_STATUS_UNSATISFIED_NOWAIT */
RTEMS_OBJECT_WAS_DELETED, /* CORE_SEMAPHORE_WAS_DELETED */ RTEMS_OBJECT_WAS_DELETED, /* CORE_SEMAPHORE_WAS_DELETED */
RTEMS_TIMEOUT, /* CORE_SEMAPHORE_TIMEOUT */ RTEMS_TIMEOUT, /* CORE_SEMAPHORE_TIMEOUT */
RTEMS_INTERNAL_ERROR, /* CORE_SEMAPHORE_MAXIMUM_COUNT_EXCEEDED */ RTEMS_UNSATISFIED /* CORE_SEMAPHORE_MAXIMUM_COUNT_EXCEEDED */
}; };

View File

@@ -149,6 +149,7 @@ RTEMS_INLINE_ROUTINE void _CORE_semaphore_Destroy(
*/ */
RTEMS_INLINE_ROUTINE CORE_semaphore_Status _CORE_semaphore_Surrender( RTEMS_INLINE_ROUTINE CORE_semaphore_Status _CORE_semaphore_Surrender(
CORE_semaphore_Control *the_semaphore, CORE_semaphore_Control *the_semaphore,
uint32_t maximum_count,
Thread_queue_Context *queue_context Thread_queue_Context *queue_context
) )
{ {
@@ -171,7 +172,7 @@ RTEMS_INLINE_ROUTINE CORE_semaphore_Status _CORE_semaphore_Surrender(
queue_context queue_context
); );
} else { } else {
if ( the_semaphore->count < UINT32_MAX ) if ( the_semaphore->count < maximum_count )
the_semaphore->count += 1; the_semaphore->count += 1;
else else
status = CORE_SEMAPHORE_MAXIMUM_COUNT_EXCEEDED; status = CORE_SEMAPHORE_MAXIMUM_COUNT_EXCEEDED;

View File

@@ -374,7 +374,7 @@ void _MPCI_Announce ( void )
Thread_queue_Context queue_context; Thread_queue_Context queue_context;
_ISR_lock_ISR_disable( &queue_context.Lock_context ); _ISR_lock_ISR_disable( &queue_context.Lock_context );
(void) _CORE_semaphore_Surrender( &_MPCI_Semaphore, &queue_context ); (void) _CORE_semaphore_Surrender( &_MPCI_Semaphore, UINT32_MAX, &queue_context );
} }
void _MPCI_Internal_packets_Send_process_packet ( void _MPCI_Internal_packets_Send_process_packet (

View File

@@ -15,6 +15,7 @@
#include <semaphore.h> #include <semaphore.h>
#include <errno.h> #include <errno.h>
#include <fcntl.h> #include <fcntl.h>
#include <limits.h>
#include <time.h> #include <time.h>
#include <tmacros.h> #include <tmacros.h>
#include <pmacros.h> #include <pmacros.h>
@@ -76,6 +77,38 @@ static void test_sem_wait_during_delete(void)
rtems_test_assert( eno == 0 ); rtems_test_assert( eno == 0 );
} }
static void test_sem_post_overflow(void)
{
sem_t sem;
int rv;
int val;
rv = sem_init( &sem, 0, SEM_VALUE_MAX );
rtems_test_assert( rv == 0 );
rv = sem_getvalue( &sem, &val );
rtems_test_assert( rv == 0 );
rtems_test_assert( val == (int) SEM_VALUE_MAX );
errno = 0;
rv = sem_post( &sem );
rtems_test_assert( rv == -1 );
rtems_test_assert( errno == EOVERFLOW );
rv = sem_getvalue( &sem, &val );
rtems_test_assert( rv == 0 );
rtems_test_assert( val == (int) SEM_VALUE_MAX );
rv = sem_wait( &sem );
rtems_test_assert( rv == 0 );
rv = sem_post( &sem );
rtems_test_assert( rv == 0 );
rv = sem_destroy( &sem );
rtems_test_assert( rv == 0 );
}
void *POSIX_Init( void *POSIX_Init(
void *argument void *argument
) )
@@ -345,6 +378,7 @@ void *POSIX_Init(
rtems_test_assert( (status == -1) && (errno == ENOENT) ); rtems_test_assert( (status == -1) && (errno == ENOENT) );
test_sem_wait_during_delete(); test_sem_wait_during_delete();
test_sem_post_overflow();
/* Try adding in unlinking before closing... (can we still open?) */ /* Try adding in unlinking before closing... (can we still open?) */

View File

@@ -30,6 +30,35 @@ rtems_task Init(
Semaphore_name[ 2 ] = rtems_build_name( 'S', 'M', '2', ' ' ); Semaphore_name[ 2 ] = rtems_build_name( 'S', 'M', '2', ' ' );
Semaphore_name[ 3 ] = rtems_build_name( 'S', 'M', '3', ' ' ); Semaphore_name[ 3 ] = rtems_build_name( 'S', 'M', '3', ' ' );
/* release overflow */
status = rtems_semaphore_create(
Semaphore_name[ 1 ],
UINT32_MAX,
RTEMS_COUNTING_SEMAPHORE,
0,
&Semaphore_id[ 1 ]
);
fatal_directive_status(
status,
RTEMS_SUCCESSFUL,
"rtems_semaphore_create"
);
puts( "TA1 - rtems_semaphore_create - RTEMS_SUCCESSFUL" );
status = rtems_semaphore_release( Semaphore_id[ 1 ] );
fatal_directive_status(
status,
RTEMS_UNSATISFIED,
"rtems_semaphore_release"
);
puts( "TA1 - rtems_semaphore_release - RTEMS_UNSATISFIED" );
status = rtems_semaphore_delete( Semaphore_id[ 1 ] );
fatal_directive_status(
status,
RTEMS_SUCCESSFUL,
"rtems_semaphore_delete"
);
puts( "TA1 - rtems_semaphore_delete - RTEMS_SUCCESSFUL" );
/* invalid name */ /* invalid name */
status = rtems_semaphore_create( status = rtems_semaphore_create(
0, 0,

View File

@@ -1,4 +1,7 @@
*** TEST SEMAPHORE ERROR 01 *** *** BEGIN OF TEST SP SEMAPHORE ERROR 01 ***
TA1 - rtems_semaphore_create - RTEMS_SUCCESSFUL
TA1 - rtems_semaphore_release - RTEMS_UNSATISFIED
TA1 - rtems_semaphore_delete - RTEMS_SUCCESSFUL
TA1 - rtems_semaphore_create - RTEMS_INVALID_NAME TA1 - rtems_semaphore_create - RTEMS_INVALID_NAME
TA1 - rtems_semaphore_create - RTEMS_INVALID_ADDRESS TA1 - rtems_semaphore_create - RTEMS_INVALID_ADDRESS
TA1 - rtems_semaphore_create - 1 - RTEMS_SUCCESSFUL TA1 - rtems_semaphore_create - 1 - RTEMS_SUCCESSFUL
@@ -16,4 +19,4 @@ TA1 - rtems_semaphore_ident - global RTEMS_INVALID_NAME
TA1 - rtems_semaphore_ident - local RTEMS_INVALID_NAME TA1 - rtems_semaphore_ident - local RTEMS_INVALID_NAME
TA1 - rtems_semaphore_release - RTEMS_INVALID_ID TA1 - rtems_semaphore_release - RTEMS_INVALID_ID
TA1 - rtems_semaphore_flush - RTEMS_INVALID_ID TA1 - rtems_semaphore_flush - RTEMS_INVALID_ID
*** END TEST SEMAPHORE ERROR 01 *** *** END OF TEST SP SEMAPHORE ERROR 01 ***