Esempio n. 1
0
void _Semaphore_Post( struct _Semaphore_Control *_sem )
{
  Semaphore_Control    *sem;
  Thread_queue_Context  queue_context;
  Thread_queue_Heads   *heads;

  sem = _Semaphore_Get( _sem );
  _Thread_queue_Context_initialize( &queue_context );
  _Semaphore_Queue_acquire( sem, &queue_context );

  heads = sem->Queue.Queue.heads;
  if ( heads == NULL ) {
    _Assert( sem->count < UINT_MAX );
    ++sem->count;
    _Semaphore_Queue_release( sem, &queue_context );
  } else {
    const Thread_queue_Operations *operations;
    Thread_Control *first;

    operations = SEMAPHORE_TQ_OPERATIONS;
    first = ( *operations->first )( heads );

    _Thread_queue_Extract_critical(
      &sem->Queue.Queue,
      operations,
      first,
      &queue_context
    );
  }
}
Esempio n. 2
0
static void _Mutex_Release_slow(
  Mutex_Control      *mutex,
  Thread_Control     *executing,
  Thread_queue_Heads *heads,
  bool                keep_priority,
  ISR_lock_Context   *lock_context
)
{
  if (heads != NULL) {
    const Thread_queue_Operations *operations;
    Thread_Control *first;

    operations = MUTEX_TQ_OPERATIONS;
    first = ( *operations->first )( heads );

    mutex->owner = first;
    _Thread_queue_Extract_critical(
      &mutex->Queue.Queue,
      operations,
      first,
      lock_context
    );
  } else {
    _Mutex_Queue_release( mutex, lock_context);
  }

  if ( !keep_priority ) {
    Per_CPU_Control *cpu_self;

    cpu_self = _Thread_Dispatch_disable();
    _Thread_Restore_priority( executing );
    _Thread_Dispatch_enable( cpu_self );
  }
}
Esempio n. 3
0
Thread_Control *_Thread_queue_Do_dequeue(
    Thread_queue_Control          *the_thread_queue,
    const Thread_queue_Operations *operations
#if defined(RTEMS_MULTIPROCESSING)
    ,
    Thread_queue_MP_callout        mp_callout
#endif
)
{
    Thread_queue_Context  queue_context;
    Thread_Control       *the_thread;

    _Thread_queue_Context_initialize( &queue_context );
    _Thread_queue_Context_set_MP_callout( &queue_context, mp_callout );
    _Thread_queue_Acquire( the_thread_queue, &queue_context );

    the_thread = _Thread_queue_First_locked( the_thread_queue, operations );

    if ( the_thread != NULL ) {
        _Thread_queue_Extract_critical(
            &the_thread_queue->Queue,
            operations,
            the_thread,
            &queue_context
        );
    } else {
        _Thread_queue_Release( the_thread_queue, &queue_context );
    }

    return the_thread;
}
Esempio n. 4
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 );
}
Esempio n. 5
0
void _Thread_queue_Flush(
  Thread_queue_Control       *the_thread_queue,
#if defined(RTEMS_MULTIPROCESSING)
  Thread_queue_Flush_callout  remote_extract_callout,
#else
  Thread_queue_Flush_callout  remote_extract_callout RTEMS_UNUSED,
#endif
  uint32_t                    status
)
{
  ISR_lock_Context  lock_context;
  Thread_Control   *the_thread;

  _Thread_queue_Acquire( the_thread_queue, &lock_context );

  while ( (the_thread = _Thread_queue_First_locked( the_thread_queue ) ) ) {
#if defined(RTEMS_MULTIPROCESSING)
    if ( _Objects_Is_local_id( the_thread->Object.id ) )
#endif
      the_thread->Wait.return_code = status;

    _Thread_queue_Extract_critical(
      &the_thread_queue->Queue,
      the_thread_queue->operations,
      the_thread,
      &lock_context
    );

#if defined(RTEMS_MULTIPROCESSING)
    if ( !_Objects_Is_local_id( the_thread->Object.id ) )
      ( *remote_extract_callout )( the_thread );
#endif

    _Thread_queue_Acquire( the_thread_queue, &lock_context );
  }

  _Thread_queue_Release( the_thread_queue, &lock_context );
}