コード例 #1
0
rtems_status_code rtems_task_delete(
  rtems_id id
)
{
  register Thread_Control *the_thread;
  Objects_Locations        location;
  Objects_Information     *the_information;

  _RTEMS_Lock_allocator();

  the_thread = _Thread_Get( id, &location );
  switch ( location ) {

    case OBJECTS_LOCAL:
      the_information = _Objects_Get_information_id( the_thread->Object.id );

      #if defined(RTEMS_DEBUG)
	if ( !the_information ) {
	  _Thread_Enable_dispatch();
	  return RTEMS_INVALID_ID;
	  /* This should never happen if _Thread_Get() works right */
	}
      #endif

      #if defined(RTEMS_MULTIPROCESSING)
        if ( the_thread->is_global ) {
          _Objects_MP_Close( &_RTEMS_tasks_Information, the_thread->Object.id );
          _RTEMS_tasks_MP_Send_process_packet(
            RTEMS_TASKS_MP_ANNOUNCE_DELETE,
            the_thread->Object.id,
            0                                /* Not used */
          );
        }
      #endif

      _Thread_Close( the_information, the_thread );

      _RTEMS_tasks_Free( the_thread );

      _RTEMS_Unlock_allocator();
      _Thread_Enable_dispatch();
      return RTEMS_SUCCESSFUL;

#if defined(RTEMS_MULTIPROCESSING)
    case OBJECTS_REMOTE:
      _RTEMS_Unlock_allocator();
      _Thread_Dispatch();
      return RTEMS_ILLEGAL_ON_REMOTE_OBJECT;
#endif

    case OBJECTS_ERROR:
      break;
  }

  _RTEMS_Unlock_allocator();
  return RTEMS_INVALID_ID;
}
コード例 #2
0
ファイル: taskdelete.c プロジェクト: Avanznow/rtems
rtems_status_code rtems_task_delete(
  rtems_id id
)
{
  Thread_Control    *the_thread;
  Objects_Locations  location;
  bool               previous_life_protection;

  previous_life_protection = _Thread_Set_life_protection( true );
  the_thread = _Thread_Get( id, &location );
  switch ( location ) {

    case OBJECTS_LOCAL:
      #if defined(RTEMS_MULTIPROCESSING)
        if ( the_thread->is_global ) {
          _Objects_MP_Close(
            &_RTEMS_tasks_Information.Objects,
            the_thread->Object.id
          );
          _RTEMS_tasks_MP_Send_process_packet(
            RTEMS_TASKS_MP_ANNOUNCE_DELETE,
            the_thread->Object.id,
            0                                /* Not used */
          );
        }
      #endif

      _Thread_Close( the_thread, _Thread_Executing );

      _Objects_Put( &the_thread->Object );
      _Thread_Set_life_protection( previous_life_protection );
      return RTEMS_SUCCESSFUL;

#if defined(RTEMS_MULTIPROCESSING)
    case OBJECTS_REMOTE:
      _Thread_Dispatch();
      _Thread_Set_life_protection( previous_life_protection );
      return RTEMS_ILLEGAL_ON_REMOTE_OBJECT;
#endif

    case OBJECTS_ERROR:
      break;
  }

  _Thread_Set_life_protection( previous_life_protection );

  return RTEMS_INVALID_ID;
}
コード例 #3
0
ファイル: taskdelete.c プロジェクト: AoLaD/rtems
rtems_status_code rtems_task_delete(
  rtems_id id
)
{
  Thread_Control   *the_thread;
  ISR_lock_Context  lock_context;
  Thread_Control   *executing;
  Per_CPU_Control  *cpu_self;

  the_thread = _Thread_Get( id, &lock_context );

  if ( the_thread == NULL ) {
#if defined(RTEMS_MULTIPROCESSING)
    if ( _Thread_MP_Is_remote( id ) ) {
      return RTEMS_ILLEGAL_ON_REMOTE_OBJECT;
    }
#endif

    return RTEMS_INVALID_ID;
  }

  cpu_self = _Thread_Dispatch_disable_critical( &lock_context );
  _ISR_lock_ISR_enable( &lock_context );

  executing = _Per_CPU_Get_executing( cpu_self );

  if ( the_thread == executing ) {
    /*
     * The Classic tasks are neither detached nor joinable.  In case of
     * self deletion, they are detached, otherwise joinable by default.
     */
    _Thread_Exit(
      executing,
      THREAD_LIFE_TERMINATING | THREAD_LIFE_DETACHED,
      NULL
    );
  } else {
    _Thread_Close( the_thread, executing );
  }

  _Thread_Dispatch_enable( cpu_self );
  return RTEMS_SUCCESSFUL;
}
コード例 #4
0
ファイル: pthreadexit.c プロジェクト: AlexShiLucky/rtems
void _POSIX_Thread_Exit(
  Thread_Control *the_thread,
  void           *value_ptr
)
{
  Thread_Control    *unblocked;
  POSIX_API_Control *api;
  bool               previous_life_protection;

  api = the_thread->API_Extensions[ THREAD_API_POSIX ];

  _Assert( _Debug_Is_thread_dispatching_allowed() );

  previous_life_protection = _Thread_Set_life_protection( true );
  _Thread_Disable_dispatch();

  the_thread->Wait.return_argument = value_ptr;

  /*
   * Process join
   */
  if ( api->detachstate == PTHREAD_CREATE_JOINABLE ) {
    unblocked = _Thread_queue_Dequeue( &api->Join_List );
    if ( unblocked ) {
      do {
        *(void **)unblocked->Wait.return_argument = value_ptr;
      } while ( (unblocked = _Thread_queue_Dequeue( &api->Join_List )) );
    } else {
      _Thread_Set_state( the_thread, STATES_WAITING_FOR_JOIN_AT_EXIT );
      _Thread_Enable_dispatch();
      /* now waiting for thread to arrive */
      _Thread_Disable_dispatch();
    }
  }

  /*
   *  Now shut down the thread
   */
  _Thread_Close( the_thread, _Thread_Executing );

  _Thread_Enable_dispatch();
  _Thread_Set_life_protection( previous_life_protection );
}
コード例 #5
0
void pthread_exit(
  void  *value_ptr
)
{
  Objects_Information     *the_information;

  the_information = _Objects_Get_information( _Thread_Executing->Object.id );

  /* This should never happen if _Thread_Get() works right */
  assert( the_information );

  _Thread_Disable_dispatch();

  _Thread_Executing->Wait.return_argument = value_ptr;

  _Thread_Close( the_information, _Thread_Executing );

  _POSIX_Threads_Free( _Thread_Executing );

  _Thread_Enable_dispatch();
}
コード例 #6
0
ファイル: pthreadexit.c プロジェクト: 0871087123/rtems
void _POSIX_Thread_Exit(
  Thread_Control *the_thread,
  void           *value_ptr
)
{
  Objects_Information  *the_information;
  Thread_Control       *unblocked;
  POSIX_API_Control    *api;

  the_information = _Objects_Get_information_id( the_thread->Object.id );

  api = the_thread->API_Extensions[ THREAD_API_POSIX ];


  /*
   * The_information has to be non-NULL.  Otherwise, we couldn't be
   * running in a thread of this API and class.
   *
   * NOTE: Lock and unlock in different order so we do not throw a
   *       fatal error when locking the allocator mutex.  And after
   *       we unlock, we want to defer the context switch until we
   *       are ready to be switched out.  Otherwise, an ISR could
   *       occur and preempt us out while we still hold the
   *       allocator mutex.
   */

  _RTEMS_Lock_allocator();
    _Thread_Disable_dispatch();

      the_thread->Wait.return_argument = value_ptr;

      /*
       * Process join
       */
      if ( api->detachstate == PTHREAD_CREATE_JOINABLE ) {
        unblocked = _Thread_queue_Dequeue( &api->Join_List );
        if ( unblocked ) {
          do {
            *(void **)unblocked->Wait.return_argument = value_ptr;
          } while ( (unblocked = _Thread_queue_Dequeue( &api->Join_List )) );
        } else {
          _Thread_Set_state(
            the_thread,
            STATES_WAITING_FOR_JOIN_AT_EXIT | STATES_TRANSIENT
          );
           _RTEMS_Unlock_allocator();
          _Thread_Enable_dispatch();
          /* now waiting for thread to arrive */
          _RTEMS_Lock_allocator();
          _Thread_Disable_dispatch();
        }
      }

      /*
       *  Now shut down the thread
       */
      _Thread_Close( the_information, the_thread );

      _POSIX_Threads_Free( the_thread );

    _RTEMS_Unlock_allocator();
  _Thread_Enable_dispatch();
}