コード例 #1
0
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;
}
コード例 #2
0
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 );
  }
}
コード例 #3
0
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 ) );
  }
}
コード例 #4
0
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 );
}