예제 #1
0
파일: init.c 프로젝트: greenmeent/rtems
static void release_semaphore(rtems_id timer, void *arg)
{
  /* The arg is NULL */
  test_context *ctx = &ctx_instance;
  rtems_status_code sc;

  if (
    _Thread_Wait_flags_get(ctx->main_task_control)
      == (THREAD_WAIT_CLASS_OBJECT | THREAD_WAIT_STATE_INTEND_TO_BLOCK)
  ) {
    CORE_semaphore_Control *sem;

    ctx->done = true;

    sc = rtems_semaphore_release(ctx->semaphore_id);
    rtems_test_assert(sc == RTEMS_SUCCESSFUL);

    rtems_test_assert(
      _Thread_Wait_flags_get(ctx->main_task_control)
        == (THREAD_WAIT_CLASS_OBJECT | THREAD_WAIT_STATE_READY_AGAIN)
    );
    sem = &ctx->semaphore_control->Core_control.Semaphore;
    rtems_test_assert(sem->count == 0);
  } else {
    sc = rtems_semaphore_release(ctx->semaphore_id);
    rtems_test_assert(sc == RTEMS_SUCCESSFUL);
  }
}
예제 #2
0
파일: init.c 프로젝트: Dipupo/rtems
static void any_satisfy_before_timeout(rtems_id timer, void *arg)
{
  rtems_status_code sc;
  test_context *ctx = arg;
  Thread_Control *thread = ctx->thread;
  Thread_Wait_flags flags = _Thread_Wait_flags_get(thread);

  if (blocks_for_event(flags)) {
    ctx->hit = interrupts_blocking_op(flags);

    rtems_test_assert(
      *(rtems_event_set *) thread->Wait.return_argument == DEADBEEF
    );
    rtems_test_assert(thread->Wait.return_code == RTEMS_SUCCESSFUL);

    sc = rtems_event_send(thread->Object.id, GREEN);
    rtems_test_assert(sc == RTEMS_SUCCESSFUL);

    rtems_test_assert(
      *(rtems_event_set *) thread->Wait.return_argument == GREEN
    );
    rtems_test_assert(thread->Wait.return_code == RTEMS_SUCCESSFUL);

    sc = rtems_event_send(thread->Object.id, RED);
    rtems_test_assert(sc == RTEMS_SUCCESSFUL);

    rtems_test_assert(
      *(rtems_event_set *) thread->Wait.return_argument == GREEN
    );
    rtems_test_assert(thread->Wait.return_code == RTEMS_SUCCESSFUL);

    _Thread_Timeout(&thread->Timer.Watchdog);

    rtems_test_assert(
      *(rtems_event_set *) thread->Wait.return_argument == GREEN
    );
    rtems_test_assert(thread->Wait.return_code == RTEMS_SUCCESSFUL);

    if (ctx->hit) {
      rtems_test_assert(
        _Thread_Wait_flags_get(thread)
          == (THREAD_WAIT_CLASS_EVENT | THREAD_WAIT_STATE_READY_AGAIN)
      );
    }

    rtems_test_assert(thread->Wait.count == EVENTS);
  }

  sc = rtems_timer_reset(timer);
  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
}
예제 #3
0
파일: init.c 프로젝트: Avanznow/rtems
static bool interrupts_blocking_op(void)
{
  Thread_Wait_flags flags = _Thread_Wait_flags_get( thread );

  return
    flags == ( THREAD_WAIT_CLASS_OBJECT | THREAD_WAIT_STATE_INTEND_TO_BLOCK );
}
예제 #4
0
static bool _Thread_queue_Make_ready_again( Thread_Control *the_thread )
{
    bool success;
    bool unblock;

    /*
     * We must update the wait flags under protection of the current thread lock,
     * otherwise a _Thread_Timeout() running on another processor may interfere.
     */
    success = _Thread_Wait_flags_try_change_release(
                  the_thread,
                  THREAD_QUEUE_INTEND_TO_BLOCK,
                  THREAD_QUEUE_READY_AGAIN
              );
    if ( success ) {
        unblock = false;
    } else {
        _Assert( _Thread_Wait_flags_get( the_thread ) == THREAD_QUEUE_BLOCKED );
        _Thread_Wait_flags_set( the_thread, THREAD_QUEUE_READY_AGAIN );
        unblock = true;
    }

    _Thread_Wait_restore_default( the_thread );
    return unblock;
}
예제 #5
0
void _Rate_monotonic_Timeout( Watchdog_Control *the_watchdog )
{
  Rate_monotonic_Control *the_period;
  Thread_Control         *owner;
  ISR_lock_Context        lock_context;
  Thread_Wait_flags       wait_flags;

  the_period = RTEMS_CONTAINER_OF( the_watchdog, Rate_monotonic_Control, Timer );
  owner = the_period->owner;

  _ISR_lock_ISR_disable( &lock_context );
  _Rate_monotonic_Acquire_critical( the_period, &lock_context );
  wait_flags = _Thread_Wait_flags_get( owner );

  if (
    ( wait_flags & THREAD_WAIT_CLASS_PERIOD ) != 0
      && owner->Wait.return_argument == the_period
  ) {
    bool unblock;
    bool success;

    owner->Wait.return_argument = NULL;

    success = _Thread_Wait_flags_try_change_release(
      owner,
      RATE_MONOTONIC_INTEND_TO_BLOCK,
      RATE_MONOTONIC_READY_AGAIN
    );
    if ( success ) {
      unblock = false;
    } else {
      _Assert( _Thread_Wait_flags_get( owner ) == RATE_MONOTONIC_BLOCKED );
      _Thread_Wait_flags_set( owner, RATE_MONOTONIC_READY_AGAIN );
      unblock = true;
    }

    _Rate_monotonic_Restart( the_period, owner, &lock_context );

    if ( unblock ) {
      _Thread_Unblock( owner );
    }
  } else {
    _Rate_monotonic_Renew_deadline( the_period, &lock_context );
  }
}
예제 #6
0
bool _Thread_queue_Do_extract_locked(
  Thread_queue_Queue            *queue,
  const Thread_queue_Operations *operations,
  Thread_Control                *the_thread
#if defined(RTEMS_MULTIPROCESSING)
  ,
  const Thread_queue_Context    *queue_context
#endif
)
{
  bool success;
  bool unblock;

#if defined(RTEMS_MULTIPROCESSING)
  if ( !_Objects_Is_local_id( the_thread->Object.id ) ) {
    Thread_Proxy_control    *the_proxy;
    Thread_queue_MP_callout  mp_callout;

    the_proxy = (Thread_Proxy_control *) the_thread;
    mp_callout = queue_context->mp_callout;
    _Assert( mp_callout != NULL );
    the_proxy->thread_queue_callout = queue_context->mp_callout;
  }
#endif

  ( *operations->extract )( queue, the_thread );

  /*
   * We must update the wait flags under protection of the current thread lock,
   * otherwise a _Thread_Timeout() running on another processor may interfere.
   */
  success = _Thread_Wait_flags_try_change_release(
    the_thread,
    THREAD_QUEUE_INTEND_TO_BLOCK,
    THREAD_QUEUE_READY_AGAIN
  );
  if ( success ) {
    unblock = false;
  } else {
    _Assert( _Thread_Wait_flags_get( the_thread ) == THREAD_QUEUE_BLOCKED );
    _Thread_Wait_flags_set( the_thread, THREAD_QUEUE_READY_AGAIN );
    unblock = true;
  }

  _Thread_Wait_restore_default( the_thread );

  return unblock;
}
예제 #7
0
static rtems_status_code _Rate_monotonic_Block_while_active(
  Rate_monotonic_Control *the_period,
  rtems_interval          length,
  Thread_Control         *executing,
  ISR_lock_Context       *lock_context
)
{
  Per_CPU_Control *cpu_self;
  bool             success;

  /*
   *  Update statistics from the concluding period.
   */
  _Rate_monotonic_Update_statistics( the_period );

  /*
   *  This tells the _Rate_monotonic_Timeout that this task is
   *  in the process of blocking on the period and that we
   *  may be changing the length of the next period.
   */
  the_period->next_length = length;
  executing->Wait.return_argument = the_period;
  _Thread_Wait_flags_set( executing, RATE_MONOTONIC_INTEND_TO_BLOCK );

  cpu_self = _Thread_Dispatch_disable_critical( lock_context );
  _Rate_monotonic_Release( the_period, lock_context );

  _Thread_Set_state( executing, STATES_WAITING_FOR_PERIOD );

  success = _Thread_Wait_flags_try_change_acquire(
    executing,
    RATE_MONOTONIC_INTEND_TO_BLOCK,
    RATE_MONOTONIC_BLOCKED
  );
  if ( !success ) {
    _Assert(
      _Thread_Wait_flags_get( executing ) == RATE_MONOTONIC_READY_AGAIN
    );
    _Thread_Unblock( executing );
  }

  _Thread_Dispatch_enable( cpu_self );
  return RTEMS_SUCCESSFUL;
}
예제 #8
0
파일: init.c 프로젝트: Avanznow/rtems
static bool is_case_hit( void )
{
  return _Thread_Wait_flags_get( main_thread)
    == ( THREAD_WAIT_CLASS_EVENT | THREAD_WAIT_STATE_INTEND_TO_BLOCK );
}
예제 #9
0
파일: init.c 프로젝트: Avanznow/rtems
static bool is_interrupt_timeout(void)
{
  Thread_Wait_flags flags = _Thread_Wait_flags_get( thread );

  return flags == ( THREAD_WAIT_CLASS_OBJECT | THREAD_WAIT_STATE_READY_AGAIN );
}
예제 #10
0
static void _POSIX_signals_Action_handler(
  Thread_Control   *executing,
  Thread_Action    *action,
  ISR_lock_Context *lock_context
)
{
  POSIX_API_Control *api;
  int                signo;
  uint32_t           hold_errno;

  (void) action;
  _Thread_State_release( executing, lock_context );

  api = executing->API_Extensions[ THREAD_API_POSIX ];

  /*
   *  We need to ensure that if the signal handler executes a call
   *  which overwrites the unblocking status, we restore it.
   */
  hold_errno = executing->Wait.return_code;

  /*
   * api may be NULL in case of a thread close in progress
   */
  if ( !api )
    return;

  /*
   *  In case the executing thread is blocked or about to block on something
   *  that uses the thread wait information, then this is a kernel bug.
   */
  _Assert(
    ( _Thread_Wait_flags_get( executing )
      & ( THREAD_WAIT_STATE_BLOCKED | THREAD_WAIT_STATE_INTEND_TO_BLOCK ) ) == 0
  );

  /*
   *  If we invoke any user code, there is the possibility that
   *  a new signal has been posted that we should process so we
   *  restart the loop if a signal handler was invoked.
   *
   *  The first thing done is to check there are any signals to be
   *  processed at all.  No point in doing this loop otherwise.
   */
  while (1) {
    Thread_queue_Context queue_context;

    _Thread_queue_Context_initialize( &queue_context );
    _POSIX_signals_Acquire( &queue_context );
      if ( !(api->signals_unblocked &
            (api->signals_pending | _POSIX_signals_Pending)) ) {
       _POSIX_signals_Release( &queue_context );
       break;
     }
    _POSIX_signals_Release( &queue_context );

    for ( signo = SIGRTMIN ; signo <= SIGRTMAX ; signo++ ) {
      _POSIX_signals_Check_signal( api, signo, false );
      _POSIX_signals_Check_signal( api, signo, true );
    }
    /* Unfortunately - nothing like __SIGFIRSTNOTRT in newlib signal .h */

    for ( signo = SIGHUP ; signo <= __SIGLASTNOTRT ; signo++ ) {
      _POSIX_signals_Check_signal( api, signo, false );
      _POSIX_signals_Check_signal( api, signo, true );
    }
  }

  executing->Wait.return_code = hold_errno;
}