score: Add semaphore variants

This commit is contained in:
Sebastian Huber
2016-05-30 16:16:21 +02:00
parent 3ca6e61851
commit 2581a563f9
16 changed files with 227 additions and 182 deletions
@@ -34,6 +34,8 @@ extern "C" {
*/
extern Objects_Information _POSIX_Semaphore_Information;
#define POSIX_SEMAPHORE_TQ_OPERATIONS &_Thread_queue_Operations_FIFO
RTEMS_INLINE_ROUTINE POSIX_Semaphore_Control *
_POSIX_Semaphore_Allocate_unprotected( void )
{
+1 -5
View File
@@ -92,11 +92,7 @@ int _POSIX_Semaphore_Create_support(
* thing is certain, no matter what we decide, it won't be
* the same as all other POSIX implementations. :)
*/
_CORE_semaphore_Initialize(
&the_semaphore->Semaphore,
CORE_SEMAPHORE_DISCIPLINES_FIFO,
value
);
_CORE_semaphore_Initialize( &the_semaphore->Semaphore, value );
/*
* Make the semaphore available for use.
+5 -1
View File
@@ -27,7 +27,11 @@ void _POSIX_Semaphore_Delete(
{
if ( !the_semaphore->linked && !the_semaphore->open_count ) {
_Objects_Close( &_POSIX_Semaphore_Information, &the_semaphore->Object );
_CORE_semaphore_Destroy( &the_semaphore->Semaphore, queue_context );
_CORE_semaphore_Destroy(
&the_semaphore->Semaphore,
POSIX_SEMAPHORE_TQ_OPERATIONS,
queue_context
);
_POSIX_Semaphore_Free( the_semaphore );
} else {
_CORE_semaphore_Release( &the_semaphore->Semaphore, queue_context );
+1
View File
@@ -43,6 +43,7 @@ int _POSIX_Semaphore_Wait_support(
status = _CORE_semaphore_Seize(
&the_semaphore->Semaphore,
POSIX_SEMAPHORE_TQ_OPERATIONS,
_Thread_Executing,
blocking,
timeout,
+1
View File
@@ -40,6 +40,7 @@ int sem_post(
status = _CORE_semaphore_Surrender(
&the_semaphore->Semaphore,
POSIX_SEMAPHORE_TQ_OPERATIONS,
SEM_VALUE_MAX,
&queue_context
);
+18
View File
@@ -96,6 +96,24 @@ typedef struct {
#endif
} Core_control;
/**
* @brief The semaphore variant.
*
* @see Semaphore_Variant.
*/
unsigned int variant : 3;
/**
* @brief The semaphore thread queue discipline.
*
* @see Semaphore_Discipline.
*/
unsigned int discipline : 1;
#if defined(RTEMS_MULTIPROCESSING)
unsigned int is_global : 1;
#endif
/**
* This is the Classic API attribute provided to the create directive.
* It is translated into behavioral attributes on the SuperCore Semaphore
@@ -26,12 +26,37 @@
extern "C" {
#endif
typedef enum {
SEMAPHORE_VARIANT_MUTEX,
SEMAPHORE_VARIANT_COUNTING
#if defined(RTEMS_SMP)
,
SEMAPHORE_VARIANT_MRSP
#endif
} Semaphore_Variant;
typedef enum {
SEMAPHORE_DISCIPLINE_PRIORITY,
SEMAPHORE_DISCIPLINE_FIFO
} Semaphore_Discipline;
/**
* The following defines the information control block used to manage
* this class of objects.
*/
extern Objects_Information _Semaphore_Information;
RTEMS_INLINE_ROUTINE const Thread_queue_Operations *_Semaphore_Get_operations(
const Semaphore_Control *the_semaphore
)
{
if ( the_semaphore->discipline == SEMAPHORE_DISCIPLINE_PRIORITY ) {
return &_Thread_queue_Operations_priority;
} else {
return &_Thread_queue_Operations_FIFO;
}
}
/**
* @brief Allocates a semaphore control block from
* the inactive chain of free semaphore control blocks.
+15 -16
View File
@@ -61,10 +61,9 @@ rtems_status_code rtems_semaphore_create(
rtems_id *id
)
{
Semaphore_Control *the_semaphore;
CORE_mutex_Attributes the_mutex_attr;
CORE_semaphore_Disciplines semaphore_discipline;
Status_Control status;
Semaphore_Control *the_semaphore;
CORE_mutex_Attributes the_mutex_attr;
Status_Control status;
if ( !rtems_is_name_valid( name ) )
return RTEMS_INVALID_NAME;
@@ -125,6 +124,8 @@ rtems_status_code rtems_semaphore_create(
}
#if defined(RTEMS_MULTIPROCESSING)
the_semaphore->is_global = _Attributes_Is_global( attribute_set );
if ( _Attributes_Is_global( attribute_set ) &&
! ( _Objects_MP_Allocate_and_open( &_Semaphore_Information, name,
the_semaphore->Object.id, false ) ) ) {
@@ -136,29 +137,25 @@ rtems_status_code rtems_semaphore_create(
the_semaphore->attribute_set = attribute_set;
if ( _Attributes_Is_priority( attribute_set ) ) {
the_semaphore->discipline = SEMAPHORE_DISCIPLINE_PRIORITY;
} else {
the_semaphore->discipline = SEMAPHORE_DISCIPLINE_FIFO;
}
/*
* Initialize it as a counting semaphore.
*/
if ( _Attributes_Is_counting_semaphore( attribute_set ) ) {
if ( _Attributes_Is_priority( attribute_set ) )
semaphore_discipline = CORE_SEMAPHORE_DISCIPLINES_PRIORITY;
else
semaphore_discipline = CORE_SEMAPHORE_DISCIPLINES_FIFO;
/*
* The following are just to make Purify happy.
*/
the_mutex_attr.lock_nesting_behavior = CORE_MUTEX_NESTING_ACQUIRES;
the_mutex_attr.priority_ceiling = PRIORITY_MINIMUM;
the_semaphore->variant = SEMAPHORE_VARIANT_COUNTING;
_CORE_semaphore_Initialize(
&the_semaphore->Core_control.semaphore,
semaphore_discipline,
count
);
status = STATUS_SUCCESSFUL;
#if defined(RTEMS_SMP)
} else if ( _Attributes_Is_multiprocessor_resource_sharing( attribute_set ) ) {
the_semaphore->variant = SEMAPHORE_VARIANT_MRSP;
status = _MRSP_Initialize(
&the_semaphore->Core_control.mrsp,
priority_ceiling,
@@ -167,6 +164,8 @@ rtems_status_code rtems_semaphore_create(
);
#endif
} else {
the_semaphore->variant = SEMAPHORE_VARIANT_MUTEX;
/*
* It is either simple binary semaphore or a more powerful mutex
* style binary semaphore. This is the mutex style.
+39 -29
View File
@@ -53,22 +53,27 @@ rtems_status_code rtems_semaphore_delete(
&queue_context.Lock_context
);
switch ( the_semaphore->variant ) {
case SEMAPHORE_VARIANT_MUTEX:
if (
_CORE_mutex_Is_locked( &the_semaphore->Core_control.mutex )
&& !_Attributes_Is_simple_binary_semaphore( attribute_set )
) {
status = STATUS_RESOURCE_IN_USE;
} else {
status = STATUS_SUCCESSFUL;
}
break;
#if defined(RTEMS_SMP)
if ( _Attributes_Is_multiprocessor_resource_sharing( attribute_set ) ) {
status = _MRSP_Can_destroy( &the_semaphore->Core_control.mrsp );
} else
case SEMAPHORE_VARIANT_MRSP:
status = _MRSP_Can_destroy( &the_semaphore->Core_control.mrsp );
break;
#endif
if ( !_Attributes_Is_counting_semaphore( attribute_set ) ) {
if (
_CORE_mutex_Is_locked( &the_semaphore->Core_control.mutex )
&& !_Attributes_Is_simple_binary_semaphore( attribute_set )
) {
status = STATUS_RESOURCE_IN_USE;
} else {
default:
_Assert( the_semaphore->variant == SEMAPHORE_VARIANT_COUNTING );
status = STATUS_SUCCESSFUL;
}
} else {
status = STATUS_SUCCESSFUL;
break;
}
if ( status != STATUS_SUCCESSFUL ) {
@@ -82,27 +87,32 @@ rtems_status_code rtems_semaphore_delete(
_Objects_Close( &_Semaphore_Information, &the_semaphore->Object );
switch ( the_semaphore->variant ) {
case SEMAPHORE_VARIANT_MUTEX:
_CORE_mutex_Flush(
&the_semaphore->Core_control.mutex,
_Thread_queue_Flush_status_object_was_deleted,
&queue_context
);
_CORE_mutex_Destroy( &the_semaphore->Core_control.mutex );
break;
#if defined(RTEMS_SMP)
if ( _Attributes_Is_multiprocessor_resource_sharing( attribute_set ) ) {
_MRSP_Destroy( &the_semaphore->Core_control.mrsp, &queue_context );
} else
case SEMAPHORE_VARIANT_MRSP:
_MRSP_Destroy( &the_semaphore->Core_control.mrsp, &queue_context );
break;
#endif
if ( !_Attributes_Is_counting_semaphore( attribute_set ) ) {
_CORE_mutex_Flush(
&the_semaphore->Core_control.mutex,
_Thread_queue_Flush_status_object_was_deleted,
&queue_context
);
_CORE_mutex_Destroy( &the_semaphore->Core_control.mutex );
} else {
_CORE_semaphore_Destroy(
&the_semaphore->Core_control.semaphore,
&queue_context
);
default:
_Assert( the_semaphore->variant == SEMAPHORE_VARIANT_COUNTING );
_CORE_semaphore_Destroy(
&the_semaphore->Core_control.semaphore,
_Semaphore_Get_operations( the_semaphore ),
&queue_context
);
break;
}
#if defined(RTEMS_MULTIPROCESSING)
if ( _Attributes_Is_global( attribute_set ) ) {
if ( the_semaphore->is_global ) {
_Objects_MP_Close( &_Semaphore_Information, id );
+27 -27
View File
@@ -19,13 +19,11 @@
#endif
#include <rtems/rtems/semimpl.h>
#include <rtems/rtems/attrimpl.h>
rtems_status_code rtems_semaphore_flush( rtems_id id )
{
Semaphore_Control *the_semaphore;
Thread_queue_Context queue_context;
rtems_attribute attribute_set;
the_semaphore = _Semaphore_Get( id, &queue_context );
@@ -39,38 +37,40 @@ rtems_status_code rtems_semaphore_flush( rtems_id id )
return RTEMS_INVALID_ID;
}
attribute_set = the_semaphore->attribute_set;
_Thread_queue_Acquire_critical(
&the_semaphore->Core_control.Wait_queue,
&queue_context.Lock_context
);
_Thread_queue_Context_set_MP_callout(
&queue_context,
_Semaphore_MP_Send_object_was_deleted
);
switch ( the_semaphore->variant ) {
#if defined(RTEMS_SMP)
if ( _Attributes_Is_multiprocessor_resource_sharing( attribute_set ) ) {
_ISR_lock_ISR_enable( &queue_context.Lock_context );
return RTEMS_NOT_DEFINED;
} else
case SEMAPHORE_VARIANT_MRSP:
_Thread_queue_Release(
&the_semaphore->Core_control.Wait_queue,
&queue_context.Lock_context
);
return RTEMS_NOT_DEFINED;
#endif
if ( !_Attributes_Is_counting_semaphore( attribute_set ) ) {
_CORE_mutex_Acquire_critical(
&the_semaphore->Core_control.mutex,
&queue_context
);
_CORE_mutex_Flush(
&the_semaphore->Core_control.mutex,
_Thread_queue_Flush_status_unavailable,
&queue_context
);
} else {
_CORE_semaphore_Acquire_critical(
&the_semaphore->Core_control.semaphore,
&queue_context
);
_CORE_semaphore_Flush(
&the_semaphore->Core_control.semaphore,
&queue_context
);
case SEMAPHORE_VARIANT_MUTEX:
_CORE_mutex_Flush(
&the_semaphore->Core_control.mutex,
_Thread_queue_Flush_status_unavailable,
&queue_context
);
break;
default:
_Assert( the_semaphore->variant == SEMAPHORE_VARIANT_COUNTING );
_CORE_semaphore_Flush(
&the_semaphore->Core_control.semaphore,
_Semaphore_Get_operations( the_semaphore ),
&queue_context
);
break;
}
return RTEMS_SUCCESSFUL;
}
+31 -29
View File
@@ -19,7 +19,6 @@
#endif
#include <rtems/rtems/semimpl.h>
#include <rtems/rtems/attrimpl.h>
#include <rtems/rtems/optionsimpl.h>
#include <rtems/rtems/statusimpl.h>
@@ -54,7 +53,6 @@ rtems_status_code rtems_semaphore_obtain(
Semaphore_Control *the_semaphore;
Thread_queue_Context queue_context;
Thread_Control *executing;
rtems_attribute attribute_set;
bool wait;
Status_Control status;
@@ -69,36 +67,40 @@ rtems_status_code rtems_semaphore_obtain(
}
executing = _Thread_Executing;
attribute_set = the_semaphore->attribute_set;
wait = !_Options_Is_no_wait( option_set );
switch ( the_semaphore->variant ) {
#if defined(RTEMS_SMP)
if ( _Attributes_Is_multiprocessor_resource_sharing( attribute_set ) ) {
status = _MRSP_Seize(
&the_semaphore->Core_control.mrsp,
executing,
wait,
timeout,
&queue_context
);
} else
case SEMAPHORE_VARIANT_MRSP:
status = _MRSP_Seize(
&the_semaphore->Core_control.mrsp,
executing,
wait,
timeout,
&queue_context
);
break;
#endif
if ( !_Attributes_Is_counting_semaphore( attribute_set ) ) {
status = _CORE_mutex_Seize(
&the_semaphore->Core_control.mutex,
executing,
wait,
timeout,
&queue_context
);
} else {
/* must be a counting semaphore */
status = _CORE_semaphore_Seize(
&the_semaphore->Core_control.semaphore,
executing,
wait,
timeout,
&queue_context
);
case SEMAPHORE_VARIANT_MUTEX:
status = _CORE_mutex_Seize(
&the_semaphore->Core_control.mutex,
executing,
wait,
timeout,
&queue_context
);
break;
default:
_Assert( the_semaphore->variant == SEMAPHORE_VARIANT_COUNTING );
status = _CORE_semaphore_Seize(
&the_semaphore->Core_control.semaphore,
_Semaphore_Get_operations( the_semaphore ),
executing,
wait,
timeout,
&queue_context
);
break;
}
return _Status_Get( status );
+23 -21
View File
@@ -22,14 +22,12 @@
#endif
#include <rtems/rtems/semimpl.h>
#include <rtems/rtems/attrimpl.h>
#include <rtems/rtems/statusimpl.h>
rtems_status_code rtems_semaphore_release( rtems_id id )
{
Semaphore_Control *the_semaphore;
Thread_queue_Context queue_context;
rtems_attribute attribute_set;
Status_Control status;
the_semaphore = _Semaphore_Get( id, &queue_context );
@@ -47,27 +45,31 @@ rtems_status_code rtems_semaphore_release( rtems_id id )
_Semaphore_Core_mutex_mp_support
);
attribute_set = the_semaphore->attribute_set;
switch ( the_semaphore->variant ) {
#if defined(RTEMS_SMP)
if ( _Attributes_Is_multiprocessor_resource_sharing( attribute_set ) ) {
status = _MRSP_Surrender(
&the_semaphore->Core_control.mrsp,
_Thread_Executing,
&queue_context
);
} else
case SEMAPHORE_VARIANT_MRSP:
status = _MRSP_Surrender(
&the_semaphore->Core_control.mrsp,
_Thread_Executing,
&queue_context
);
break;
#endif
if ( !_Attributes_Is_counting_semaphore( attribute_set ) ) {
status = _CORE_mutex_Surrender(
&the_semaphore->Core_control.mutex,
&queue_context
);
} else {
status = _CORE_semaphore_Surrender(
&the_semaphore->Core_control.semaphore,
UINT32_MAX,
&queue_context
);
case SEMAPHORE_VARIANT_MUTEX:
status = _CORE_mutex_Surrender(
&the_semaphore->Core_control.mutex,
&queue_context
);
break;
default:
_Assert( the_semaphore->variant == SEMAPHORE_VARIANT_COUNTING );
status = _CORE_semaphore_Surrender(
&the_semaphore->Core_control.semaphore,
_Semaphore_Get_operations( the_semaphore ),
UINT32_MAX,
&queue_context
);
break;
}
return _Status_Get( status );
@@ -37,18 +37,6 @@ extern "C" {
*/
/**@{*/
/**
* Blocking disciplines for a semaphore.
*/
typedef enum {
/** This specifies that threads will wait for the semaphore in FIFO order. */
CORE_SEMAPHORE_DISCIPLINES_FIFO,
/** This specifies that threads will wait for the semaphore in
* priority order.
*/
CORE_SEMAPHORE_DISCIPLINES_PRIORITY
} CORE_semaphore_Disciplines;
/**
* The following defines the control block used to manage each
* counting semaphore.
@@ -59,11 +47,6 @@ typedef struct {
*/
Thread_queue_Control Wait_queue;
/**
* @brief The thread queue operations according to the blocking discipline.
*/
const Thread_queue_Operations *operations;
/** This element contains the current count of this semaphore. */
uint32_t count;
} CORE_semaphore_Control;
+28 -26
View File
@@ -46,13 +46,11 @@ extern "C" {
* This routine initializes the semaphore based on the parameters passed.
*
* @param[in] the_semaphore is the semaphore to initialize
* @param[in] discipline the blocking discipline
* @param[in] initial_value is the initial count of the semaphore
*/
void _CORE_semaphore_Initialize(
CORE_semaphore_Control *the_semaphore,
CORE_semaphore_Disciplines discipline,
uint32_t initial_value
CORE_semaphore_Control *the_semaphore,
uint32_t initial_value
);
RTEMS_INLINE_ROUTINE void _CORE_semaphore_Acquire_critical(
@@ -78,13 +76,14 @@ RTEMS_INLINE_ROUTINE void _CORE_semaphore_Release(
}
RTEMS_INLINE_ROUTINE void _CORE_semaphore_Destroy(
CORE_semaphore_Control *the_semaphore,
Thread_queue_Context *queue_context
CORE_semaphore_Control *the_semaphore,
const Thread_queue_Operations *operations,
Thread_queue_Context *queue_context
)
{
_Thread_queue_Flush_critical(
&the_semaphore->Wait_queue.Queue,
the_semaphore->operations,
operations,
_Thread_queue_Flush_status_object_was_deleted,
queue_context
);
@@ -99,15 +98,17 @@ RTEMS_INLINE_ROUTINE void _CORE_semaphore_Destroy(
* given to that task. Otherwise, the unit will be returned to the semaphore.
*
* @param[in] the_semaphore is the semaphore to surrender
* @param[in] operations The thread queue operations.
* @param[in] queue_context is a temporary variable used to contain the ISR
* disable level cookie
*
* @retval an indication of whether the routine succeeded or failed
*/
RTEMS_INLINE_ROUTINE Status_Control _CORE_semaphore_Surrender(
CORE_semaphore_Control *the_semaphore,
uint32_t maximum_count,
Thread_queue_Context *queue_context
CORE_semaphore_Control *the_semaphore,
const Thread_queue_Operations *operations,
uint32_t maximum_count,
Thread_queue_Context *queue_context
)
{
Thread_Control *the_thread;
@@ -119,12 +120,12 @@ RTEMS_INLINE_ROUTINE Status_Control _CORE_semaphore_Surrender(
the_thread = _Thread_queue_First_locked(
&the_semaphore->Wait_queue,
the_semaphore->operations
operations
);
if ( the_thread != NULL ) {
_Thread_queue_Extract_critical(
&the_semaphore->Wait_queue.Queue,
the_semaphore->operations,
operations,
the_thread,
queue_context
);
@@ -141,13 +142,14 @@ RTEMS_INLINE_ROUTINE Status_Control _CORE_semaphore_Surrender(
}
RTEMS_INLINE_ROUTINE void _CORE_semaphore_Flush(
CORE_semaphore_Control *the_semaphore,
Thread_queue_Context *queue_context
CORE_semaphore_Control *the_semaphore,
const Thread_queue_Operations *operations,
Thread_queue_Context *queue_context
)
{
_Thread_queue_Flush_critical(
&the_semaphore->Wait_queue.Queue,
the_semaphore->operations,
operations,
_Thread_queue_Flush_status_unavailable,
queue_context
);
@@ -161,7 +163,7 @@ RTEMS_INLINE_ROUTINE void _CORE_semaphore_Flush(
* @return the current count of this semaphore
*/
RTEMS_INLINE_ROUTINE uint32_t _CORE_semaphore_Get_count(
CORE_semaphore_Control *the_semaphore
const CORE_semaphore_Control *the_semaphore
)
{
return the_semaphore->count;
@@ -174,23 +176,23 @@ RTEMS_INLINE_ROUTINE uint32_t _CORE_semaphore_Get_count(
* available.
*
* @param[in] the_semaphore is the semaphore to obtain
* @param[in,out] executing The currently executing thread.
* @param[in] operations The thread queue operations.
* @param[in] executing The currently executing thread.
* @param[in] wait is true if the thread is willing to wait
* @param[in] timeout is the maximum number of ticks to block
* @param[in] queue_context is a temporary variable used to contain the ISR
* disable level cookie
*
* @note There is currently no MACRO version of this routine.
*/
RTEMS_INLINE_ROUTINE Status_Control _CORE_semaphore_Seize(
CORE_semaphore_Control *the_semaphore,
Thread_Control *executing,
bool wait,
Watchdog_Interval timeout,
Thread_queue_Context *queue_context
CORE_semaphore_Control *the_semaphore,
const Thread_queue_Operations *operations,
Thread_Control *executing,
bool wait,
Watchdog_Interval timeout,
Thread_queue_Context *queue_context
)
{
/* disabled when you get here */
_Assert( _ISR_Get_level() != 0 );
_CORE_semaphore_Acquire_critical( the_semaphore, queue_context );
if ( the_semaphore->count != 0 ) {
@@ -207,7 +209,7 @@ RTEMS_INLINE_ROUTINE Status_Control _CORE_semaphore_Seize(
_Thread_queue_Context_set_expected_level( queue_context, 1 );
_Thread_queue_Enqueue_critical(
&the_semaphore->Wait_queue.Queue,
the_semaphore->operations,
operations,
executing,
STATES_WAITING_FOR_SEMAPHORE,
timeout,
+2 -9
View File
@@ -21,18 +21,11 @@
#include <rtems/score/coresemimpl.h>
void _CORE_semaphore_Initialize(
CORE_semaphore_Control *the_semaphore,
CORE_semaphore_Disciplines discipline,
uint32_t initial_value
CORE_semaphore_Control *the_semaphore,
uint32_t initial_value
)
{
the_semaphore->count = initial_value;
_Thread_queue_Initialize( &the_semaphore->Wait_queue );
if ( discipline == CORE_SEMAPHORE_DISCIPLINES_PRIORITY ) {
the_semaphore->operations = &_Thread_queue_Operations_priority;
} else {
the_semaphore->operations = &_Thread_queue_Operations_FIFO;
}
}
+9 -2
View File
@@ -35,6 +35,8 @@ RTEMS_STATIC_ASSERT(
MPCI_Internal_packet
);
#define MPCI_SEMAPHORE_TQ_OPERATIONS &_Thread_queue_Operations_FIFO
bool _System_state_Is_multiprocessing;
rtems_multiprocessing_table *_Configuration_MP_table;
@@ -119,7 +121,6 @@ static void _MPCI_Handler_initialization( void )
_CORE_semaphore_Initialize(
&_MPCI_Semaphore,
CORE_SEMAPHORE_DISCIPLINES_FIFO,
0 /* initial_value */
);
}
@@ -335,6 +336,7 @@ void _MPCI_Receive_server(
_ISR_lock_ISR_disable( &queue_context.Lock_context );
_CORE_semaphore_Seize(
&_MPCI_Semaphore,
MPCI_SEMAPHORE_TQ_OPERATIONS,
executing,
true,
WATCHDOG_NO_TIMEOUT,
@@ -373,7 +375,12 @@ void _MPCI_Announce ( void )
Thread_queue_Context queue_context;
_ISR_lock_ISR_disable( &queue_context.Lock_context );
(void) _CORE_semaphore_Surrender( &_MPCI_Semaphore, UINT32_MAX, &queue_context );
(void) _CORE_semaphore_Surrender(
&_MPCI_Semaphore,
MPCI_SEMAPHORE_TQ_OPERATIONS,
UINT32_MAX,
&queue_context
);
}
void _MPCI_Internal_packets_Send_process_packet (