diff options
Diffstat (limited to 'cpukit/posix/include/rtems/posix/muteximpl.h')
-rw-r--r-- | cpukit/posix/include/rtems/posix/muteximpl.h | 487 |
1 files changed, 0 insertions, 487 deletions
diff --git a/cpukit/posix/include/rtems/posix/muteximpl.h b/cpukit/posix/include/rtems/posix/muteximpl.h deleted file mode 100644 index 435b43634d..0000000000 --- a/cpukit/posix/include/rtems/posix/muteximpl.h +++ /dev/null @@ -1,487 +0,0 @@ -/** - * @file - * - * @brief Private Inlined Routines for POSIX Mutex's. - * - * This include file contains the static inline implementation of the private - * inlined routines for POSIX mutex's. - */ - -/* COPYRIGHT (c) 1989-2013. - * On-Line Applications Research Corporation (OAR). - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. - */ - -#ifndef _RTEMS_POSIX_MUTEXIMPL_H -#define _RTEMS_POSIX_MUTEXIMPL_H - -#include <errno.h> -#include <pthread.h> - -#include <rtems/score/percpu.h> -#include <rtems/score/muteximpl.h> -#include <rtems/score/threadimpl.h> - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct { - unsigned long flags; - Mutex_recursive_Control Recursive; - Priority_Node Priority_ceiling; - const Scheduler_Control *scheduler; -} POSIX_Mutex_Control; - -#define POSIX_MUTEX_PROTOCOL_MASK 0x3UL - -#define POSIX_MUTEX_RECURSIVE 0x4UL - -#define POSIX_MUTEX_FLAGS_MASK 0x7UL - -#define POSIX_MUTEX_MAGIC 0x961c13b8UL - -#define POSIX_MUTEX_NO_PROTOCOL_TQ_OPERATIONS &_Thread_queue_Operations_FIFO - -#define POSIX_MUTEX_PRIORITY_INHERIT_TQ_OPERATIONS \ - &_Thread_queue_Operations_priority_inherit - -#define POSIX_MUTEX_PRIORITY_CEILING_TQ_OPERATIONS \ - &_Thread_queue_Operations_priority - -/** - * @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 default mutex attributes structure. - */ -extern const pthread_mutexattr_t _POSIX_Mutex_Default_attributes; - -RTEMS_INLINE_ROUTINE Thread_Control *_POSIX_Mutex_Acquire( - POSIX_Mutex_Control *the_mutex, - Thread_queue_Context *queue_context -) -{ - ISR_Level level; - Thread_Control *executing; - - _Thread_queue_Context_initialize( queue_context ); - _Thread_queue_Context_ISR_disable( queue_context, level ); - _Thread_queue_Context_set_ISR_level( queue_context, level ); - executing = _Thread_Executing; - _Thread_queue_Queue_acquire_critical( - &the_mutex->Recursive.Mutex.Queue.Queue, - &executing->Potpourri_stats, - &queue_context->Lock_context.Lock_context - ); - - return executing; -} - -RTEMS_INLINE_ROUTINE void _POSIX_Mutex_Release( - POSIX_Mutex_Control *the_mutex, - Thread_queue_Context *queue_context -) -{ - _Thread_queue_Queue_release( - &the_mutex->Recursive.Mutex.Queue.Queue, - &queue_context->Lock_context.Lock_context - ); -} - -RTEMS_INLINE_ROUTINE POSIX_Mutex_Protocol _POSIX_Mutex_Get_protocol( - unsigned long flags -) -{ - return flags & POSIX_MUTEX_PROTOCOL_MASK; -} - -RTEMS_INLINE_ROUTINE bool _POSIX_Mutex_Is_recursive( - unsigned long flags -) -{ - return ( flags & POSIX_MUTEX_RECURSIVE ) != 0; -} - -RTEMS_INLINE_ROUTINE Thread_Control *_POSIX_Mutex_Get_owner( - const POSIX_Mutex_Control *the_mutex -) -{ - return the_mutex->Recursive.Mutex.Queue.Queue.owner; -} - -RTEMS_INLINE_ROUTINE bool _POSIX_Mutex_Is_locked( - const POSIX_Mutex_Control *the_mutex -) -{ - return _POSIX_Mutex_Get_owner( the_mutex ) != NULL; -} - -Status_Control _POSIX_Mutex_Seize_slow( - POSIX_Mutex_Control *the_mutex, - const Thread_queue_Operations *operations, - Thread_Control *executing, - const struct timespec *abstime, - Thread_queue_Context *queue_context -); - -RTEMS_INLINE_ROUTINE void _POSIX_Mutex_Set_owner( - POSIX_Mutex_Control *the_mutex, - Thread_Control *owner -) -{ - the_mutex->Recursive.Mutex.Queue.Queue.owner = owner; -} - -RTEMS_INLINE_ROUTINE bool _POSIX_Mutex_Is_owner( - const POSIX_Mutex_Control *the_mutex, - const Thread_Control *the_thread -) -{ - return _POSIX_Mutex_Get_owner( the_mutex ) == the_thread; -} - -static Status_Control _POSIX_Mutex_Lock_nested( - POSIX_Mutex_Control *the_mutex, - unsigned long flags -) -{ - - if ( _POSIX_Mutex_Is_recursive( flags ) ) { - ++the_mutex->Recursive.nest_level; - return STATUS_SUCCESSFUL; - } else { - return STATUS_NESTING_NOT_ALLOWED; - } -} - -RTEMS_INLINE_ROUTINE Status_Control _POSIX_Mutex_Seize( - POSIX_Mutex_Control *the_mutex, - unsigned long flags, - const Thread_queue_Operations *operations, - Thread_Control *executing, - const struct timespec *abstime, - Thread_queue_Context *queue_context -) -{ - Thread_Control *owner; - - owner = _POSIX_Mutex_Get_owner( the_mutex ); - - if ( owner == NULL ) { - _POSIX_Mutex_Set_owner( the_mutex, executing ); - _Thread_Resource_count_increment( executing ); - _POSIX_Mutex_Release( the_mutex, queue_context ); - return STATUS_SUCCESSFUL; - } - - if ( owner == executing ) { - Status_Control status; - - status = _POSIX_Mutex_Lock_nested( the_mutex, flags ); - _POSIX_Mutex_Release( the_mutex, queue_context ); - return status; - } - - return _POSIX_Mutex_Seize_slow( - the_mutex, - operations, - executing, - abstime, - queue_context - ); -} - -RTEMS_INLINE_ROUTINE Status_Control _POSIX_Mutex_Surrender( - POSIX_Mutex_Control *the_mutex, - const Thread_queue_Operations *operations, - Thread_Control *executing, - Thread_queue_Context *queue_context -) -{ - unsigned int nest_level; - Thread_queue_Heads *heads; - - if ( !_POSIX_Mutex_Is_owner( the_mutex, executing ) ) { - _POSIX_Mutex_Release( the_mutex, queue_context ); - return STATUS_NOT_OWNER; - } - - nest_level = the_mutex->Recursive.nest_level; - - if ( nest_level > 0 ) { - the_mutex->Recursive.nest_level = nest_level - 1; - _POSIX_Mutex_Release( the_mutex, queue_context ); - return STATUS_SUCCESSFUL; - } - - _Thread_Resource_count_decrement( executing ); - _POSIX_Mutex_Set_owner( the_mutex, NULL ); - - heads = the_mutex->Recursive.Mutex.Queue.Queue.heads; - - if ( heads == NULL ) { - _POSIX_Mutex_Release( the_mutex, queue_context ); - return STATUS_SUCCESSFUL; - } - - _Thread_queue_Surrender( - &the_mutex->Recursive.Mutex.Queue.Queue, - heads, - executing, - queue_context, - operations - ); - return STATUS_SUCCESSFUL; -} - -RTEMS_INLINE_ROUTINE const Scheduler_Control *_POSIX_Mutex_Get_scheduler( - const POSIX_Mutex_Control *the_mutex -) -{ -#if defined(RTEMS_SMP) - return the_mutex->scheduler; -#else - return &_Scheduler_Table[ 0 ]; -#endif -} - -RTEMS_INLINE_ROUTINE void _POSIX_Mutex_Set_priority( - POSIX_Mutex_Control *the_mutex, - Priority_Control priority_ceiling, - Thread_queue_Context *queue_context -) -{ - Thread_Control *owner; - - owner = _POSIX_Mutex_Get_owner( the_mutex ); - - if ( owner != NULL ) { - _Thread_Wait_acquire( owner, queue_context ); - _Thread_Priority_change( - owner, - &the_mutex->Priority_ceiling, - priority_ceiling, - false, - queue_context - ); - _Thread_Wait_release( owner, queue_context ); - } else { - the_mutex->Priority_ceiling.priority = priority_ceiling; - } -} - -RTEMS_INLINE_ROUTINE Priority_Control _POSIX_Mutex_Get_priority( - const POSIX_Mutex_Control *the_mutex -) -{ - return the_mutex->Priority_ceiling.priority; -} - -RTEMS_INLINE_ROUTINE Status_Control _POSIX_Mutex_Ceiling_set_owner( - POSIX_Mutex_Control *the_mutex, - Thread_Control *owner, - Thread_queue_Context *queue_context -) -{ - ISR_lock_Context lock_context; - Scheduler_Node *scheduler_node; - Per_CPU_Control *cpu_self; - - _Thread_Wait_acquire_default_critical( owner, &lock_context ); - - scheduler_node = _Thread_Scheduler_get_home_node( owner ); - - if ( - _Priority_Get_priority( &scheduler_node->Wait.Priority ) - < the_mutex->Priority_ceiling.priority - ) { - _Thread_Wait_release_default_critical( owner, &lock_context ); - _POSIX_Mutex_Release( the_mutex, queue_context ); - return STATUS_MUTEX_CEILING_VIOLATED; - } - - _POSIX_Mutex_Set_owner( the_mutex, owner ); - _Thread_Resource_count_increment( owner ); - _Thread_Priority_add( - owner, - &the_mutex->Priority_ceiling, - queue_context - ); - _Thread_Wait_release_default_critical( owner, &lock_context ); - - cpu_self = _Thread_queue_Dispatch_disable( queue_context ); - _POSIX_Mutex_Release( the_mutex, queue_context ); - _Thread_Priority_update( queue_context ); - _Thread_Dispatch_enable( cpu_self ); - return STATUS_SUCCESSFUL; -} - -RTEMS_INLINE_ROUTINE Status_Control _POSIX_Mutex_Ceiling_seize( - POSIX_Mutex_Control *the_mutex, - unsigned long flags, - Thread_Control *executing, - const struct timespec *abstime, - Thread_queue_Context *queue_context -) -{ - Thread_Control *owner; - - owner = _POSIX_Mutex_Get_owner( the_mutex ); - - if ( owner == NULL ) { -#if defined(RTEMS_SMP) - if ( - _Thread_Scheduler_get_home( executing ) - != _POSIX_Mutex_Get_scheduler( the_mutex ) - ) { - _POSIX_Mutex_Release( the_mutex, queue_context ); - return STATUS_NOT_DEFINED; - } -#endif - - _Thread_queue_Context_clear_priority_updates( queue_context ); - return _POSIX_Mutex_Ceiling_set_owner( - the_mutex, - executing, - queue_context - ); - } - - if ( owner == executing ) { - Status_Control status; - - status = _POSIX_Mutex_Lock_nested( the_mutex, flags ); - _POSIX_Mutex_Release( the_mutex, queue_context ); - return status; - } - - return _POSIX_Mutex_Seize_slow( - the_mutex, - POSIX_MUTEX_PRIORITY_CEILING_TQ_OPERATIONS, - executing, - abstime, - queue_context - ); -} - -RTEMS_INLINE_ROUTINE Status_Control _POSIX_Mutex_Ceiling_surrender( - POSIX_Mutex_Control *the_mutex, - Thread_Control *executing, - Thread_queue_Context *queue_context -) -{ - unsigned int nest_level; - ISR_lock_Context lock_context; - Per_CPU_Control *cpu_self; - Thread_queue_Heads *heads; - - if ( !_POSIX_Mutex_Is_owner( the_mutex, executing ) ) { - _POSIX_Mutex_Release( the_mutex, queue_context ); - return STATUS_NOT_OWNER; - } - - nest_level = the_mutex->Recursive.nest_level; - - if ( nest_level > 0 ) { - the_mutex->Recursive.nest_level = nest_level - 1; - _POSIX_Mutex_Release( the_mutex, queue_context ); - return STATUS_SUCCESSFUL; - } - - _Thread_Resource_count_decrement( executing ); - - _Thread_queue_Context_clear_priority_updates( queue_context ); - _Thread_Wait_acquire_default_critical( executing, &lock_context ); - _Thread_Priority_remove( - executing, - &the_mutex->Priority_ceiling, - queue_context - ); - _Thread_Wait_release_default_critical( executing, &lock_context ); - - cpu_self = _Thread_queue_Dispatch_disable( queue_context ); - - heads = the_mutex->Recursive.Mutex.Queue.Queue.heads; - - if ( heads != NULL ) { - const Thread_queue_Operations *operations; - Thread_Control *new_owner; - - operations = POSIX_MUTEX_PRIORITY_CEILING_TQ_OPERATIONS; - new_owner = ( *operations->first )( heads ); - _POSIX_Mutex_Set_owner( the_mutex, new_owner ); - _Thread_Resource_count_increment( new_owner ); - _Thread_Priority_add( - new_owner, - &the_mutex->Priority_ceiling, - queue_context - ); - _Thread_queue_Extract_critical( - &the_mutex->Recursive.Mutex.Queue.Queue, - operations, - new_owner, - queue_context - ); - } else { - _POSIX_Mutex_Set_owner( the_mutex, NULL ); - _POSIX_Mutex_Release( the_mutex, queue_context ); - } - - _Thread_Priority_update( queue_context ); - _Thread_Dispatch_enable( cpu_self ); - return STATUS_SUCCESSFUL; -} - -#define POSIX_MUTEX_ABSTIME_TRY_LOCK ((uintptr_t) 1) - -int _POSIX_Mutex_Lock_support( - pthread_mutex_t *mutex, - const struct timespec *abstime, - Thread_queue_Enqueue_callout enqueue_callout -); - -static inline POSIX_Mutex_Control *_POSIX_Mutex_Get( - pthread_mutex_t *mutex -) -{ - return (POSIX_Mutex_Control *) mutex; -} - -bool _POSIX_Mutex_Auto_initialization( POSIX_Mutex_Control *the_mutex ); - -#define POSIX_MUTEX_VALIDATE_OBJECT( the_mutex, flags ) \ - do { \ - if ( ( the_mutex ) == NULL ) { \ - return EINVAL; \ - } \ - flags = ( the_mutex )->flags; \ - if ( \ - ( ( (uintptr_t) ( the_mutex ) ^ POSIX_MUTEX_MAGIC ) \ - & ~POSIX_MUTEX_FLAGS_MASK ) \ - != ( flags & ~POSIX_MUTEX_FLAGS_MASK ) \ - ) { \ - if ( !_POSIX_Mutex_Auto_initialization( the_mutex ) ) { \ - return EINVAL; \ - } \ - } \ - } while ( 0 ) - -#ifdef __cplusplus -} -#endif - -#endif -/* end of include file */ - |