mirror of
https://gitlab.rtems.org/rtems/rtos/rtems.git
synced 2026-09-23 16:02:05 +08:00
score: Add CORE mutex variants
Add CORE_recursive_mutex_Control and CORE_ceiling_mutex_Control to avoid the run-time evaluation of attributes to figure out how a particular mutex methods should behave. Start with the no protocol variants. This eliminates the CORE_MUTEX_DISCIPLINES_FIFO and CORE_MUTEX_DISCIPLINES_PRIORITY disciplines.
This commit is contained in:
@@ -22,7 +22,7 @@ rtems_monitor_sema_canonical(
|
||||
|
||||
canonical_sema->attribute = rtems_sema->attribute_set;
|
||||
canonical_sema->priority_ceiling =
|
||||
rtems_sema->Core_control.mutex.Attributes.priority_ceiling;
|
||||
rtems_sema->Core_control.Mutex.priority_ceiling;
|
||||
|
||||
canonical_sema->holder_id = 0;
|
||||
|
||||
@@ -33,8 +33,9 @@ rtems_monitor_sema_canonical(
|
||||
}
|
||||
else {
|
||||
/* we have a binary semaphore (mutex) */
|
||||
Thread_Control *holder = rtems_sema->Core_control.mutex.holder;
|
||||
Thread_Control *holder;
|
||||
|
||||
holder = rtems_sema->Core_control.Mutex.Recursive.Mutex.holder;
|
||||
if (holder != NULL) {
|
||||
canonical_sema->holder_id = holder->Object.id;
|
||||
canonical_sema->cur_count = 0;
|
||||
|
||||
@@ -118,7 +118,7 @@ rtems_bsdnet_semaphore_release_recursive(void)
|
||||
|
||||
nest_count =
|
||||
the_networkSemaphore ?
|
||||
the_networkSemaphore->Core_control.mutex.nest_count : 0;
|
||||
the_networkSemaphore->Core_control.Mutex.Recursive.Mutex.nest_count : 0;
|
||||
for (i = 0; i < nest_count; ++i) {
|
||||
rtems_bsdnet_semaphore_release();
|
||||
}
|
||||
@@ -378,7 +378,7 @@ rtems_bsdnet_semaphore_obtain (void)
|
||||
_Thread_queue_Context_initialize(&queue_context);
|
||||
_ISR_lock_ISR_disable(&queue_context.Lock_context);
|
||||
status = _CORE_mutex_Seize (
|
||||
&the_networkSemaphore->Core_control.mutex,
|
||||
&the_networkSemaphore->Core_control.Mutex.Recursive.Mutex,
|
||||
_Thread_Executing,
|
||||
1, /* wait */
|
||||
0, /* forever */
|
||||
@@ -411,7 +411,7 @@ rtems_bsdnet_semaphore_release (void)
|
||||
_Thread_queue_Context_initialize(&queue_context);
|
||||
_ISR_lock_ISR_disable(&queue_context.Lock_context);
|
||||
status = _CORE_mutex_Surrender (
|
||||
&the_networkSemaphore->Core_control.mutex,
|
||||
&the_networkSemaphore->Core_control.Mutex.Recursive.Mutex,
|
||||
&queue_context
|
||||
);
|
||||
if (status != STATUS_SUCCESSFUL)
|
||||
|
||||
@@ -35,14 +35,35 @@ extern "C" {
|
||||
*/
|
||||
/**@{**/
|
||||
|
||||
/*
|
||||
* Data Structure used to manage a POSIX mutex
|
||||
/**
|
||||
* @brief The POSIX mutex control.
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
Objects_Control Object;
|
||||
CORE_mutex_Control Mutex;
|
||||
} POSIX_Mutex_Control;
|
||||
/**
|
||||
* @brief The object control.
|
||||
*/
|
||||
Objects_Control Object;
|
||||
|
||||
/**
|
||||
* The most general mutex variant supported by a POSIX mutex.
|
||||
*
|
||||
* The priority inheritance or no protocol variants will use only parts of
|
||||
* this structure.
|
||||
*/
|
||||
CORE_ceiling_mutex_Control Mutex;
|
||||
|
||||
/**
|
||||
* @brief The protocol variant.
|
||||
*
|
||||
* @see POSIX_Mutex_Protocol.
|
||||
*/
|
||||
unsigned int protocol : 2;
|
||||
|
||||
/**
|
||||
* @brief Indicates if this is a non-recursive or recursive mutex.
|
||||
*/
|
||||
unsigned int is_recursive : 1;
|
||||
} POSIX_Mutex_Control;
|
||||
|
||||
/** @} */
|
||||
|
||||
|
||||
@@ -28,6 +28,19 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define POSIX_MUTEX_NO_PROTOCOL_TQ_OPERATIONS &_Thread_queue_Operations_FIFO
|
||||
|
||||
/**
|
||||
* @brief Supported POSIX mutex protocols.
|
||||
*
|
||||
* Must be in synchronization with POSIX_Mutex_Control::protocol.
|
||||
*/
|
||||
typedef enum {
|
||||
POSIX_MUTEX_NO_PROTOCOL,
|
||||
POSIX_MUTEX_PRIORITY_INHERIT,
|
||||
POSIX_MUTEX_PRIORITY_CEILING
|
||||
} POSIX_Mutex_Protocol;
|
||||
|
||||
/**
|
||||
* The following defines the information control block used to manage
|
||||
* this class of objects.
|
||||
@@ -39,6 +52,28 @@ extern Objects_Information _POSIX_Mutex_Information;
|
||||
*/
|
||||
extern pthread_mutexattr_t _POSIX_Mutex_Default_attributes;
|
||||
|
||||
RTEMS_INLINE_ROUTINE void _POSIX_Mutex_Acquire_critical(
|
||||
POSIX_Mutex_Control *the_mutex,
|
||||
Thread_queue_Context *queue_context
|
||||
)
|
||||
{
|
||||
_CORE_mutex_Acquire_critical(
|
||||
&the_mutex->Mutex.Recursive.Mutex,
|
||||
queue_context
|
||||
);
|
||||
}
|
||||
|
||||
RTEMS_INLINE_ROUTINE void _POSIX_Mutex_Release(
|
||||
POSIX_Mutex_Control *the_mutex,
|
||||
Thread_queue_Context *queue_context
|
||||
)
|
||||
{
|
||||
_CORE_mutex_Release(
|
||||
&the_mutex->Mutex.Recursive.Mutex,
|
||||
queue_context
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief POSIX Mutex Allocate
|
||||
*
|
||||
|
||||
@@ -37,21 +37,23 @@ int pthread_mutex_destroy(
|
||||
the_mutex = _POSIX_Mutex_Get( mutex, &queue_context );
|
||||
|
||||
if ( the_mutex != NULL ) {
|
||||
_CORE_mutex_Acquire_critical( &the_mutex->Mutex, &queue_context );
|
||||
_POSIX_Mutex_Acquire_critical( the_mutex, &queue_context );
|
||||
|
||||
/*
|
||||
* XXX: There is an error for the mutex being locked
|
||||
* or being in use by a condition variable.
|
||||
*/
|
||||
|
||||
if ( !_CORE_mutex_Is_locked( &the_mutex->Mutex ) ) {
|
||||
if (
|
||||
!_CORE_mutex_Is_locked( &the_mutex->Mutex.Recursive.Mutex )
|
||||
) {
|
||||
_Objects_Close( &_POSIX_Mutex_Information, &the_mutex->Object );
|
||||
_CORE_mutex_Release( &the_mutex->Mutex, &queue_context );
|
||||
_CORE_mutex_Destroy( &the_mutex->Mutex );
|
||||
_POSIX_Mutex_Release( the_mutex, &queue_context );
|
||||
_CORE_mutex_Destroy( &the_mutex->Mutex.Recursive.Mutex );
|
||||
_POSIX_Mutex_Free( the_mutex );
|
||||
eno = 0;
|
||||
} else {
|
||||
_CORE_mutex_Release( &the_mutex->Mutex, &queue_context );
|
||||
_POSIX_Mutex_Release( the_mutex, &queue_context );
|
||||
eno = EBUSY;
|
||||
}
|
||||
} else {
|
||||
|
||||
@@ -43,13 +43,13 @@ int pthread_mutex_getprioceiling(
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
_CORE_mutex_Acquire_critical( &the_mutex->Mutex, &queue_context );
|
||||
_POSIX_Mutex_Acquire_critical( the_mutex, &queue_context );
|
||||
|
||||
*prioceiling = _POSIX_Priority_From_core(
|
||||
the_mutex->Mutex.Attributes.priority_ceiling
|
||||
the_mutex->Mutex.Recursive.Mutex.Attributes.priority_ceiling
|
||||
);
|
||||
|
||||
_CORE_mutex_Release( &the_mutex->Mutex, &queue_context );
|
||||
_POSIX_Mutex_Release( the_mutex, &queue_context );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -33,10 +33,9 @@ int pthread_mutex_init(
|
||||
const pthread_mutexattr_t *attr
|
||||
)
|
||||
{
|
||||
POSIX_Mutex_Control *the_mutex;
|
||||
CORE_mutex_Attributes *the_mutex_attr;
|
||||
const pthread_mutexattr_t *the_attr;
|
||||
CORE_mutex_Disciplines the_discipline;
|
||||
POSIX_Mutex_Control *the_mutex;
|
||||
const pthread_mutexattr_t *the_attr;
|
||||
POSIX_Mutex_Protocol protocol;
|
||||
|
||||
if ( attr ) the_attr = attr;
|
||||
else the_attr = &_POSIX_Mutex_Default_attributes;
|
||||
@@ -75,13 +74,13 @@ int pthread_mutex_init(
|
||||
*/
|
||||
switch ( the_attr->protocol ) {
|
||||
case PTHREAD_PRIO_NONE:
|
||||
the_discipline = CORE_MUTEX_DISCIPLINES_FIFO;
|
||||
protocol = POSIX_MUTEX_NO_PROTOCOL;
|
||||
break;
|
||||
case PTHREAD_PRIO_INHERIT:
|
||||
the_discipline = CORE_MUTEX_DISCIPLINES_PRIORITY_INHERIT;
|
||||
protocol = POSIX_MUTEX_PRIORITY_INHERIT;
|
||||
break;
|
||||
case PTHREAD_PRIO_PROTECT:
|
||||
the_discipline = CORE_MUTEX_DISCIPLINES_PRIORITY_CEILING;
|
||||
protocol = POSIX_MUTEX_PRIORITY_CEILING;
|
||||
break;
|
||||
default:
|
||||
return EINVAL;
|
||||
@@ -117,21 +116,41 @@ int pthread_mutex_init(
|
||||
return EAGAIN;
|
||||
}
|
||||
|
||||
the_mutex_attr = &the_mutex->Mutex.Attributes;
|
||||
the_mutex->protocol = protocol;
|
||||
the_mutex->is_recursive = ( the_attr->type == PTHREAD_MUTEX_RECURSIVE );
|
||||
|
||||
if ( the_attr->type == PTHREAD_MUTEX_RECURSIVE )
|
||||
the_mutex_attr->lock_nesting_behavior = CORE_MUTEX_NESTING_ACQUIRES;
|
||||
else
|
||||
the_mutex_attr->lock_nesting_behavior = CORE_MUTEX_NESTING_IS_ERROR;
|
||||
the_mutex_attr->only_owner_release = true;
|
||||
the_mutex_attr->priority_ceiling =
|
||||
_POSIX_Priority_To_core( the_attr->prio_ceiling );
|
||||
the_mutex_attr->discipline = the_discipline;
|
||||
if ( protocol == POSIX_MUTEX_NO_PROTOCOL ) {
|
||||
_CORE_recursive_mutex_Initialize(
|
||||
&the_mutex->Mutex.Recursive
|
||||
);
|
||||
} else {
|
||||
CORE_mutex_Attributes the_mutex_attr;
|
||||
|
||||
/*
|
||||
* Must be initialized to unlocked.
|
||||
*/
|
||||
_CORE_mutex_Initialize( &the_mutex->Mutex, NULL, the_mutex_attr, false );
|
||||
if ( the_attr->type == PTHREAD_MUTEX_RECURSIVE ) {
|
||||
the_mutex_attr.lock_nesting_behavior = CORE_MUTEX_NESTING_ACQUIRES;
|
||||
} else {
|
||||
the_mutex_attr.lock_nesting_behavior = CORE_MUTEX_NESTING_IS_ERROR;
|
||||
}
|
||||
|
||||
the_mutex_attr.priority_ceiling =
|
||||
_POSIX_Priority_To_core( the_attr->prio_ceiling );
|
||||
|
||||
if ( protocol == POSIX_MUTEX_PRIORITY_CEILING ) {
|
||||
the_mutex_attr.discipline = CORE_MUTEX_DISCIPLINES_PRIORITY_CEILING;
|
||||
} else {
|
||||
the_mutex_attr.discipline = CORE_MUTEX_DISCIPLINES_PRIORITY_INHERIT;
|
||||
}
|
||||
|
||||
/*
|
||||
* Must be initialized to unlocked.
|
||||
*/
|
||||
_CORE_mutex_Initialize(
|
||||
&the_mutex->Mutex.Recursive.Mutex,
|
||||
NULL,
|
||||
&the_mutex_attr,
|
||||
false
|
||||
);
|
||||
}
|
||||
|
||||
_Objects_Open_u32( &_POSIX_Mutex_Information, &the_mutex->Object, 0 );
|
||||
|
||||
|
||||
@@ -21,16 +21,39 @@
|
||||
#include <rtems/posix/muteximpl.h>
|
||||
#include <rtems/posix/posixapi.h>
|
||||
|
||||
THREAD_QUEUE_OBJECT_ASSERT( POSIX_Mutex_Control, Mutex.Wait_queue );
|
||||
THREAD_QUEUE_OBJECT_ASSERT(
|
||||
POSIX_Mutex_Control,
|
||||
Mutex.Recursive.Mutex.Wait_queue
|
||||
);
|
||||
|
||||
static Status_Control _POSIX_Mutex_Lock_nested(
|
||||
CORE_recursive_mutex_Control *the_recursive_mutex
|
||||
)
|
||||
{
|
||||
POSIX_Mutex_Control *the_mutex;
|
||||
|
||||
the_mutex = RTEMS_CONTAINER_OF(
|
||||
the_recursive_mutex,
|
||||
POSIX_Mutex_Control,
|
||||
Mutex.Recursive
|
||||
);
|
||||
|
||||
if ( the_mutex->is_recursive ) {
|
||||
return _CORE_recursive_mutex_Seize_nested( the_recursive_mutex );
|
||||
} else {
|
||||
return STATUS_NESTING_NOT_ALLOWED;
|
||||
}
|
||||
}
|
||||
|
||||
int _POSIX_Mutex_Lock_support(
|
||||
pthread_mutex_t *mutex,
|
||||
bool blocking,
|
||||
bool wait,
|
||||
Watchdog_Interval timeout
|
||||
)
|
||||
{
|
||||
POSIX_Mutex_Control *the_mutex;
|
||||
Thread_queue_Context queue_context;
|
||||
Thread_Control *executing;
|
||||
Status_Control status;
|
||||
|
||||
the_mutex = _POSIX_Mutex_Get( mutex, &queue_context );
|
||||
@@ -39,12 +62,30 @@ int _POSIX_Mutex_Lock_support(
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
status = _CORE_mutex_Seize(
|
||||
&the_mutex->Mutex,
|
||||
_Thread_Executing,
|
||||
blocking,
|
||||
timeout,
|
||||
&queue_context
|
||||
);
|
||||
executing = _Thread_Executing;
|
||||
|
||||
switch ( the_mutex->protocol ) {
|
||||
case POSIX_MUTEX_NO_PROTOCOL:
|
||||
status = _CORE_recursive_mutex_Seize_no_protocol(
|
||||
&the_mutex->Mutex.Recursive,
|
||||
POSIX_MUTEX_NO_PROTOCOL_TQ_OPERATIONS,
|
||||
executing,
|
||||
wait,
|
||||
timeout,
|
||||
_POSIX_Mutex_Lock_nested,
|
||||
&queue_context
|
||||
);
|
||||
break;
|
||||
default:
|
||||
status = _CORE_mutex_Seize(
|
||||
&the_mutex->Mutex.Recursive.Mutex,
|
||||
executing,
|
||||
wait,
|
||||
timeout,
|
||||
&queue_context
|
||||
);
|
||||
break;
|
||||
}
|
||||
|
||||
return _POSIX_Get_error( status );
|
||||
}
|
||||
|
||||
@@ -57,9 +57,10 @@ int pthread_mutex_setprioceiling(
|
||||
_Assert( the_mutex != NULL );
|
||||
|
||||
*old_ceiling = _POSIX_Priority_From_core(
|
||||
the_mutex->Mutex.Attributes.priority_ceiling
|
||||
the_mutex->Mutex.Recursive.Mutex.Attributes.priority_ceiling
|
||||
);
|
||||
the_mutex->Mutex.Attributes.priority_ceiling = the_priority;
|
||||
the_mutex->Mutex.Recursive.Mutex.Attributes.priority_ceiling =
|
||||
the_priority;
|
||||
|
||||
error = pthread_mutex_unlock( mutex );
|
||||
_Assert( error == 0 );
|
||||
|
||||
@@ -33,6 +33,7 @@ int pthread_mutex_unlock(
|
||||
{
|
||||
POSIX_Mutex_Control *the_mutex;
|
||||
Thread_queue_Context queue_context;
|
||||
Thread_Control *executing;
|
||||
Status_Control status;
|
||||
|
||||
the_mutex = _POSIX_Mutex_Get( mutex, &queue_context );
|
||||
@@ -41,6 +42,24 @@ int pthread_mutex_unlock(
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
status = _CORE_mutex_Surrender( &the_mutex->Mutex, &queue_context );
|
||||
executing = _Thread_Executing;
|
||||
|
||||
switch ( the_mutex->protocol ) {
|
||||
case POSIX_MUTEX_NO_PROTOCOL:
|
||||
status = _CORE_recursive_mutex_Surrender_no_protocol(
|
||||
&the_mutex->Mutex.Recursive,
|
||||
POSIX_MUTEX_NO_PROTOCOL_TQ_OPERATIONS,
|
||||
executing,
|
||||
&queue_context
|
||||
);
|
||||
break;
|
||||
default:
|
||||
status = _CORE_mutex_Surrender(
|
||||
&the_mutex->Mutex.Recursive.Mutex,
|
||||
&queue_context
|
||||
);
|
||||
break;
|
||||
}
|
||||
|
||||
return _POSIX_Get_error( status );
|
||||
}
|
||||
|
||||
@@ -83,7 +83,7 @@ typedef struct {
|
||||
* This is the SuperCore Mutex instance associated with this Classic
|
||||
* API Semaphore instance.
|
||||
*/
|
||||
CORE_mutex_Control mutex;
|
||||
CORE_ceiling_mutex_Control Mutex;
|
||||
|
||||
/**
|
||||
* This is the SuperCore Semaphore instance associated with this Classic
|
||||
|
||||
@@ -26,8 +26,14 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Classic semaphore variants.
|
||||
*
|
||||
* Must be in synchronization with Semaphore_Control::variant.
|
||||
*/
|
||||
typedef enum {
|
||||
SEMAPHORE_VARIANT_MUTEX,
|
||||
SEMAPHORE_VARIANT_MUTEX_NO_PROTOCOL,
|
||||
SEMAPHORE_VARIANT_SIMPLE_BINARY,
|
||||
SEMAPHORE_VARIANT_COUNTING
|
||||
#if defined(RTEMS_SMP)
|
||||
|
||||
@@ -63,6 +63,7 @@ rtems_status_code rtems_semaphore_create(
|
||||
{
|
||||
Semaphore_Control *the_semaphore;
|
||||
CORE_mutex_Attributes the_mutex_attr;
|
||||
Thread_Control *executing;
|
||||
Status_Control status;
|
||||
|
||||
if ( !rtems_is_name_valid( name ) )
|
||||
@@ -136,6 +137,7 @@ rtems_status_code rtems_semaphore_create(
|
||||
#endif
|
||||
|
||||
the_semaphore->attribute_set = attribute_set;
|
||||
executing = _Thread_Get_executing();
|
||||
|
||||
if ( _Attributes_Is_priority( attribute_set ) ) {
|
||||
the_semaphore->discipline = SEMAPHORE_DISCIPLINE_PRIORITY;
|
||||
@@ -163,43 +165,46 @@ rtems_status_code rtems_semaphore_create(
|
||||
status = _MRSP_Initialize(
|
||||
&the_semaphore->Core_control.mrsp,
|
||||
priority_ceiling,
|
||||
_Thread_Get_executing(),
|
||||
executing,
|
||||
count != 1
|
||||
);
|
||||
#endif
|
||||
} else if (
|
||||
!_Attributes_Is_inherit_priority( attribute_set )
|
||||
&& !_Attributes_Is_priority_ceiling( attribute_set )
|
||||
) {
|
||||
_Assert( _Attributes_Is_binary_semaphore( attribute_set ) );
|
||||
the_semaphore->variant = SEMAPHORE_VARIANT_MUTEX_NO_PROTOCOL;
|
||||
_CORE_recursive_mutex_Initialize(
|
||||
&the_semaphore->Core_control.Mutex.Recursive
|
||||
);
|
||||
|
||||
if ( count == 0 ) {
|
||||
_CORE_mutex_Set_owner(
|
||||
&the_semaphore->Core_control.Mutex.Recursive.Mutex,
|
||||
executing
|
||||
);
|
||||
}
|
||||
|
||||
status = STATUS_SUCCESSFUL;
|
||||
} else {
|
||||
_Assert( _Attributes_Is_binary_semaphore( attribute_set ) );
|
||||
the_semaphore->variant = SEMAPHORE_VARIANT_MUTEX;
|
||||
|
||||
_Assert( _Attributes_Is_binary_semaphore( attribute_set ) );
|
||||
|
||||
/*
|
||||
* It is either simple binary semaphore or a more powerful mutex
|
||||
* style binary semaphore. This is the mutex style.
|
||||
*/
|
||||
if ( _Attributes_Is_priority( attribute_set ) )
|
||||
the_mutex_attr.discipline = CORE_MUTEX_DISCIPLINES_PRIORITY;
|
||||
else
|
||||
the_mutex_attr.discipline = CORE_MUTEX_DISCIPLINES_FIFO;
|
||||
|
||||
the_mutex_attr.priority_ceiling = _RTEMS_tasks_Priority_to_Core(
|
||||
priority_ceiling
|
||||
);
|
||||
the_mutex_attr.priority_ceiling =
|
||||
_RTEMS_tasks_Priority_to_Core( priority_ceiling );
|
||||
the_mutex_attr.lock_nesting_behavior = CORE_MUTEX_NESTING_ACQUIRES;
|
||||
the_mutex_attr.only_owner_release = false;
|
||||
|
||||
if ( the_mutex_attr.discipline == CORE_MUTEX_DISCIPLINES_PRIORITY ) {
|
||||
if ( _Attributes_Is_inherit_priority( attribute_set ) ) {
|
||||
the_mutex_attr.discipline = CORE_MUTEX_DISCIPLINES_PRIORITY_INHERIT;
|
||||
the_mutex_attr.only_owner_release = true;
|
||||
} else if ( _Attributes_Is_priority_ceiling( attribute_set ) ) {
|
||||
the_mutex_attr.discipline = CORE_MUTEX_DISCIPLINES_PRIORITY_CEILING;
|
||||
the_mutex_attr.only_owner_release = true;
|
||||
}
|
||||
if ( _Attributes_Is_inherit_priority( attribute_set ) ) {
|
||||
the_mutex_attr.discipline = CORE_MUTEX_DISCIPLINES_PRIORITY_INHERIT;
|
||||
} else {
|
||||
_Assert( _Attributes_Is_priority_ceiling( attribute_set ) );
|
||||
the_mutex_attr.discipline = CORE_MUTEX_DISCIPLINES_PRIORITY_CEILING;
|
||||
}
|
||||
|
||||
status = _CORE_mutex_Initialize(
|
||||
&the_semaphore->Core_control.mutex,
|
||||
_Thread_Get_executing(),
|
||||
&the_semaphore->Core_control.Mutex.Recursive.Mutex,
|
||||
executing,
|
||||
&the_mutex_attr,
|
||||
count != 1
|
||||
);
|
||||
|
||||
@@ -51,7 +51,12 @@ rtems_status_code rtems_semaphore_delete(
|
||||
|
||||
switch ( the_semaphore->variant ) {
|
||||
case SEMAPHORE_VARIANT_MUTEX:
|
||||
if ( _CORE_mutex_Is_locked( &the_semaphore->Core_control.mutex ) ) {
|
||||
case SEMAPHORE_VARIANT_MUTEX_NO_PROTOCOL:
|
||||
if (
|
||||
_CORE_mutex_Is_locked(
|
||||
&the_semaphore->Core_control.Mutex.Recursive.Mutex
|
||||
)
|
||||
) {
|
||||
status = STATUS_RESOURCE_IN_USE;
|
||||
} else {
|
||||
status = STATUS_SUCCESSFUL;
|
||||
@@ -92,6 +97,7 @@ rtems_status_code rtems_semaphore_delete(
|
||||
default:
|
||||
_Assert(
|
||||
the_semaphore->variant == SEMAPHORE_VARIANT_MUTEX
|
||||
|| the_semaphore->variant == SEMAPHORE_VARIANT_MUTEX_NO_PROTOCOL
|
||||
|| the_semaphore->variant == SEMAPHORE_VARIANT_SIMPLE_BINARY
|
||||
|| the_semaphore->variant == SEMAPHORE_VARIANT_COUNTING
|
||||
);
|
||||
|
||||
@@ -58,6 +58,7 @@ rtems_status_code rtems_semaphore_flush( rtems_id id )
|
||||
default:
|
||||
_Assert(
|
||||
the_semaphore->variant == SEMAPHORE_VARIANT_MUTEX
|
||||
|| the_semaphore->variant == SEMAPHORE_VARIANT_MUTEX_NO_PROTOCOL
|
||||
|| the_semaphore->variant == SEMAPHORE_VARIANT_SIMPLE_BINARY
|
||||
|| the_semaphore->variant == SEMAPHORE_VARIANT_COUNTING
|
||||
);
|
||||
|
||||
@@ -29,7 +29,7 @@ THREAD_QUEUE_OBJECT_ASSERT(
|
||||
|
||||
THREAD_QUEUE_OBJECT_ASSERT(
|
||||
Semaphore_Control,
|
||||
Core_control.mutex.Wait_queue
|
||||
Core_control.Mutex.Recursive.Mutex.Wait_queue
|
||||
);
|
||||
|
||||
THREAD_QUEUE_OBJECT_ASSERT(
|
||||
@@ -83,13 +83,24 @@ rtems_status_code rtems_semaphore_obtain(
|
||||
#endif
|
||||
case SEMAPHORE_VARIANT_MUTEX:
|
||||
status = _CORE_mutex_Seize(
|
||||
&the_semaphore->Core_control.mutex,
|
||||
&the_semaphore->Core_control.Mutex.Recursive.Mutex,
|
||||
executing,
|
||||
wait,
|
||||
timeout,
|
||||
&queue_context
|
||||
);
|
||||
break;
|
||||
case SEMAPHORE_VARIANT_MUTEX_NO_PROTOCOL:
|
||||
status = _CORE_recursive_mutex_Seize_no_protocol(
|
||||
&the_semaphore->Core_control.Mutex.Recursive,
|
||||
_Semaphore_Get_operations( the_semaphore ),
|
||||
executing,
|
||||
wait,
|
||||
timeout,
|
||||
_CORE_recursive_mutex_Seize_nested,
|
||||
&queue_context
|
||||
);
|
||||
break;
|
||||
default:
|
||||
_Assert(
|
||||
the_semaphore->variant == SEMAPHORE_VARIANT_SIMPLE_BINARY
|
||||
|
||||
@@ -57,10 +57,18 @@ rtems_status_code rtems_semaphore_release( rtems_id id )
|
||||
#endif
|
||||
case SEMAPHORE_VARIANT_MUTEX:
|
||||
status = _CORE_mutex_Surrender(
|
||||
&the_semaphore->Core_control.mutex,
|
||||
&the_semaphore->Core_control.Mutex.Recursive.Mutex,
|
||||
&queue_context
|
||||
);
|
||||
break;
|
||||
case SEMAPHORE_VARIANT_MUTEX_NO_PROTOCOL:
|
||||
_CORE_recursive_mutex_Surrender_no_protocol_classic(
|
||||
&the_semaphore->Core_control.Mutex.Recursive,
|
||||
_Semaphore_Get_operations( the_semaphore ),
|
||||
&queue_context
|
||||
);
|
||||
status = STATUS_SUCCESSFUL;
|
||||
break;
|
||||
case SEMAPHORE_VARIANT_SIMPLE_BINARY:
|
||||
status = _CORE_semaphore_Surrender(
|
||||
&the_semaphore->Core_control.semaphore,
|
||||
|
||||
@@ -54,8 +54,9 @@ static rtems_status_code _Semaphore_Set_priority(
|
||||
} else
|
||||
#endif
|
||||
if ( _Attributes_Is_priority_ceiling( attribute_set ) ) {
|
||||
CORE_mutex_Control *mutex = &the_semaphore->Core_control.mutex;
|
||||
CORE_mutex_Control *mutex;
|
||||
|
||||
mutex = &the_semaphore->Core_control.Mutex.Recursive.Mutex;
|
||||
_CORE_mutex_Acquire_critical( mutex, queue_context );
|
||||
|
||||
old_priority = mutex->Attributes.priority_ceiling;
|
||||
|
||||
@@ -47,10 +47,6 @@ extern "C" {
|
||||
* This enumerated type defines the blocking disciplines for a mutex.
|
||||
*/
|
||||
typedef enum {
|
||||
/** This specifies that threads will wait for the mutex in FIFO order. */
|
||||
CORE_MUTEX_DISCIPLINES_FIFO,
|
||||
/** This specifies that threads will wait for the mutex in priority order. */
|
||||
CORE_MUTEX_DISCIPLINES_PRIORITY,
|
||||
/** This specifies that threads will wait for the mutex in priority order.
|
||||
* Additionally, the Priority Inheritance Protocol will be in effect.
|
||||
*/
|
||||
@@ -100,10 +96,6 @@ typedef struct {
|
||||
* be when attempting to acquire the mutex when it is already locked.
|
||||
*/
|
||||
CORE_mutex_Nesting_behaviors lock_nesting_behavior;
|
||||
/** When this field is true, then only the thread that locked the mutex
|
||||
* is allowed to unlock it.
|
||||
*/
|
||||
bool only_owner_release;
|
||||
/** This field indicates whether threads waiting on the mutex block in
|
||||
* FIFO or priority order.
|
||||
*/
|
||||
@@ -125,11 +117,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 is the set of attributes which define this instance's
|
||||
* behavior.
|
||||
*/
|
||||
@@ -145,6 +132,36 @@ typedef struct {
|
||||
Thread_Control *holder;
|
||||
} CORE_mutex_Control;
|
||||
|
||||
/**
|
||||
* @brief The recursive mutex control.
|
||||
*/
|
||||
typedef struct {
|
||||
/**
|
||||
* @brief The plain non-recursive mutex.
|
||||
*/
|
||||
CORE_mutex_Control Mutex;
|
||||
|
||||
/**
|
||||
* @brief The nest level in case of a recursive seize.
|
||||
*/
|
||||
unsigned int nest_level;
|
||||
} CORE_recursive_mutex_Control;
|
||||
|
||||
/**
|
||||
* @brief The recursive mutex control with priority ceiling protocol support.
|
||||
*/
|
||||
typedef struct {
|
||||
/**
|
||||
* @brief The plain recursive mutex.
|
||||
*/
|
||||
CORE_recursive_mutex_Control Recursive;
|
||||
|
||||
/**
|
||||
* @brief The priority ceiling value for the mutex owner.
|
||||
*/
|
||||
Priority_Control priority_ceiling;
|
||||
} CORE_ceiling_mutex_Control;
|
||||
|
||||
/**@}*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
@@ -33,6 +33,8 @@ extern "C" {
|
||||
*/
|
||||
/**@{**/
|
||||
|
||||
#define CORE_MUTEX_TQ_OPERATIONS &_Thread_queue_Operations_priority
|
||||
|
||||
/**
|
||||
* @brief Initializes the mutex based on the parameters passed.
|
||||
*
|
||||
@@ -100,6 +102,13 @@ Status_Control _CORE_mutex_Seize_interrupt_blocking(
|
||||
Thread_queue_Context *queue_context
|
||||
);
|
||||
|
||||
RTEMS_INLINE_ROUTINE Thread_Control *_CORE_mutex_Get_owner(
|
||||
const CORE_mutex_Control *the_mutex
|
||||
)
|
||||
{
|
||||
return the_mutex->holder;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Is mutex locked.
|
||||
*
|
||||
@@ -115,7 +124,7 @@ RTEMS_INLINE_ROUTINE bool _CORE_mutex_Is_locked(
|
||||
const CORE_mutex_Control *the_mutex
|
||||
)
|
||||
{
|
||||
return the_mutex->holder != NULL;
|
||||
return _CORE_mutex_Get_owner( the_mutex ) != NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -180,10 +189,7 @@ RTEMS_INLINE_ROUTINE Status_Control _CORE_mutex_Seize_interrupt_trylock(
|
||||
if ( !_CORE_mutex_Is_locked( the_mutex ) ) {
|
||||
the_mutex->holder = executing;
|
||||
the_mutex->nest_count = 1;
|
||||
if ( _CORE_mutex_Is_inherit_priority( &the_mutex->Attributes ) ||
|
||||
_CORE_mutex_Is_priority_ceiling( &the_mutex->Attributes ) ){
|
||||
executing->resource_count++;
|
||||
}
|
||||
++executing->resource_count;
|
||||
|
||||
if ( !_CORE_mutex_Is_priority_ceiling( &the_mutex->Attributes ) ) {
|
||||
_CORE_mutex_Release( the_mutex, queue_context );
|
||||
@@ -309,35 +315,168 @@ RTEMS_INLINE_ROUTINE Status_Control _CORE_mutex_Seize(
|
||||
);
|
||||
}
|
||||
|
||||
Status_Control _CORE_mutex_Seize_no_protocol_slow(
|
||||
CORE_mutex_Control *the_mutex,
|
||||
const Thread_queue_Operations *operations,
|
||||
Thread_Control *executing,
|
||||
bool wait,
|
||||
Watchdog_Interval timeout,
|
||||
Thread_queue_Context *queue_context
|
||||
);
|
||||
|
||||
Status_Control _CORE_mutex_Surrender(
|
||||
CORE_mutex_Control *the_mutex,
|
||||
Thread_queue_Context *queue_context
|
||||
);
|
||||
|
||||
RTEMS_INLINE_ROUTINE void _CORE_mutex_Set_owner(
|
||||
CORE_mutex_Control *the_mutex,
|
||||
Thread_Control *owner
|
||||
)
|
||||
{
|
||||
the_mutex->holder = owner;
|
||||
}
|
||||
|
||||
RTEMS_INLINE_ROUTINE bool _CORE_mutex_Is_owner(
|
||||
const CORE_mutex_Control *the_mutex,
|
||||
const Thread_Control *the_thread
|
||||
)
|
||||
{
|
||||
return the_mutex->holder == the_thread;
|
||||
return _CORE_mutex_Get_owner( the_mutex ) == the_thread;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Does core mutex use FIFO blocking.
|
||||
*
|
||||
* This routine returns true if the mutex's wait discipline is FIFO and false
|
||||
* otherwise.
|
||||
*
|
||||
* @param[in] the_attribute is the attribute set of the mutex.
|
||||
*
|
||||
* @retval true The mutex is using FIFO blocking order.
|
||||
* @retval false The mutex is not using FIFO blocking order.
|
||||
*/
|
||||
RTEMS_INLINE_ROUTINE bool _CORE_mutex_Is_fifo(
|
||||
const CORE_mutex_Attributes *the_attribute
|
||||
RTEMS_INLINE_ROUTINE void _CORE_recursive_mutex_Initialize(
|
||||
CORE_recursive_mutex_Control *the_mutex
|
||||
)
|
||||
{
|
||||
return the_attribute->discipline == CORE_MUTEX_DISCIPLINES_FIFO;
|
||||
_Thread_queue_Initialize( &the_mutex->Mutex.Wait_queue );
|
||||
the_mutex->Mutex.holder = NULL;
|
||||
the_mutex->nest_level = 0;
|
||||
}
|
||||
|
||||
RTEMS_INLINE_ROUTINE Status_Control _CORE_recursive_mutex_Seize_nested(
|
||||
CORE_recursive_mutex_Control *the_mutex
|
||||
)
|
||||
{
|
||||
++the_mutex->nest_level;
|
||||
return STATUS_SUCCESSFUL;
|
||||
}
|
||||
|
||||
RTEMS_INLINE_ROUTINE Status_Control _CORE_recursive_mutex_Seize_no_protocol(
|
||||
CORE_recursive_mutex_Control *the_mutex,
|
||||
const Thread_queue_Operations *operations,
|
||||
Thread_Control *executing,
|
||||
bool wait,
|
||||
Watchdog_Interval timeout,
|
||||
Status_Control ( *nested )( CORE_recursive_mutex_Control * ),
|
||||
Thread_queue_Context *queue_context
|
||||
)
|
||||
{
|
||||
Thread_Control *owner;
|
||||
|
||||
_CORE_mutex_Acquire_critical( &the_mutex->Mutex, queue_context );
|
||||
|
||||
owner = _CORE_mutex_Get_owner( &the_mutex->Mutex );
|
||||
|
||||
if ( owner == NULL ) {
|
||||
_CORE_mutex_Set_owner( &the_mutex->Mutex, executing );
|
||||
_CORE_mutex_Release( &the_mutex->Mutex, queue_context );
|
||||
return STATUS_SUCCESSFUL;
|
||||
}
|
||||
|
||||
if ( owner == executing ) {
|
||||
Status_Control status;
|
||||
|
||||
status = ( *nested )( the_mutex );
|
||||
_CORE_mutex_Release( &the_mutex->Mutex, queue_context );
|
||||
return status;
|
||||
}
|
||||
|
||||
return _CORE_mutex_Seize_no_protocol_slow(
|
||||
&the_mutex->Mutex,
|
||||
operations,
|
||||
executing,
|
||||
wait,
|
||||
timeout,
|
||||
queue_context
|
||||
);
|
||||
}
|
||||
|
||||
RTEMS_INLINE_ROUTINE void
|
||||
_CORE_recursive_mutex_Surrender_no_protocol_finalize(
|
||||
CORE_recursive_mutex_Control *the_mutex,
|
||||
const Thread_queue_Operations *operations,
|
||||
Thread_queue_Context *queue_context
|
||||
)
|
||||
{
|
||||
unsigned int nest_level;
|
||||
Thread_Control *new_owner;
|
||||
|
||||
nest_level = the_mutex->nest_level;
|
||||
|
||||
if ( nest_level > 0 ) {
|
||||
the_mutex->nest_level = nest_level - 1;
|
||||
_CORE_mutex_Release( &the_mutex->Mutex, queue_context );
|
||||
return;
|
||||
}
|
||||
|
||||
new_owner = _Thread_queue_First_locked(
|
||||
&the_mutex->Mutex.Wait_queue,
|
||||
operations
|
||||
);
|
||||
_CORE_mutex_Set_owner( &the_mutex->Mutex, new_owner );
|
||||
|
||||
if ( new_owner == NULL ) {
|
||||
_CORE_mutex_Release( &the_mutex->Mutex, queue_context );
|
||||
return;
|
||||
}
|
||||
|
||||
_Thread_queue_Extract_critical(
|
||||
&the_mutex->Mutex.Wait_queue.Queue,
|
||||
operations,
|
||||
new_owner,
|
||||
queue_context
|
||||
);
|
||||
}
|
||||
|
||||
RTEMS_INLINE_ROUTINE Status_Control _CORE_recursive_mutex_Surrender_no_protocol(
|
||||
CORE_recursive_mutex_Control *the_mutex,
|
||||
const Thread_queue_Operations *operations,
|
||||
Thread_Control *executing,
|
||||
Thread_queue_Context *queue_context
|
||||
)
|
||||
{
|
||||
_CORE_mutex_Acquire_critical( &the_mutex->Mutex, queue_context );
|
||||
|
||||
if ( !_CORE_mutex_Is_owner( &the_mutex->Mutex, executing ) ) {
|
||||
_CORE_mutex_Release( &the_mutex->Mutex, queue_context );
|
||||
return STATUS_NOT_OWNER;
|
||||
}
|
||||
|
||||
_CORE_recursive_mutex_Surrender_no_protocol_finalize(
|
||||
the_mutex,
|
||||
operations,
|
||||
queue_context
|
||||
);
|
||||
return STATUS_SUCCESSFUL;
|
||||
}
|
||||
|
||||
/*
|
||||
* The Classic no protocol recursive mutex has the nice property that everyone
|
||||
* can release it.
|
||||
*/
|
||||
RTEMS_INLINE_ROUTINE void _CORE_recursive_mutex_Surrender_no_protocol_classic(
|
||||
CORE_recursive_mutex_Control *the_mutex,
|
||||
const Thread_queue_Operations *operations,
|
||||
Thread_queue_Context *queue_context
|
||||
)
|
||||
{
|
||||
_CORE_mutex_Acquire_critical( &the_mutex->Mutex, queue_context );
|
||||
_CORE_recursive_mutex_Surrender_no_protocol_finalize(
|
||||
the_mutex,
|
||||
operations,
|
||||
queue_context
|
||||
);
|
||||
}
|
||||
|
||||
/** @} */
|
||||
|
||||
@@ -49,7 +49,6 @@ void _API_Mutex_Allocate(
|
||||
|
||||
CORE_mutex_Attributes attr = {
|
||||
CORE_MUTEX_NESTING_ACQUIRES,
|
||||
true,
|
||||
CORE_MUTEX_DISCIPLINES_PRIORITY_INHERIT,
|
||||
0
|
||||
};
|
||||
|
||||
@@ -39,42 +39,41 @@ Status_Control _CORE_mutex_Initialize(
|
||||
the_mutex->Attributes = *the_mutex_attributes;
|
||||
|
||||
if ( initially_locked ) {
|
||||
bool is_priority_ceiling =
|
||||
_CORE_mutex_Is_priority_ceiling( &the_mutex->Attributes );
|
||||
bool is_priority_ceiling;
|
||||
Priority_Control ceiling;
|
||||
Per_CPU_Control *cpu_self;
|
||||
|
||||
the_mutex->nest_count = 1;
|
||||
the_mutex->holder = executing;
|
||||
|
||||
if ( is_priority_ceiling ||
|
||||
_CORE_mutex_Is_inherit_priority( &the_mutex->Attributes ) ) {
|
||||
Priority_Control ceiling = the_mutex->Attributes.priority_ceiling;
|
||||
Per_CPU_Control *cpu_self;
|
||||
/* The mutex initialization is only protected by the allocator lock */
|
||||
cpu_self = _Thread_Dispatch_disable();
|
||||
|
||||
/* The mutex initialization is only protected by the allocator lock */
|
||||
cpu_self = _Thread_Dispatch_disable();
|
||||
is_priority_ceiling =
|
||||
_CORE_mutex_Is_priority_ceiling( &the_mutex->Attributes );
|
||||
ceiling = the_mutex->Attributes.priority_ceiling;
|
||||
|
||||
/*
|
||||
* The test to check for a ceiling violation is a bit arbitrary. In case
|
||||
* this thread is the owner of a priority inheritance mutex, then it may
|
||||
* get a higher priority later or anytime on SMP configurations.
|
||||
*/
|
||||
if ( is_priority_ceiling && executing->current_priority < ceiling ) {
|
||||
/*
|
||||
* The test to check for a ceiling violation is a bit arbitrary. In case
|
||||
* this thread is the owner of a priority inheritance mutex, then it may
|
||||
* get a higher priority later or anytime on SMP configurations.
|
||||
* There is no need to undo the previous work since this error aborts
|
||||
* the object creation.
|
||||
*/
|
||||
if ( is_priority_ceiling && executing->current_priority < ceiling ) {
|
||||
/*
|
||||
* There is no need to undo the previous work since this error aborts
|
||||
* the object creation.
|
||||
*/
|
||||
_Thread_Dispatch_enable( cpu_self );
|
||||
return STATUS_MUTEX_CEILING_VIOLATED;
|
||||
}
|
||||
|
||||
executing->resource_count++;
|
||||
|
||||
if ( is_priority_ceiling ) {
|
||||
_Thread_Raise_priority( executing, ceiling );
|
||||
}
|
||||
|
||||
_Thread_Dispatch_enable( cpu_self );
|
||||
return STATUS_MUTEX_CEILING_VIOLATED;
|
||||
}
|
||||
|
||||
executing->resource_count++;
|
||||
|
||||
if ( is_priority_ceiling ) {
|
||||
_Thread_Raise_priority( executing, ceiling );
|
||||
}
|
||||
|
||||
_Thread_Dispatch_enable( cpu_self );
|
||||
} else {
|
||||
the_mutex->nest_count = 0;
|
||||
the_mutex->holder = NULL;
|
||||
@@ -82,11 +81,5 @@ Status_Control _CORE_mutex_Initialize(
|
||||
|
||||
_Thread_queue_Initialize( &the_mutex->Wait_queue );
|
||||
|
||||
if ( _CORE_mutex_Is_fifo( the_mutex_attributes ) ) {
|
||||
the_mutex->operations = &_Thread_queue_Operations_FIFO;
|
||||
} else {
|
||||
the_mutex->operations = &_Thread_queue_Operations_priority;
|
||||
}
|
||||
|
||||
return STATUS_SUCCESSFUL;
|
||||
}
|
||||
|
||||
@@ -68,7 +68,7 @@ Status_Control _CORE_mutex_Seize_interrupt_blocking(
|
||||
|
||||
_Thread_queue_Enqueue_critical(
|
||||
&the_mutex->Wait_queue.Queue,
|
||||
the_mutex->operations,
|
||||
CORE_MUTEX_TQ_OPERATIONS,
|
||||
executing,
|
||||
STATES_WAITING_FOR_MUTEX,
|
||||
timeout,
|
||||
@@ -82,3 +82,28 @@ Status_Control _CORE_mutex_Seize_interrupt_blocking(
|
||||
return _Thread_Wait_get_status( executing );
|
||||
}
|
||||
|
||||
Status_Control _CORE_mutex_Seize_no_protocol_slow(
|
||||
CORE_mutex_Control *the_mutex,
|
||||
const Thread_queue_Operations *operations,
|
||||
Thread_Control *executing,
|
||||
bool wait,
|
||||
Watchdog_Interval timeout,
|
||||
Thread_queue_Context *queue_context
|
||||
)
|
||||
{
|
||||
if ( wait ) {
|
||||
_Thread_queue_Context_set_expected_level( queue_context, 1 );
|
||||
_Thread_queue_Enqueue_critical(
|
||||
&the_mutex->Wait_queue.Queue,
|
||||
operations,
|
||||
executing,
|
||||
STATES_WAITING_FOR_MUTEX,
|
||||
timeout,
|
||||
queue_context
|
||||
);
|
||||
return _Thread_Wait_get_status( executing );
|
||||
} else {
|
||||
_CORE_mutex_Release( the_mutex, queue_context );
|
||||
return STATUS_UNAVAILABLE;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,18 +34,12 @@ Status_Control _CORE_mutex_Surrender(
|
||||
holder = the_mutex->holder;
|
||||
|
||||
/*
|
||||
* The following code allows a thread (or ISR) other than the thread
|
||||
* which acquired the mutex to release that mutex. This is only
|
||||
* allowed when the mutex in quetion is FIFO or simple Priority
|
||||
* discipline. But Priority Ceiling or Priority Inheritance mutexes
|
||||
* must be released by the thread which acquired them.
|
||||
* Priority Ceiling or Priority Inheritance mutexes must be released by the
|
||||
* thread which acquired them.
|
||||
*/
|
||||
|
||||
if ( the_mutex->Attributes.only_owner_release ) {
|
||||
if ( !_Thread_Is_executing( holder ) ) {
|
||||
_ISR_lock_ISR_enable( &queue_context->Lock_context );
|
||||
return STATUS_NOT_OWNER;
|
||||
}
|
||||
if ( !_Thread_Is_executing( holder ) ) {
|
||||
_ISR_lock_ISR_enable( &queue_context->Lock_context );
|
||||
return STATUS_NOT_OWNER;
|
||||
}
|
||||
|
||||
_CORE_mutex_Acquire_critical( the_mutex, queue_context );
|
||||
@@ -88,10 +82,7 @@ Status_Control _CORE_mutex_Surrender(
|
||||
* Formally release the mutex before possibly transferring it to a
|
||||
* blocked thread.
|
||||
*/
|
||||
if ( _CORE_mutex_Is_inherit_priority( &the_mutex->Attributes ) ||
|
||||
_CORE_mutex_Is_priority_ceiling( &the_mutex->Attributes ) ) {
|
||||
holder->resource_count--;
|
||||
}
|
||||
holder->resource_count--;
|
||||
the_mutex->holder = NULL;
|
||||
|
||||
/*
|
||||
@@ -101,7 +92,7 @@ Status_Control _CORE_mutex_Surrender(
|
||||
if (
|
||||
( the_thread = _Thread_queue_First_locked(
|
||||
&the_mutex->Wait_queue,
|
||||
the_mutex->operations
|
||||
CORE_MUTEX_TQ_OPERATIONS
|
||||
)
|
||||
)
|
||||
) {
|
||||
@@ -118,7 +109,7 @@ Status_Control _CORE_mutex_Surrender(
|
||||
*/
|
||||
unblock = _Thread_queue_Extract_locked(
|
||||
&the_mutex->Wait_queue.Queue,
|
||||
the_mutex->operations,
|
||||
CORE_MUTEX_TQ_OPERATIONS,
|
||||
the_thread,
|
||||
queue_context
|
||||
);
|
||||
@@ -128,9 +119,6 @@ Status_Control _CORE_mutex_Surrender(
|
||||
#endif
|
||||
{
|
||||
switch ( the_mutex->Attributes.discipline ) {
|
||||
case CORE_MUTEX_DISCIPLINES_FIFO:
|
||||
case CORE_MUTEX_DISCIPLINES_PRIORITY:
|
||||
break;
|
||||
case CORE_MUTEX_DISCIPLINES_PRIORITY_INHERIT:
|
||||
the_thread->resource_count++;
|
||||
_Thread_queue_Boost_priority( &the_mutex->Wait_queue.Queue, the_thread );
|
||||
|
||||
Reference in New Issue
Block a user