Esempio n. 1
0
static void _Mutex_Acquire_slow(
  Mutex_Control        *mutex,
  Thread_Control       *owner,
  Thread_Control       *executing,
  ISR_Level             level,
  Thread_queue_Context *queue_context
)
{
  _Thread_queue_Context_set_thread_state(
    queue_context,
    STATES_WAITING_FOR_SYS_LOCK_MUTEX
  );
  _Thread_queue_Context_set_do_nothing_enqueue_callout( queue_context );
  _Thread_queue_Context_set_deadlock_callout(
    queue_context,
    _Thread_queue_Deadlock_fatal
  );
  _Thread_queue_Context_set_ISR_level( queue_context, level );
  _Thread_queue_Enqueue(
    &mutex->Queue.Queue,
    MUTEX_TQ_OPERATIONS,
    executing,
    queue_context
  );
}
Esempio n. 2
0
static void _Mutex_Release_critical(
  Mutex_Control        *mutex,
  Thread_Control       *executing,
  ISR_Level             level,
  Thread_queue_Context *queue_context
)
{
  Thread_queue_Heads *heads;

  heads = mutex->Queue.Queue.heads;
  mutex->Queue.Queue.owner = NULL;
  _Thread_Resource_count_decrement( executing );

  if ( __predict_true( heads == NULL ) ) {
    _Mutex_Queue_release( mutex, level, queue_context );
  } else {
    _Thread_queue_Context_set_ISR_level( queue_context, level );
    _Thread_queue_Surrender(
      &mutex->Queue.Queue,
      heads,
      executing,
      queue_context,
      MUTEX_TQ_OPERATIONS
    );
  }
}
Esempio n. 3
0
int sem_post( sem_t *_sem )
{
  Sem_Control          *sem;
  ISR_Level             level;
  Thread_queue_Context  queue_context;
  Thread_queue_Heads   *heads;
  unsigned int          count;

  POSIX_SEMAPHORE_VALIDATE_OBJECT( _sem );

  sem = _Sem_Get( &_sem->_Semaphore );
  _Thread_queue_Context_initialize( &queue_context );
  _Thread_queue_Context_ISR_disable( &queue_context, level );
  _Sem_Queue_acquire_critical( sem, &queue_context );

  heads = sem->Queue.Queue.heads;
  count = sem->count;

  if ( __predict_true( heads == NULL && count < SEM_VALUE_MAX ) ) {
    sem->count = count + 1;
    _Sem_Queue_release( sem, level, &queue_context );
    return 0;
  }

  if ( __predict_true( heads != NULL ) ) {
    const Thread_queue_Operations *operations;
    Thread_Control *first;

    _Thread_queue_Context_set_ISR_level( &queue_context, level );
    operations = SEMAPHORE_TQ_OPERATIONS;
    first = ( *operations->first )( heads );

    _Thread_queue_Extract_critical(
      &sem->Queue.Queue,
      operations,
      first,
      &queue_context
    );
    return 0;
  }

  _Sem_Queue_release( sem, level, &queue_context );
  rtems_set_errno_and_return_minus_one( EOVERFLOW );
}