rtems_status_code rtems_semaphore_flush( rtems_id id ) { Semaphore_Control *the_semaphore; Thread_queue_Context queue_context; the_semaphore = _Semaphore_Get( id, &queue_context ); if ( the_semaphore == NULL ) { #if defined(RTEMS_MULTIPROCESSING) if ( _Semaphore_MP_Is_remote( id ) ) { return RTEMS_ILLEGAL_ON_REMOTE_OBJECT; } #endif return RTEMS_INVALID_ID; } _Thread_queue_Acquire_critical( &the_semaphore->Core_control.Wait_queue, &queue_context ); _Thread_queue_Context_set_MP_callout( &queue_context, _Semaphore_MP_Send_object_was_deleted ); switch ( the_semaphore->variant ) { #if defined(RTEMS_SMP) case SEMAPHORE_VARIANT_MRSP: _Thread_queue_Release( &the_semaphore->Core_control.Wait_queue, &queue_context ); return RTEMS_NOT_DEFINED; #endif default: _Assert( the_semaphore->variant == SEMAPHORE_VARIANT_MUTEX_INHERIT_PRIORITY || the_semaphore->variant == SEMAPHORE_VARIANT_MUTEX_PRIORITY_CEILING || the_semaphore->variant == SEMAPHORE_VARIANT_MUTEX_NO_PROTOCOL || the_semaphore->variant == SEMAPHORE_VARIANT_SIMPLE_BINARY || the_semaphore->variant == SEMAPHORE_VARIANT_COUNTING ); _Thread_queue_Flush_critical( &the_semaphore->Core_control.Wait_queue.Queue, _Semaphore_Get_operations( the_semaphore ), _Thread_queue_Flush_status_unavailable, &queue_context ); break; } return RTEMS_SUCCESSFUL; }
Status_Control _CORE_RWLock_Surrender( CORE_RWLock_Control *the_rwlock, Thread_queue_Context *queue_context ) { /* * If unlocked, then OK to read. * Otherwise, we have to block. * If locked for reading and no waiters, then OK to read. * If any thread is waiting, then we wait. */ _CORE_RWLock_Acquire_critical( the_rwlock, queue_context ); if ( the_rwlock->current_state == CORE_RWLOCK_UNLOCKED){ /* This is an error at the caller site */ _CORE_RWLock_Release( the_rwlock, queue_context ); return STATUS_SUCCESSFUL; } if ( the_rwlock->current_state == CORE_RWLOCK_LOCKED_FOR_READING ) { the_rwlock->number_of_readers -= 1; if ( the_rwlock->number_of_readers != 0 ) { /* must be unlocked again */ _CORE_RWLock_Release( the_rwlock, queue_context ); return STATUS_SUCCESSFUL; } } _Assert( the_rwlock->current_state == CORE_RWLOCK_LOCKED_FOR_WRITING || ( the_rwlock->current_state == CORE_RWLOCK_LOCKED_FOR_READING && the_rwlock->number_of_readers == 0 ) ); /* * Implicitly transition to "unlocked" and find another thread interested * in obtaining this rwlock. */ the_rwlock->current_state = CORE_RWLOCK_UNLOCKED; _Thread_queue_Flush_critical( &the_rwlock->Wait_queue.Queue, CORE_RWLOCK_TQ_OPERATIONS, _CORE_RWLock_Flush_filter, queue_context ); return STATUS_SUCCESSFUL; }
uint32_t _CORE_barrier_Do_surrender( CORE_barrier_Control *the_barrier, Thread_queue_Flush_filter filter, #if defined(RTEMS_MULTIPROCESSING) Thread_queue_MP_callout mp_callout, Objects_Id mp_id, #endif ISR_lock_Context *lock_context ) { the_barrier->number_of_waiting_threads = 0; return _Thread_queue_Flush_critical( &the_barrier->Wait_queue.Queue, CORE_BARRIER_TQ_OPERATIONS, filter, mp_callout, mp_id, lock_context ); }
static void _Thread_Wake_up_joining_threads( Thread_Control *the_thread ) { Thread_Join_context join_context; #if defined(RTEMS_POSIX_API) join_context.exit_value = the_thread->Life.exit_value; #endif _Thread_queue_Context_initialize( &join_context.Base ); _Thread_queue_Acquire( &the_thread->Join_queue, &join_context.Base ); _Thread_queue_Flush_critical( &the_thread->Join_queue.Queue, THREAD_JOIN_TQ_OPERATIONS, #if defined(RTEMS_POSIX_API) _Thread_Join_flush_filter, #else _Thread_queue_Flush_default_filter, #endif &join_context.Base ); }
void _CORE_message_queue_Close( CORE_message_queue_Control *the_message_queue, Thread_queue_Context *queue_context ) { /* * This will flush blocked threads whether they were blocked on * a send or receive. */ _Thread_queue_Flush_critical( &the_message_queue->Wait_queue.Queue, the_message_queue->operations, _CORE_message_queue_Was_deleted, queue_context ); (void) _Workspace_Free( the_message_queue->message_buffers ); _Thread_queue_Destroy( &the_message_queue->Wait_queue ); }
rtems_status_code rtems_semaphore_delete( rtems_id id ) { Semaphore_Control *the_semaphore; Thread_queue_Context queue_context; Status_Control status; _Objects_Allocator_lock(); the_semaphore = _Semaphore_Get( id, &queue_context ); if ( the_semaphore == NULL ) { _Objects_Allocator_unlock(); #if defined(RTEMS_MULTIPROCESSING) if ( _Semaphore_MP_Is_remote( id ) ) { return RTEMS_ILLEGAL_ON_REMOTE_OBJECT; } #endif return RTEMS_INVALID_ID; } _Thread_queue_Acquire_critical( &the_semaphore->Core_control.Wait_queue, &queue_context.Lock_context ); switch ( the_semaphore->variant ) { case SEMAPHORE_VARIANT_MUTEX_INHERIT_PRIORITY: case SEMAPHORE_VARIANT_MUTEX_PRIORITY_CEILING: 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; } break; #if defined(RTEMS_SMP) case SEMAPHORE_VARIANT_MRSP: status = _MRSP_Can_destroy( &the_semaphore->Core_control.MRSP ); break; #endif default: _Assert( the_semaphore->variant == SEMAPHORE_VARIANT_SIMPLE_BINARY || the_semaphore->variant == SEMAPHORE_VARIANT_COUNTING ); status = STATUS_SUCCESSFUL; break; } if ( status != STATUS_SUCCESSFUL ) { _Thread_queue_Release( &the_semaphore->Core_control.Wait_queue, &queue_context.Lock_context ); _Objects_Allocator_unlock(); return _Status_Get( status ); } _Objects_Close( &_Semaphore_Information, &the_semaphore->Object ); switch ( the_semaphore->variant ) { #if defined(RTEMS_SMP) case SEMAPHORE_VARIANT_MRSP: _MRSP_Destroy( &the_semaphore->Core_control.MRSP, &queue_context ); break; #endif default: _Assert( the_semaphore->variant == SEMAPHORE_VARIANT_MUTEX_INHERIT_PRIORITY || the_semaphore->variant == SEMAPHORE_VARIANT_MUTEX_PRIORITY_CEILING || the_semaphore->variant == SEMAPHORE_VARIANT_MUTEX_NO_PROTOCOL || the_semaphore->variant == SEMAPHORE_VARIANT_SIMPLE_BINARY || the_semaphore->variant == SEMAPHORE_VARIANT_COUNTING ); _Thread_queue_Flush_critical( &the_semaphore->Core_control.Wait_queue.Queue, _Semaphore_Get_operations( the_semaphore ), _Thread_queue_Flush_status_object_was_deleted, &queue_context ); _Thread_queue_Destroy( &the_semaphore->Core_control.Wait_queue ); break; } #if defined(RTEMS_MULTIPROCESSING) if ( the_semaphore->is_global ) { _Objects_MP_Close( &_Semaphore_Information, id ); _Semaphore_MP_Send_process_packet( SEMAPHORE_MP_ANNOUNCE_DELETE, id, 0, /* Not used */ 0 /* Not used */ ); } #endif _Semaphore_Free( the_semaphore ); _Objects_Allocator_unlock(); return RTEMS_SUCCESSFUL; }