diff options
Diffstat (limited to 'cpukit/posix/src/mutexunlock.c')
-rw-r--r-- | cpukit/posix/src/mutexunlock.c | 75 |
1 files changed, 60 insertions, 15 deletions
diff --git a/cpukit/posix/src/mutexunlock.c b/cpukit/posix/src/mutexunlock.c index c15f7e6ad2..ead3109812 100644 --- a/cpukit/posix/src/mutexunlock.c +++ b/cpukit/posix/src/mutexunlock.c @@ -21,6 +21,51 @@ #include <rtems/posix/muteximpl.h> #include <rtems/posix/posixapi.h> +#include <string.h> + +bool _POSIX_Mutex_Auto_initialization( POSIX_Mutex_Control *the_mutex ) +{ + unsigned long zero; + unsigned long flags; + + /* We cannot use memset() and memcmp() due to structure internal padding */ + zero = 0; + zero |= the_mutex->flags; +#if defined(RTEMS_SMP) + zero |= _Atomic_Load_uint( + &the_mutex->Recursive.Mutex.Queue.Queue.Lock.next_ticket, + ATOMIC_ORDER_RELAXED + ); + zero |= _Atomic_Load_uint( + &the_mutex->Recursive.Mutex.Queue.Queue.Lock.now_serving, + ATOMIC_ORDER_RELAXED + ); +#else + zero |= the_mutex->Recursive.Mutex.Queue.reserved[ 0 ]; + zero |= the_mutex->Recursive.Mutex.Queue.reserved[ 1 ]; +#endif + zero |= (unsigned long) the_mutex->Recursive.Mutex.Queue.Queue.heads; + zero |= (unsigned long) the_mutex->Recursive.Mutex.Queue.Queue.owner; + zero |= (unsigned long) the_mutex->Recursive.Mutex.Queue.Queue.name; + zero |= the_mutex->Recursive.nest_level; + zero |= (unsigned long) the_mutex->Priority_ceiling.Node.RBTree.Node.rbe_left; + zero |= (unsigned long) the_mutex->Priority_ceiling.Node.RBTree.Node.rbe_right; + zero |= (unsigned long) the_mutex->Priority_ceiling.Node.RBTree.Node.rbe_parent; + zero |= (unsigned long) the_mutex->Priority_ceiling.Node.RBTree.Node.rbe_color; + zero |= (unsigned long) the_mutex->Priority_ceiling.priority; + zero |= (unsigned long) (the_mutex->Priority_ceiling.priority >> 32); + zero |= (unsigned long) the_mutex->scheduler; + + if ( zero != 0 ) { + return false; + } + + flags = (uintptr_t) the_mutex ^ POSIX_MUTEX_MAGIC; + flags &= ~POSIX_MUTEX_FLAGS_MASK; + the_mutex->flags = flags; + return true; +} + /* * 11.3.3 Locking and Unlocking a Mutex, P1003.1c/Draft 10, p. 93 * @@ -32,39 +77,39 @@ int pthread_mutex_unlock( ) { POSIX_Mutex_Control *the_mutex; + unsigned long flags; Thread_queue_Context queue_context; Thread_Control *executing; Status_Control status; - the_mutex = _POSIX_Mutex_Get( mutex, &queue_context ); + the_mutex = _POSIX_Mutex_Get( mutex ); + POSIX_MUTEX_VALIDATE_OBJECT( the_mutex, flags ); - if ( the_mutex == NULL ) { - return EINVAL; - } - - executing = _Thread_Executing; + executing = _POSIX_Mutex_Acquire( the_mutex, &queue_context ); - switch ( the_mutex->protocol ) { + switch ( _POSIX_Mutex_Get_protocol( flags ) ) { case POSIX_MUTEX_PRIORITY_CEILING: - status = _CORE_ceiling_mutex_Surrender( - &the_mutex->Mutex, + status = _POSIX_Mutex_Ceiling_surrender( + the_mutex, executing, &queue_context ); break; case POSIX_MUTEX_NO_PROTOCOL: - status = _CORE_recursive_mutex_Surrender( - &the_mutex->Mutex.Recursive, + status = _POSIX_Mutex_Surrender( + the_mutex, POSIX_MUTEX_NO_PROTOCOL_TQ_OPERATIONS, executing, &queue_context ); break; default: - _Assert( the_mutex->protocol == POSIX_MUTEX_PRIORITY_INHERIT ); - status = _CORE_recursive_mutex_Surrender( - &the_mutex->Mutex.Recursive, - CORE_MUTEX_TQ_PRIORITY_INHERIT_OPERATIONS, + _Assert( + _POSIX_Mutex_Get_protocol( flags ) == POSIX_MUTEX_PRIORITY_INHERIT + ); + status = _POSIX_Mutex_Surrender( + the_mutex, + POSIX_MUTEX_PRIORITY_INHERIT_TQ_OPERATIONS, executing, &queue_context ); |