コード例 #1
0
ファイル: threadrestart.c プロジェクト: Avanznow/rtems
static void _Thread_Make_zombie( Thread_Control *the_thread )
{
  ISR_lock_Context lock_context;
  Thread_Zombie_control *zombies = &_Thread_Zombies;

  if ( _Thread_Owns_resources( the_thread ) ) {
    _Terminate(
      INTERNAL_ERROR_CORE,
      false,
      INTERNAL_ERROR_RESOURCE_IN_USE
    );
  }

  _Objects_Close(
    _Objects_Get_information_id( the_thread->Object.id ),
    &the_thread->Object
  );

  _Thread_Set_state( the_thread, STATES_ZOMBIE );
  _Thread_queue_Extract_with_proxy( the_thread );
  _Watchdog_Remove_ticks( &the_thread->Timer );

  _ISR_lock_ISR_disable_and_acquire( &zombies->Lock, &lock_context );
  _Chain_Append_unprotected( &zombies->Chain, &the_thread->Object.Node );
  _ISR_lock_Release_and_ISR_enable( &zombies->Lock, &lock_context );
}
コード例 #2
0
static void _Thread_Make_zombie( Thread_Control *the_thread )
{
  if ( _Thread_Owns_resources( the_thread ) ) {
    _Terminate(
      INTERNAL_ERROR_CORE,
      false,
      INTERNAL_ERROR_RESOURCE_IN_USE
    );
  }

  _Objects_Close(
    _Objects_Get_information_id( the_thread->Object.id ),
    &the_thread->Object
  );

  _Thread_Set_state( the_thread, STATES_ZOMBIE );
  _Thread_queue_Extract_with_proxy( the_thread );
  _Thread_Timer_remove( the_thread );

  /*
   * Add the thread to the thread zombie chain before we wake up joining
   * threads, so that they are able to clean up the thread immediately.  This
   * matters for SMP configurations.
   */
  _Thread_Add_to_zombie_chain( the_thread );

  _Thread_Wake_up_joining_threads( the_thread );
}
コード例 #3
0
static void _Thread_Make_zombie( Thread_Control *the_thread )
{
#if defined(RTEMS_SCORE_THREAD_ENABLE_RESOURCE_COUNT)
  if ( _Thread_Owns_resources( the_thread ) ) {
    _Internal_error( INTERNAL_ERROR_RESOURCE_IN_USE );
  }
#endif

  _Objects_Close(
    _Objects_Get_information_id( the_thread->Object.id ),
    &the_thread->Object
  );

  _Thread_Set_state( the_thread, STATES_ZOMBIE );
  _Thread_queue_Extract_with_proxy( the_thread );
  _Thread_Timer_remove( the_thread );

  /*
   * Add the thread to the thread zombie chain before we wake up joining
   * threads, so that they are able to clean up the thread immediately.  This
   * matters for SMP configurations.
   */
  _Thread_Add_to_zombie_chain( the_thread );

  _Thread_Wake_up_joining_threads( the_thread );
}
コード例 #4
0
static void _Thread_Finalize_life_change(
  Thread_Control   *the_thread,
  Priority_Control  priority
)
{
  _Thread_queue_Extract_with_proxy( the_thread );
  _Thread_Timer_remove( the_thread );
  _Thread_Raise_real_priority( the_thread, priority );
  _Thread_Remove_life_change_request( the_thread );
}
コード例 #5
0
ファイル: threadrestart.c プロジェクト: Fyleo/rtems
static void _Thread_Start_life_change(
  Thread_Control          *the_thread,
  const Scheduler_Control *scheduler,
  Priority_Control         priority
)
{
  the_thread->is_preemptible   = the_thread->Start.is_preemptible;
  the_thread->budget_algorithm = the_thread->Start.budget_algorithm;
  the_thread->budget_callout   = the_thread->Start.budget_callout;
  the_thread->real_priority    = priority;

  _Thread_Set_state( the_thread, STATES_RESTARTING );
  _Thread_queue_Extract_with_proxy( the_thread );
  _Watchdog_Remove( &the_thread->Timer );
  _Scheduler_Set_priority_if_higher( scheduler, the_thread, priority );
  _Thread_Add_post_switch_action( the_thread, &the_thread->Life.Action );
  _Thread_Ready( the_thread );
  _Thread_Request_dispatch_if_executing( the_thread );
}
コード例 #6
0
ファイル: threadrestart.c プロジェクト: Avanznow/rtems
static void _Thread_Start_life_change(
  Thread_Control          *the_thread,
  const Scheduler_Control *scheduler,
  Priority_Control         priority
)
{
  the_thread->is_preemptible   = the_thread->Start.is_preemptible;
  the_thread->budget_algorithm = the_thread->Start.budget_algorithm;
  the_thread->budget_callout   = the_thread->Start.budget_callout;

  _Thread_Set_state( the_thread, STATES_RESTARTING );
  _Thread_queue_Extract_with_proxy( the_thread );
  _Watchdog_Remove_ticks( &the_thread->Timer );
  _Thread_Change_priority(
    the_thread,
    priority,
    NULL,
    _Thread_Raise_real_priority_filter,
    false
  );
  _Thread_Add_life_change_action( the_thread );
  _Thread_Ready( the_thread );
}
コード例 #7
0
ファイル: threadclose.c プロジェクト: cloud-hot/rtems
void _Thread_Close(
  Objects_Information  *information,
  Thread_Control       *the_thread
)
{
  /*
   *  Now we are in a dispatching critical section again and we
   *  can take the thread OUT of the published set.  It is invalid
   *  to use this thread's Id after this call.  This will prevent
   *  any other task from attempting to initiate a call on this task.
   */
  _Objects_Invalidate_Id( information, &the_thread->Object );

  /*
   *  We assume the Allocator Mutex is locked when we get here.
   *  This provides sufficient protection to let the user extensions
   *  run but as soon as we get back, we will make the thread
   *  disappear and set a transient state on it.  So we temporarily
   *  unnest dispatching.
   */
  _Thread_Unnest_dispatch();

  _User_extensions_Thread_delete( the_thread );

  _Thread_Disable_dispatch();

  /*
   *  Now we are in a dispatching critical section again and we
   *  can take the thread OUT of the published set.  It is invalid
   *  to use this thread's Id OR name after this call.
   */
  _Objects_Close( information, &the_thread->Object );

  /*
   *  By setting the dormant state, the thread will not be considered
   *  for scheduling when we remove any blocking states.
   */
  _Thread_Set_state( the_thread, STATES_DORMANT );

  if ( !_Thread_queue_Extract_with_proxy( the_thread ) ) {
    if ( _Watchdog_Is_active( &the_thread->Timer ) )
      (void) _Watchdog_Remove( &the_thread->Timer );
  }

  /*
   * Free the per-thread scheduling information.
   */
  _Scheduler_Free( the_thread );

  /*
   *  The thread might have been FP.  So deal with that.
   */
#if ( CPU_HARDWARE_FP == TRUE ) || ( CPU_SOFTWARE_FP == TRUE )
#if ( CPU_USE_DEFERRED_FP_SWITCH == TRUE )
  if ( _Thread_Is_allocated_fp( the_thread ) )
    _Thread_Deallocate_fp();
#endif
  the_thread->fp_context = NULL;

  _Workspace_Free( the_thread->Start.fp_context );
#endif

  /*
   *  Free the rest of the memory associated with this task
   *  and set the associated pointers to NULL for safety.
   */
  _Thread_Stack_Free( the_thread );
  the_thread->Start.stack = NULL;

  _Workspace_Free( the_thread->extensions );
  the_thread->extensions = NULL;

  _Workspace_Free( the_thread->Start.tls_area );
}
コード例 #8
0
ファイル: psignalunblockthread.c プロジェクト: epicsdeb/rtems
/* XXX this routine could probably be cleaned up */
bool _POSIX_signals_Unblock_thread(
  Thread_Control  *the_thread,
  int              signo,
  siginfo_t       *info
)
{
  POSIX_API_Control  *api;
  sigset_t            mask;
  siginfo_t          *the_info = NULL;

  api = the_thread->API_Extensions[ THREAD_API_POSIX ];

  mask = signo_to_mask( signo );

  /*
   *  Is the thread is specifically waiting for a signal?
   */

  if ( _States_Is_interruptible_signal( the_thread->current_state ) ) {

    if ( (the_thread->Wait.option & mask) || (~api->signals_blocked & mask) ) {
      the_thread->Wait.return_code = EINTR;

      the_info = (siginfo_t *) the_thread->Wait.return_argument;

      if ( !info ) {
        the_info->si_signo = signo;
        the_info->si_code = SI_USER;
        the_info->si_value.sival_int = 0;
      } else {
        *the_info = *info;
      }

      _Thread_queue_Extract_with_proxy( the_thread );
      return true;
    }

    /*
     *  This should only be reached via pthread_kill().
     */

    return false;
  }

  /*
   *  Thread is not waiting due to a sigwait.
   */
  if ( ~api->signals_blocked & mask ) {

    /*
     *  The thread is interested in this signal.  We are going
     *  to post it.  We have a few broad cases:
     *    + If it is blocked on an interruptible signal, THEN
     *        we unblock the thread.
     *    + If it is in the ready state AND
     *      we are sending from an ISR AND
     *      it is the interrupted thread AND
     *      it is not blocked, THEN
     *        we need to dispatch at the end of this ISR.
     *    + Any other combination, do nothing.
     */

    the_thread->do_post_task_switch_extension = true;

    if ( _States_Is_interruptible_by_signal( the_thread->current_state ) ) {
      the_thread->Wait.return_code = EINTR;
      /*
       *  In pthread_cond_wait, a thread will be blocking on a thread
       *  queue, but is also interruptible by a POSIX signal.
       */
      if ( _States_Is_waiting_on_thread_queue(the_thread->current_state) )
        _Thread_queue_Extract_with_proxy( the_thread );
      else if ( _States_Is_delaying(the_thread->current_state) ){
	(void) _Watchdog_Remove( &the_thread->Timer );
        _Thread_Unblock( the_thread );
      }

    } else if ( the_thread->current_state == STATES_READY ) {
      if ( _ISR_Is_in_progress() && _Thread_Is_executing( the_thread ) )
	_ISR_Signals_to_thread_executing = true;
    }
  }
  return false;
}
コード例 #9
0
/* XXX this routine could probably be cleaned up */
boolean _POSIX_signals_Unblock_thread(
  Thread_Control  *the_thread,
  int              signo,
  siginfo_t       *info
)
{
  POSIX_API_Control  *api;
  sigset_t            mask;
  siginfo_t          *the_info = NULL;

  api = the_thread->API_Extensions[ THREAD_API_POSIX ];

  mask = signo_to_mask( signo );

  /*
   *  Is the thread is specifically waiting for a signal?
   */

  if ( _States_Is_interruptible_signal( the_thread->current_state ) ) {

    if ( (the_thread->Wait.option & mask) || (~api->signals_blocked & mask) ) {
      the_thread->Wait.return_code = EINTR;

      the_info = (siginfo_t *) the_thread->Wait.return_argument;

      if ( !info ) {
        the_info->si_signo = signo;
        the_info->si_code = SI_USER;
        the_info->si_value.sival_int = 0;
      } else {
        *the_info = *info;
      }

      _Thread_queue_Extract_with_proxy( the_thread );
      return TRUE;
    }

    /*
     *  This should only be reached via pthread_kill().
     */

    return FALSE;
  }

  if ( ~api->signals_blocked & mask ) {
    the_thread->do_post_task_switch_extension = TRUE;

    if ( the_thread->current_state & STATES_INTERRUPTIBLE_BY_SIGNAL ) {
      the_thread->Wait.return_code = EINTR;
      if ( _States_Is_waiting_on_thread_queue(the_thread->current_state) )
        _Thread_queue_Extract_with_proxy( the_thread );
      else if ( _States_Is_delaying(the_thread->current_state)){
        if ( _Watchdog_Is_active( &the_thread->Timer ) )
          (void) _Watchdog_Remove( &the_thread->Timer );
        _Thread_Unblock( the_thread );
      }
    }
  }
  return FALSE;

}
コード例 #10
0
ファイル: psignalunblockthread.c プロジェクト: AoLaD/rtems
bool _POSIX_signals_Unblock_thread(
  Thread_Control  *the_thread,
  int              signo,
  siginfo_t       *info
)
{
  POSIX_API_Control  *api;
  sigset_t            mask;
  siginfo_t          *the_info = NULL;

  api = the_thread->API_Extensions[ THREAD_API_POSIX ];

  mask = signo_to_mask( signo );

  /*
   *  Is the thread is specifically waiting for a signal?
   */

  if ( _States_Is_interruptible_signal( the_thread->current_state ) ) {

    if ( (the_thread->Wait.option & mask) || (api->signals_unblocked & mask) ) {
      the_thread->Wait.return_code = STATUS_INTERRUPTED;

      the_info = (siginfo_t *) the_thread->Wait.return_argument;

      if ( !info ) {
        the_info->si_signo = signo;
        the_info->si_code = SI_USER;
        the_info->si_value.sival_int = 0;
      } else {
        *the_info = *info;
      }

      _Thread_queue_Extract_with_proxy( the_thread );
      return _POSIX_signals_Unblock_thread_done( the_thread, api, true );
    }

    /*
     *  This should only be reached via pthread_kill().
     */

    return _POSIX_signals_Unblock_thread_done( the_thread, api, false );
  }

  /*
   *  Thread is not waiting due to a sigwait.
   */
  if ( api->signals_unblocked & mask ) {

    /*
     *  The thread is interested in this signal.  We are going
     *  to post it.  We have a few broad cases:
     *    + If it is blocked on an interruptible signal, THEN
     *        we unblock the thread.
     *    + If it is in the ready state AND
     *      we are sending from an ISR AND
     *      it is the interrupted thread AND
     *      it is not blocked, THEN
     *        we need to dispatch at the end of this ISR.
     *    + Any other combination, do nothing.
     */

    if ( _States_Is_interruptible_by_signal( the_thread->current_state ) ) {
      the_thread->Wait.return_code = STATUS_INTERRUPTED;
      _Thread_queue_Extract_with_proxy( the_thread );
    }
  }
  return _POSIX_signals_Unblock_thread_done( the_thread, api, false );
}