int _Mutex_recursive_Try_acquire( struct _Mutex_recursive_Control *_mutex ) { Mutex_recursive_Control *mutex; Thread_queue_Context queue_context; ISR_Level level; Thread_Control *executing; Thread_Control *owner; int eno; mutex = _Mutex_recursive_Get( _mutex ); _Thread_queue_Context_initialize( &queue_context ); _Thread_queue_Context_ISR_disable( &queue_context, level ); executing = _Mutex_Queue_acquire_critical( &mutex->Mutex, &queue_context ); owner = mutex->Mutex.Queue.Queue.owner; if ( __predict_true( owner == NULL ) ) { mutex->Mutex.Queue.Queue.owner = executing; _Thread_Resource_count_increment( executing ); eno = 0; } else if ( owner == executing ) { ++mutex->nest_level; eno = 0; } else { eno = EBUSY; } _Mutex_Queue_release( &mutex->Mutex, level, &queue_context ); return eno; }
void _Mutex_recursive_Acquire( struct _Mutex_recursive_Control *_mutex ) { Mutex_recursive_Control *mutex; Thread_queue_Context queue_context; ISR_Level level; Thread_Control *executing; Thread_Control *owner; mutex = _Mutex_recursive_Get( _mutex ); _Thread_queue_Context_initialize( &queue_context ); _Thread_queue_Context_ISR_disable( &queue_context, level ); executing = _Mutex_Queue_acquire_critical( &mutex->Mutex, &queue_context ); owner = mutex->Mutex.Queue.Queue.owner; if ( __predict_true( owner == NULL ) ) { mutex->Mutex.Queue.Queue.owner = executing; _Thread_Resource_count_increment( executing ); _Mutex_Queue_release( &mutex->Mutex, level, &queue_context ); } else if ( owner == executing ) { ++mutex->nest_level; _Mutex_Queue_release( &mutex->Mutex, level, &queue_context ); } else { _Thread_queue_Context_set_no_timeout( &queue_context ); _Mutex_Acquire_slow( &mutex->Mutex, owner, executing, level, &queue_context ); } }
int _Mutex_recursive_Acquire_timed( struct _Mutex_recursive_Control *_mutex, const struct timespec *abstime ) { Mutex_recursive_Control *mutex; Thread_queue_Context queue_context; ISR_Level level; Thread_Control *executing; Thread_Control *owner; mutex = _Mutex_recursive_Get( _mutex ); _Thread_queue_Context_initialize( &queue_context ); _Thread_queue_Context_ISR_disable( &queue_context, level ); executing = _Mutex_Queue_acquire_critical( &mutex->Mutex, &queue_context ); owner = mutex->Mutex.Queue.Queue.owner; if ( __predict_true( owner == NULL ) ) { mutex->Mutex.Queue.Queue.owner = executing; _Thread_Resource_count_increment( executing ); _Mutex_Queue_release( &mutex->Mutex, level, &queue_context ); return 0; } else if ( owner == executing ) { ++mutex->nest_level; _Mutex_Queue_release( &mutex->Mutex, level, &queue_context ); return 0; } else { Watchdog_Interval ticks; switch ( _TOD_Absolute_timeout_to_ticks( abstime, CLOCK_REALTIME, &ticks ) ) { case TOD_ABSOLUTE_TIMEOUT_INVALID: _Mutex_Queue_release( &mutex->Mutex, level, &queue_context ); return EINVAL; case TOD_ABSOLUTE_TIMEOUT_IS_IN_PAST: case TOD_ABSOLUTE_TIMEOUT_IS_NOW: _Mutex_Queue_release( &mutex->Mutex, level, &queue_context ); return ETIMEDOUT; default: break; } _Thread_queue_Context_set_relative_timeout( &queue_context, ticks ); _Mutex_Acquire_slow( &mutex->Mutex, owner, executing, level, &queue_context ); return STATUS_GET_POSIX( _Thread_Wait_get_status( executing ) ); } }
void _Thread_queue_Surrender( Thread_queue_Queue *queue, Thread_queue_Heads *heads, Thread_Control *previous_owner, Thread_queue_Context *queue_context, const Thread_queue_Operations *operations ) { Thread_Control *new_owner; bool unblock; Per_CPU_Control *cpu_self; _Assert( heads != NULL ); _Thread_queue_Context_clear_priority_updates( queue_context ); new_owner = ( *operations->surrender )( queue, heads, previous_owner, queue_context ); queue->owner = new_owner; #if defined(RTEMS_MULTIPROCESSING) if ( !_Thread_queue_MP_set_callout( new_owner, queue_context ) ) #endif { _Thread_Resource_count_increment( new_owner ); } unblock = _Thread_queue_Make_ready_again( new_owner ); cpu_self = _Thread_Dispatch_disable_critical( &queue_context->Lock_context.Lock_context ); _Thread_queue_Queue_release( queue, &queue_context->Lock_context.Lock_context ); _Thread_Priority_update( queue_context ); if ( unblock ) { _Thread_Remove_timer_and_unblock( new_owner, queue ); } _Thread_Dispatch_enable( cpu_self ); }