예제 #1
0
void _CORE_barrier_Wait(
    CORE_barrier_Control                *the_barrier,
    Thread_Control                      *executing,
    Objects_Id                           id,
    bool                                 wait,
    Watchdog_Interval                    timeout,
    CORE_barrier_API_mp_support_callout  api_barrier_mp_support
)
{
    ISR_Level       level;

    executing->Wait.return_code = CORE_BARRIER_STATUS_SUCCESSFUL;
    _ISR_Disable( level );
    the_barrier->number_of_waiting_threads++;
    if ( _CORE_barrier_Is_automatic( &the_barrier->Attributes ) ) {
        if ( the_barrier->number_of_waiting_threads ==
                the_barrier->Attributes.maximum_count) {
            executing->Wait.return_code = CORE_BARRIER_STATUS_AUTOMATICALLY_RELEASED;
            _ISR_Enable( level );
            _CORE_barrier_Release( the_barrier, id, api_barrier_mp_support );
            return;
        }
    }

    _Thread_queue_Enter_critical_section( &the_barrier->Wait_queue );
    executing->Wait.queue          = &the_barrier->Wait_queue;
    executing->Wait.id             = id;
    _ISR_Enable( level );

    _Thread_queue_Enqueue( &the_barrier->Wait_queue, timeout );
}
Status_Control _CORE_barrier_Seize(
  CORE_barrier_Control *the_barrier,
  Thread_Control       *executing,
  bool                  wait,
  Watchdog_Interval     timeout,
  Thread_queue_Context *queue_context
)
{
  uint32_t number_of_waiting_threads;

  _CORE_barrier_Acquire_critical( the_barrier, queue_context );

  number_of_waiting_threads = the_barrier->number_of_waiting_threads;
  ++number_of_waiting_threads;

  if (
    _CORE_barrier_Is_automatic( &the_barrier->Attributes )
      && number_of_waiting_threads == the_barrier->Attributes.maximum_count
  ) {
    _CORE_barrier_Surrender( the_barrier, queue_context );
    return STATUS_BARRIER_AUTOMATICALLY_RELEASED;
  } else {
    the_barrier->number_of_waiting_threads = number_of_waiting_threads;
    _Thread_queue_Context_set_expected_level( queue_context, 1 );
    _Thread_queue_Enqueue_critical(
      &the_barrier->Wait_queue.Queue,
      CORE_BARRIER_TQ_OPERATIONS,
      executing,
      STATES_WAITING_FOR_BARRIER,
      timeout,
      queue_context
    );
    return _Thread_Wait_get_status( executing );
  }
}