コード例 #1
0
rtems_status_code rtems_task_get_note(
  Objects_Id  id,
  uint32_t    notepad,
  uint32_t   *note
)
{
  register Thread_Control *the_thread;
  Objects_Locations        location;
  RTEMS_API_Control       *api;

  if ( !note )
    return RTEMS_INVALID_ADDRESS;

  /*
   *  NOTE:  There is no check for < RTEMS_NOTEPAD_FIRST because that would
   *         be checking an unsigned number for being negative.
   */

  if ( notepad > RTEMS_NOTEPAD_LAST )
    return RTEMS_INVALID_NUMBER;

  /*
   *  Optimize the most likely case to avoid the Thread_Dispatch.
   */

  if ( _Objects_Are_ids_equal( id, OBJECTS_ID_OF_SELF ) ||
       _Objects_Are_ids_equal( id, _Thread_Executing->Object.id ) ) {
      api = _Thread_Executing->API_Extensions[ THREAD_API_RTEMS ];
      *note = api->Notepads[ notepad ];
      return RTEMS_SUCCESSFUL;
  }

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

    case OBJECTS_REMOTE:
#if defined(RTEMS_MULTIPROCESSING)
      _Thread_Executing->Wait.return_argument = note;

      return _RTEMS_tasks_MP_Send_request_packet(
        RTEMS_TASKS_MP_GET_NOTE_REQUEST,
        id,
        0,          /* Not used */
        notepad,
        0           /* Not used */
      );
#endif

    case OBJECTS_ERROR:
      return RTEMS_INVALID_ID;

    case OBJECTS_LOCAL:
      api = the_thread->API_Extensions[ THREAD_API_RTEMS ];
      *note = api->Notepads[ notepad ];
      _Thread_Enable_dispatch();
      return RTEMS_SUCCESSFUL;
  }

  return RTEMS_INTERNAL_ERROR;   /* unreached - only to remove warnings */
}
コード例 #2
0
ファイル: tasksetnote.c プロジェクト: AlexShiLucky/rtems
rtems_status_code rtems_task_set_note(
  rtems_id id,
  uint32_t notepad,
  uint32_t note
)
{
  Thread_Control          *the_thread;
  Objects_Locations        location;
  RTEMS_API_Control       *api;
  Thread_Control          *executing;

  if ( !rtems_configuration_get_notepads_enabled() )
    return RTEMS_NOT_CONFIGURED;

  /*
   *  NOTE:  There is no check for < RTEMS_NOTEPAD_FIRST because that would
   *         be checking an unsigned number for being negative.
   */

  if ( notepad > RTEMS_NOTEPAD_LAST )
    return RTEMS_INVALID_NUMBER;

  /*
   *  Optimize the most likely case to avoid the Thread_Dispatch.
   */

  executing = _Thread_Get_executing();
  if ( _Objects_Are_ids_equal( id, OBJECTS_ID_OF_SELF ) ||
       _Objects_Are_ids_equal( id, executing->Object.id ) ) {
      api = executing->API_Extensions[ THREAD_API_RTEMS ];
      api->Notepads[ notepad ] = note;
      return RTEMS_SUCCESSFUL;
  }

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

    case OBJECTS_LOCAL:
      api = the_thread->API_Extensions[ THREAD_API_RTEMS ];
      api->Notepads[ notepad ] = note;
      _Objects_Put( &the_thread->Object );
      return RTEMS_SUCCESSFUL;

#if defined(RTEMS_MULTIPROCESSING)
    case OBJECTS_REMOTE:
      return _RTEMS_tasks_MP_Send_request_packet(
        RTEMS_TASKS_MP_SET_NOTE_REQUEST,
        id,
        0,          /* Not used */
        notepad,
        note
      );
#endif

    case OBJECTS_ERROR:
      break;
  }

  return RTEMS_INVALID_ID;
}
コード例 #3
0
ファイル: pthreaddetach.c プロジェクト: 0871087123/rtems
int pthread_detach(
  pthread_t   thread
)
{
  register Thread_Control *the_thread;
  POSIX_API_Control       *api;
  Objects_Locations        location;

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

    case OBJECTS_LOCAL:

      api = the_thread->API_Extensions[ THREAD_API_POSIX ];
      api->detachstate = PTHREAD_CREATE_DETACHED;
      _Thread_Enable_dispatch();
      return 0;

#if defined(RTEMS_MULTIPROCESSING)
    case OBJECTS_REMOTE:
#endif
    case OBJECTS_ERROR:
      break;
  }

  return ESRCH;
}
コード例 #4
0
ファイル: taskrestart.c プロジェクト: atixing/rtems
rtems_status_code rtems_task_restart(
  rtems_id  id,
  uint32_t  argument
)
{
  register Thread_Control *the_thread;
  Objects_Locations        location;

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

    case OBJECTS_LOCAL:
      if ( _Thread_Restart( the_thread, NULL, argument ) ) {
        _Objects_Put( &the_thread->Object );
        return RTEMS_SUCCESSFUL;
      }
      _Objects_Put( &the_thread->Object );
      return RTEMS_INCORRECT_STATE;

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

    case OBJECTS_ERROR:
      break;
  }

  return RTEMS_INVALID_ID;
}
コード例 #5
0
int pthread_getaffinity_np(
  const pthread_t       id,
  size_t                cpusetsize,
  cpu_set_t            *cpuset
)
{
  Objects_Locations        location;
  Thread_Control          *the_thread;
  bool                     ok;

  if ( !cpuset )
    return EFAULT;

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

    case OBJECTS_LOCAL:
      ok = _Scheduler_Get_affinity(
        the_thread,
        cpusetsize,
        cpuset
      );
      _Objects_Put( &the_thread->Object );
      return ok ? 0 : EINVAL;

#if defined(RTEMS_MULTIPROCESSING)
    case OBJECTS_REMOTE:
#endif
    case OBJECTS_ERROR:
      break;
  }
  return ESRCH;
}
コード例 #6
0
ファイル: pthreadkill.c プロジェクト: AoLaD/rtems
int pthread_kill( pthread_t thread, int sig )
{
  Thread_Control    *the_thread;
  ISR_lock_Context   lock_context;
  POSIX_API_Control *api;
  Per_CPU_Control   *cpu_self;

  if ( !is_valid_signo( sig ) ) {
    return EINVAL;
  }

  the_thread = _Thread_Get( thread, &lock_context );

  if ( the_thread == NULL ) {
    return ESRCH;
  }

  api = the_thread->API_Extensions[ THREAD_API_POSIX ];

  if ( _POSIX_signals_Vectors[ sig ].sa_handler == SIG_IGN ) {
    _ISR_lock_ISR_enable( &lock_context );
    return 0;
  }

  /* XXX critical section */

  api->signals_pending |= signo_to_mask( sig );

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

  (void) _POSIX_signals_Unblock_thread( the_thread, sig, NULL );
  _Thread_Dispatch_enable( cpu_self );
  return 0;
}
コード例 #7
0
ファイル: pthreadgetattrnp.c プロジェクト: AlexShiLucky/rtems
int pthread_getattr_np(
  pthread_t       id,
  pthread_attr_t *attr
)
{
  Objects_Locations        location;
  POSIX_API_Control       *api;
  Thread_Control          *the_thread;

  if ( !attr )
    return EINVAL;

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

    case OBJECTS_LOCAL:
      api = the_thread->API_Extensions[ THREAD_API_POSIX ];
      _POSIX_Threads_Copy_attributes( attr, &api->Attributes);
      _Objects_Put( &the_thread->Object );
      return 0;

#if defined(RTEMS_MULTIPROCESSING)
    case OBJECTS_REMOTE:
#endif
    case OBJECTS_ERROR:
      break;
  }

  return ESRCH;
}
コード例 #8
0
int _Scheduler_CBS_Get_execution_time (
  Scheduler_CBS_Server_id   server_id,
  time_t                   *exec_time,
  time_t                   *abs_time
)
{
  Objects_Locations location;
  Thread_Control *the_thread;

  if ( server_id >= _Scheduler_CBS_Maximum_servers )
    return SCHEDULER_CBS_ERROR_INVALID_PARAMETER;
  if ( !_Scheduler_CBS_Server_list[server_id] )
    return SCHEDULER_CBS_ERROR_NOSERVER;
  if ( _Scheduler_CBS_Server_list[server_id]->task_id == -1 ) {
    *exec_time = 0;
    return SCHEDULER_CBS_OK;
  }

  the_thread = _Thread_Get(
                 _Scheduler_CBS_Server_list[server_id]->task_id,
                 &location
               );
  /* The routine _Thread_Get may disable dispatch and not enable again. */
  if ( the_thread ) {
    *exec_time = _Scheduler_CBS_Server_list[server_id]->parameters.budget -
      the_thread->cpu_time_budget;
    _Objects_Put( &the_thread->Object );
  }
  else {
    *exec_time = _Scheduler_CBS_Server_list[server_id]->parameters.budget;
  }
  return SCHEDULER_CBS_OK;
}
コード例 #9
0
ファイル: pthreadgetnamenp.c プロジェクト: gedare/rtems
int pthread_getname_np( pthread_t thread, char *name, size_t len )
{
  Thread_Control   *the_thread;
  ISR_lock_Context  lock_context;
  size_t            actual_len;

  _Objects_Allocator_lock();
  the_thread = _Thread_Get( thread, &lock_context );

  if ( the_thread == NULL ) {
    _Objects_Allocator_unlock();
    strlcpy(name, "", len);
    return ESRCH;
  }

  _ISR_lock_ISR_enable( &lock_context );
  actual_len = _Thread_Get_name( the_thread, name, len );
  _Objects_Allocator_unlock();

  if ( actual_len >= len ) {
    return ERANGE;
  }

  return 0;
}
コード例 #10
0
rtems_status_code rtems_task_is_suspended(
  rtems_id id
)
{
  register Thread_Control *the_thread;
  Objects_Locations        location;

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

    case OBJECTS_LOCAL:
      if ( !_States_Is_suspended( the_thread->current_state ) ) {
        _Thread_Enable_dispatch();
        return RTEMS_SUCCESSFUL;
      }
      _Thread_Enable_dispatch();
      return RTEMS_ALREADY_SUSPENDED;

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

    case OBJECTS_ERROR:
      break;
  }

  return RTEMS_INVALID_ID;
}
コード例 #11
0
int _Scheduler_CBS_Get_remaining_budget (
  Scheduler_CBS_Server_id  server_id,
  time_t                  *remaining_budget
)
{
  Objects_Locations location;
  Thread_Control *the_thread;

  if ( server_id >= _Scheduler_CBS_Maximum_servers )
    return SCHEDULER_CBS_ERROR_INVALID_PARAMETER;
  if ( !_Scheduler_CBS_Server_list[server_id] )
    return SCHEDULER_CBS_ERROR_NOSERVER;
  if ( _Scheduler_CBS_Server_list[server_id]->task_id == -1 ) {
    *remaining_budget = _Scheduler_CBS_Server_list[server_id]->parameters.budget;
    return SCHEDULER_CBS_OK;
  }

  the_thread = _Thread_Get(
                 _Scheduler_CBS_Server_list[server_id]->task_id,
                 &location
               );
  /* The routine _Thread_Get may disable dispatch and not enable again. */
  if ( the_thread ) {
    _Thread_Enable_dispatch();
    *remaining_budget = the_thread->cpu_time_budget;
  }
  else {
    *remaining_budget = 0;
  }

  return SCHEDULER_CBS_OK;
}
コード例 #12
0
ファイル: taskresume.c プロジェクト: fsmd/RTEMS
rtems_status_code rtems_task_resume(
  rtems_id id
)
{
  Thread_Control          *the_thread;
  Objects_Locations        location;
  States_Control           previous_state;

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

    case OBJECTS_LOCAL:
      previous_state = _Thread_Clear_state( the_thread, STATES_SUSPENDED );
      _Objects_Put( &the_thread->Object );

      return _States_Is_suspended( previous_state ) ?
        RTEMS_SUCCESSFUL : RTEMS_INCORRECT_STATE;

#if defined(RTEMS_MULTIPROCESSING)
    case OBJECTS_REMOTE:
      return _RTEMS_tasks_MP_Send_request_packet(
          RTEMS_TASKS_MP_RESUME_REQUEST,
          id,
          0,          /* Not used */
          0,          /* Not used */
          0           /* Not used */
        );
#endif

    case OBJECTS_ERROR:
      break;
  }

  return RTEMS_INVALID_ID;
}
コード例 #13
0
static int _POSIX_Threads_Join( pthread_t thread, void **value_ptr )
{
  Thread_Control       *the_thread;
  Thread_queue_Context  queue_context;
  Per_CPU_Control      *cpu_self;
  Thread_Control       *executing;
  void                 *value;

  _Thread_queue_Context_initialize( &queue_context );
  _Thread_queue_Context_set_expected_level( &queue_context, 1 );
  the_thread = _Thread_Get( thread, &queue_context.Lock_context );

  if ( the_thread == NULL ) {
    return ESRCH;
  }

  cpu_self = _Per_CPU_Get();
  executing = _Per_CPU_Get_executing( cpu_self );

  if ( executing == the_thread ) {
    _ISR_lock_ISR_enable( &queue_context.Lock_context );
    return EDEADLK;
  }

  _Thread_State_acquire_critical( the_thread, &queue_context.Lock_context );

  if ( !_Thread_Is_joinable( the_thread ) ) {
    _Thread_State_release( the_thread, &queue_context.Lock_context );
    return EINVAL;
  }

  if ( _States_Is_waiting_for_join_at_exit( the_thread->current_state ) ) {
    value = the_thread->Life.exit_value;
    _Thread_Clear_state_locked( the_thread, STATES_WAITING_FOR_JOIN_AT_EXIT );
    _Thread_Dispatch_disable_with_CPU( cpu_self, &queue_context.Lock_context );
    _Thread_State_release( the_thread, &queue_context.Lock_context );
    _Thread_Dispatch_enable( cpu_self );
  } else {
    _Thread_Join(
      the_thread,
      STATES_INTERRUPTIBLE_BY_SIGNAL | STATES_WAITING_FOR_JOIN,
      executing,
      &queue_context
    );

    if ( _POSIX_Get_error_after_wait( executing ) != 0 ) {
      _Assert( _POSIX_Get_error_after_wait( executing ) == EINTR );
      return EINTR;
    }

    value = executing->Wait.return_argument;
  }

  if ( value_ptr != NULL ) {
    *value_ptr = value;
  }

  return 0;
}
コード例 #14
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;
}
コード例 #15
0
rtems_status_code rtems_task_set_priority(
  rtems_id             id,
  rtems_task_priority  new_priority,
  rtems_task_priority *old_priority_p
)
{
  Thread_Control          *the_thread;
  ISR_lock_Context         lock_context;
  const Scheduler_Control *scheduler;
  Priority_Control         old_priority;
  rtems_status_code        status;

  if ( old_priority_p == NULL ) {
    return RTEMS_INVALID_ADDRESS;
  }

  the_thread = _Thread_Get( id, &lock_context );

  if ( the_thread == NULL ) {
#if defined(RTEMS_MULTIPROCESSING)
    return _RTEMS_tasks_MP_Set_priority( id, new_priority, old_priority_p );
#else
    return RTEMS_INVALID_ID;
#endif
  }

  if ( new_priority != RTEMS_CURRENT_PRIORITY ) {
    RTEMS_tasks_Set_priority_context  context;
    Per_CPU_Control                  *cpu_self;

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

    context.new_priority = new_priority;
    _Thread_Change_priority(
      the_thread,
      0,
      &context,
      _RTEMS_tasks_Set_priority_filter,
      false
    );

    _Thread_Dispatch_enable( cpu_self );
    scheduler = context.scheduler;
    old_priority = context.old_priority;
    status = context.status;
  } else {
    _Thread_State_acquire_critical( the_thread, &lock_context );
    scheduler = _Scheduler_Get_own( the_thread );
    old_priority = _Thread_Get_priority( the_thread );
    _Thread_State_release( the_thread, &lock_context );
    status = RTEMS_SUCCESSFUL;
  }

  *old_priority_p = _RTEMS_Priority_From_core( scheduler, old_priority );
  return status;
}
コード例 #16
0
ファイル: pthreadkill.c プロジェクト: epicsdeb/rtems
int pthread_kill(
  pthread_t   thread,
  int         sig
)
{
  POSIX_API_Control  *api;
  Thread_Control     *the_thread;
  Objects_Locations  location;

  if ( !sig )
    rtems_set_errno_and_return_minus_one( EINVAL );

  if ( !is_valid_signo(sig) )
    rtems_set_errno_and_return_minus_one( EINVAL );

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

    case OBJECTS_LOCAL:
      /*
       *  If sig == 0 then just validate arguments
       */

      api = the_thread->API_Extensions[ THREAD_API_POSIX ];

      if ( sig ) {

        if ( _POSIX_signals_Vectors[ sig ].sa_handler == SIG_IGN ) {
          _Thread_Enable_dispatch();
          return 0;
        }

        /* XXX critical section */

        api->signals_pending |= signo_to_mask( sig );

        (void) _POSIX_signals_Unblock_thread( the_thread, sig, NULL );

        the_thread->do_post_task_switch_extension = true;

        if ( _ISR_Is_in_progress() && _Thread_Is_executing( the_thread ) )
          _ISR_Signals_to_thread_executing = true;
      }
      _Thread_Enable_dispatch();
      return 0;

#if defined(RTEMS_MULTIPROCESSING)
    case OBJECTS_REMOTE:
#endif
    case OBJECTS_ERROR:
      break;
  }

  rtems_set_errno_and_return_minus_one( ESRCH );
}
コード例 #17
0
ファイル: init.c プロジェクト: AlexShiLucky/rtems
static Thread_Control *get_thread_by_id(rtems_id task_id)
{
  Objects_Locations location;
  Thread_Control *thread;

  thread = _Thread_Get(task_id, &location);
  rtems_test_assert(location == OBJECTS_LOCAL);
  _Thread_Enable_dispatch();

  return thread;
}
コード例 #18
0
ファイル: eventtimeout.c プロジェクト: 0871087123/rtems
void _Event_Timeout(
  Objects_Id  id,
  void       *ignored
)
{
  Thread_Control    *the_thread;
  Objects_Locations  location;
  ISR_Level          level;

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

    case OBJECTS_LOCAL:

      /*
       *  If the event manager is not synchronized, then it is either
       *  "nothing happened", "timeout", or "satisfied".   If the_thread
       *  is the executing thread, then it is in the process of blocking
       *  and it is the thread which is responsible for the synchronization
       *  process.
       *
       *  If it is not satisfied, then it is "nothing happened" and
       *  this is the "timeout" transition.  After a request is satisfied,
       *  a timeout is not allowed to occur.
       */
      _ISR_Disable( level );
        #if defined(RTEMS_DEBUG)
          if ( !the_thread->Wait.count ) {  /* verify thread is waiting */
            _Thread_Unnest_dispatch();
            _ISR_Enable( level );
            return;
          }
        #endif

        the_thread->Wait.count = 0;
        if ( _Thread_Is_executing( the_thread ) ) {
          if ( _Event_Sync_state == THREAD_BLOCKING_OPERATION_NOTHING_HAPPENED )
            _Event_Sync_state = THREAD_BLOCKING_OPERATION_TIMEOUT;
        }

        the_thread->Wait.return_code = RTEMS_TIMEOUT;
      _ISR_Enable( level );
      _Thread_Unblock( the_thread );
      _Thread_Unnest_dispatch();
      break;

#if defined(RTEMS_MULTIPROCESSING)
    case OBJECTS_REMOTE:  /* impossible */
#endif
    case OBJECTS_ERROR:
      break;
  }
}
コード例 #19
0
ファイル: osdThread.c プロジェクト: ukaea/epics
void epicsThreadGetName (epicsThreadId id, char *name, size_t size)
{
    rtems_id tid = (rtems_id)id;
    struct taskVar *v;
    int haveName = 0;

    if (size <= 0)
        return;
    taskVarLock ();
    for (v=taskVarHead ; v != NULL ; v=v->forw) {
        if (v->id == tid) {
            strncpy(name, v->name, size);
            haveName = 1;
            break;
        }
    }
    taskVarUnlock ();
    if (!haveName) {
#if (__RTEMS_MAJOR__>4 || \
    (__RTEMS_MAJOR__==4 && __RTEMS_MINOR__>8) || \
    (__RTEMS_MAJOR__==4 && __RTEMS_MINOR__==8 && __RTEMS_REVISION__>=99))
        if (_Objects_Get_name_as_string((rtems_id)id, size, name) != NULL)
            haveName = 1;
#else
        /*
         * Try to get the RTEMS task name
         */
        Thread_Control *thr;
        Objects_Locations l;
        if ((thr=_Thread_Get(tid, &l)) != NULL) {
            if (OBJECTS_LOCAL == l) {
                int length;
                Objects_Information *oi = _Objects_Get_information(tid);
                if (oi->name_length >= size)
                    length = size - 1;
                else
                    length = oi->name_length;
                 if (oi->is_string)
                     strncpy(name, thr->Object.name, length);
                else
                    _Objects_Copy_name_raw( &thr->Object.name, name, length);
                name[length] = '\0';
                haveName = 1;
            }
            _Thread_Enable_dispatch();
        }
#endif
    }
    if (!haveName)
        snprintf(name, size, "0x%lx", (long)tid);
    name[size-1] = '\0';
}
コード例 #20
0
ファイル: tasksetscheduler.c プロジェクト: AoLaD/rtems
rtems_status_code rtems_task_set_scheduler(
  rtems_id            task_id,
  rtems_id            scheduler_id,
  rtems_task_priority priority
)
{
  const Scheduler_Control *scheduler;
  Thread_Control          *the_thread;
  Thread_queue_Context     queue_context;
  ISR_lock_Context         state_context;
  Per_CPU_Control         *cpu_self;
  bool                     valid;
  Priority_Control         core_priority;
  Status_Control           status;

  if ( !_Scheduler_Get_by_id( scheduler_id, &scheduler ) ) {
    return RTEMS_INVALID_ID;
  }

  core_priority = _RTEMS_Priority_To_core( scheduler, priority, &valid );
  if ( !valid ) {
    return RTEMS_INVALID_PRIORITY;
  }

  _Thread_queue_Context_initialize( &queue_context );
  the_thread = _Thread_Get( task_id, &queue_context.Lock_context.Lock_context );

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

    return RTEMS_INVALID_ID;
  }

  cpu_self = _Thread_Dispatch_disable_critical(
    &queue_context.Lock_context.Lock_context
  );

  _Thread_Wait_acquire_critical( the_thread, &queue_context );
  _Thread_State_acquire_critical( the_thread, &state_context );

  status = _Scheduler_Set( scheduler, the_thread, core_priority );

  _Thread_State_release_critical( the_thread, &state_context );
  _Thread_Wait_release( the_thread, &queue_context );
  _Thread_Dispatch_enable( cpu_self );
  return _Status_Get( status );
}
コード例 #21
0
ファイル: pthreadsetschedparam.c プロジェクト: gedare/rtems
int pthread_setschedparam(
  pthread_t           thread,
  int                 policy,
  struct sched_param *param
)
{
  Thread_CPU_budget_algorithms         budget_algorithm;
  Thread_CPU_budget_algorithm_callout  budget_callout;
  Thread_Control                      *the_thread;
  Per_CPU_Control                     *cpu_self;
  Thread_queue_Context                 queue_context;
  int                                  error;

  if ( param == NULL ) {
    return EINVAL;
  }

  error = _POSIX_Thread_Translate_sched_param(
    policy,
    param,
    &budget_algorithm,
    &budget_callout
  );
  if ( error != 0 ) {
    return error;
  }

  _Thread_queue_Context_initialize( &queue_context );
  _Thread_queue_Context_clear_priority_updates( &queue_context );
  the_thread = _Thread_Get( thread, &queue_context.Lock_context.Lock_context );

  if ( the_thread == NULL ) {
    return ESRCH;
  }

  _Thread_Wait_acquire_critical( the_thread, &queue_context );
  error = _POSIX_Set_sched_param(
    the_thread,
    policy,
    param,
    budget_algorithm,
    budget_callout,
    &queue_context
  );
  cpu_self = _Thread_queue_Dispatch_disable( &queue_context );
  _Thread_Wait_release( the_thread, &queue_context );
  _Thread_Priority_update( &queue_context );
  _Thread_Dispatch_enable( cpu_self );
  return error;
}
コード例 #22
0
rtems_status_code rtems_task_variable_get(
    rtems_id tid,
    void **ptr,
    void **result
)
{
    Thread_Control        *the_thread;
    Objects_Locations      location;
    rtems_task_variable_t *tvp;

    if ( !ptr )
        return RTEMS_INVALID_ADDRESS;

    if ( !result )
        return RTEMS_INVALID_ADDRESS;

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

    case OBJECTS_LOCAL:
        /*
         *  Figure out if the variable is in this task's list.
         */
        tvp = the_thread->task_variables;
        while (tvp) {
            if (tvp->ptr == ptr) {
                /*
                 * Should this return the current (i.e not the
                 * saved) value if `tid' is the current task?
                 */
                *result = tvp->tval;
                _Thread_Enable_dispatch();
                return RTEMS_SUCCESSFUL;
            }
            tvp = (rtems_task_variable_t *)tvp->next;
        }
        _Thread_Enable_dispatch();
        return RTEMS_INVALID_ADDRESS;

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

    case OBJECTS_ERROR:
        break;
    }
    return RTEMS_INVALID_ID;
}
コード例 #23
0
ファイル: signalsend.c プロジェクト: 0871087123/rtems
rtems_status_code rtems_signal_send(
  rtems_id          id,
  rtems_signal_set  signal_set
)
{
  register Thread_Control *the_thread;
  Objects_Locations        location;
  RTEMS_API_Control       *api;
  ASR_Information         *asr;

  if ( !signal_set )
    return RTEMS_INVALID_NUMBER;

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

    case OBJECTS_LOCAL:
      api = the_thread->API_Extensions[ THREAD_API_RTEMS ];
      asr = &api->Signal;

      if ( ! _ASR_Is_null_handler( asr->handler ) ) {
        if ( asr->is_enabled ) {
          _ASR_Post_signals( signal_set, &asr->signals_posted );

          if ( _ISR_Is_in_progress() && _Thread_Is_executing( the_thread ) )
            _Thread_Dispatch_necessary = true;
        } else {
          _ASR_Post_signals( signal_set, &asr->signals_pending );
        }
        _Thread_Enable_dispatch();
        return RTEMS_SUCCESSFUL;
      }
      _Thread_Enable_dispatch();
      return RTEMS_NOT_DEFINED;

#if defined(RTEMS_MULTIPROCESSING)
    case OBJECTS_REMOTE:
      return _Signal_MP_Send_request_packet(
        SIGNAL_MP_SEND_REQUEST,
        id,
        signal_set
      );
#endif

    case OBJECTS_ERROR:
      break;
  }

  return RTEMS_INVALID_ID;
}
コード例 #24
0
epos_status_code epos_task_set_priority(
  epos_id             id,
  epos_task_priority  new_priority,
  epos_task_priority *old_priority
)
{ 
  register Thread_Control *the_thread;
  Objects_Locations               location;

  if ( new_priority != RTEMS_CURRENT_PRIORITY &&
       !_RTEMS_tasks_Priority_is_valid( new_priority ) )
    return RTEMS_INVALID_PRIORITY;

  if ( !old_priority )
    return RTEMS_INVALID_ADDRESS;

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

    case OBJECTS_LOCAL:
      /* XXX need helper to "convert" from core priority */
      *old_priority = the_thread->current_priority;
      if ( new_priority != RTEMS_CURRENT_PRIORITY ) {
        the_thread->real_priority = new_priority;
        if ( the_thread->resource_count == 0 ||
             the_thread->current_priority > new_priority )
          _Thread_Change_priority( the_thread, new_priority, false );
      }
      _Thread_Enable_dispatch();
      return RTEMS_SUCCESSFUL;

#if defined(RTEMS_MULTIPROCESSING)
    case OBJECTS_REMOTE:
      _Thread_Executing->Wait.return_argument = old_priority;
      return _RTEMS_tasks_MP_Send_request_packet(
          RTEMS_TASKS_MP_SET_PRIORITY_REQUEST,
          id,
          new_priority,
          0,          /* Not used */
          0           /* Not used */
      );
#endif

    case OBJECTS_ERROR:
      break;
  }

  return RTEMS_INVALID_ID;
}
コード例 #25
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;
}
コード例 #26
0
ファイル: tasksetpriority.c プロジェクト: gedare/rtems
rtems_status_code rtems_task_set_priority(
  rtems_id             id,
  rtems_task_priority  new_priority,
  rtems_task_priority *old_priority_p
)
{
  Thread_Control          *the_thread;
  Thread_queue_Context     queue_context;
  const Scheduler_Control *scheduler;
  Priority_Control         old_priority;
  rtems_status_code        status;

  if ( old_priority_p == NULL ) {
    return RTEMS_INVALID_ADDRESS;
  }

  _Thread_queue_Context_initialize( &queue_context );
  _Thread_queue_Context_clear_priority_updates( &queue_context );
  the_thread = _Thread_Get( id, &queue_context.Lock_context.Lock_context );

  if ( the_thread == NULL ) {
#if defined(RTEMS_MULTIPROCESSING)
    return _RTEMS_tasks_MP_Set_priority( id, new_priority, old_priority_p );
#else
    return RTEMS_INVALID_ID;
#endif
  }

  _Thread_Wait_acquire_critical( the_thread, &queue_context );

  scheduler = _Thread_Scheduler_get_home( the_thread );
  old_priority = _Thread_Get_priority( the_thread );

  if ( new_priority != RTEMS_CURRENT_PRIORITY ) {
    status = _RTEMS_tasks_Set_priority(
      the_thread,
      scheduler,
      new_priority,
      &queue_context
    );
  } else {
    _Thread_Wait_release( the_thread, &queue_context );
    status = RTEMS_SUCCESSFUL;
  }

  *old_priority_p = _RTEMS_Priority_From_core( scheduler, old_priority );
  return status;
}
コード例 #27
0
int _Scheduler_CBS_Attach_thread (
  Scheduler_CBS_Server_id server_id,
  rtems_id                task_id
)
{
  Scheduler_CBS_Server *server;
  ISR_lock_Context      lock_context;
  Thread_Control       *the_thread;
  Scheduler_CBS_Node   *node;

  if ( server_id >= _Scheduler_CBS_Maximum_servers ) {
    return SCHEDULER_CBS_ERROR_INVALID_PARAMETER;
  }

  server = &_Scheduler_CBS_Server_list[ server_id ];

  if ( !server->initialized ) {
    return SCHEDULER_CBS_ERROR_NOSERVER;
  }

  if ( server->task_id != -1 ) {
    return SCHEDULER_CBS_ERROR_FULL;
  }

  the_thread = _Thread_Get( task_id, &lock_context );

  if ( the_thread == NULL ) {
    return SCHEDULER_CBS_ERROR_INVALID_PARAMETER;
  }

  node = _Scheduler_CBS_Thread_get_node( the_thread );

  if ( node->cbs_server != NULL ) {
    _ISR_lock_ISR_enable( &lock_context );
    return SCHEDULER_CBS_ERROR_FULL;
  }

  node->cbs_server = server;

  server->task_id = task_id;

  the_thread->budget_callout   = _Scheduler_CBS_Budget_callout;
  the_thread->budget_algorithm = THREAD_CPU_BUDGET_ALGORITHM_CALLOUT;
  the_thread->is_preemptible   = true;

  _ISR_lock_ISR_enable( &lock_context );
  return SCHEDULER_CBS_OK;
}
コード例 #28
0
ファイル: taskstart.c プロジェクト: cloud-hot/rtems
rtems_status_code rtems_task_start(
  rtems_id         	id,
  rtems_task_entry 	entry_point,
  rtems_task_argument	argument
)
{
  Thread_Control          *the_thread;
  Objects_Locations        location;
  bool                     successfully_started;

  if ( entry_point == NULL )
    return RTEMS_INVALID_ADDRESS;

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

    case OBJECTS_LOCAL:
      successfully_started = _Thread_Start(
        the_thread,
        THREAD_START_NUMERIC,
        entry_point,
        NULL,
        argument,
        NULL
      );

      _Objects_Put( &the_thread->Object );

      if ( successfully_started ) {
        return RTEMS_SUCCESSFUL;
      } else {
        return RTEMS_INCORRECT_STATE;
      }

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

    case OBJECTS_ERROR:
      break;
  }

  return RTEMS_INVALID_ID;
}
コード例 #29
0
ファイル: pthreadsetschedprio.c プロジェクト: AoLaD/rtems
int pthread_setschedprio( pthread_t thread, int prio )
{
  Thread_Control          *the_thread;
  Per_CPU_Control         *cpu_self;
  Thread_queue_Context     queue_context;
  const Scheduler_Control *scheduler;
  Priority_Control         new_priority;
  bool                     valid;

  the_thread = _Thread_Get( thread, &queue_context.Lock_context.Lock_context );

  if ( the_thread == NULL ) {
    return ESRCH;
  }

  _Thread_queue_Context_clear_priority_updates( &queue_context );
  _Thread_Wait_acquire_critical( the_thread, &queue_context );

  scheduler = _Scheduler_Get_own( the_thread );

  new_priority = _POSIX_Priority_To_core( scheduler, prio, &valid );
  if ( !valid ) {
    _Thread_Wait_release( the_thread, &queue_context );
    return EINVAL;
  }

  _Thread_Priority_change(
    the_thread,
    &the_thread->Real_priority,
    new_priority,
    true,
    &queue_context
  );

  cpu_self = _Thread_Dispatch_disable_critical(
    &queue_context.Lock_context.Lock_context
  );
  _Thread_Wait_release( the_thread, &queue_context );

  _Thread_Priority_update( &queue_context );

  _Thread_Dispatch_enable( cpu_self );
  return 0;
}
コード例 #30
0
int _Scheduler_CBS_Attach_thread (
  Scheduler_CBS_Server_id server_id,
  rtems_id                task_id
)
{
  Objects_Locations location;
  Thread_Control *the_thread;

  if ( server_id >= _Scheduler_CBS_Maximum_servers )
    return SCHEDULER_CBS_ERROR_INVALID_PARAMETER;

  /* Server is not valid. */
  if ( !_Scheduler_CBS_Server_list[server_id].initialized )
    return SCHEDULER_CBS_ERROR_NOSERVER;

  /* Server is already attached to a thread. */
  if ( _Scheduler_CBS_Server_list[server_id].task_id != -1 )
    return SCHEDULER_CBS_ERROR_FULL;

  the_thread = _Thread_Get(task_id, &location);
  /* The routine _Thread_Get may disable dispatch and not enable again. */
  if ( the_thread ) {
    Scheduler_CBS_Node *node = _Scheduler_CBS_Thread_get_node( the_thread );

    /* Thread is already attached to a server. */
    if ( node->cbs_server ) {
      _Objects_Put( &the_thread->Object );
      return SCHEDULER_CBS_ERROR_FULL;
    }

    _Scheduler_CBS_Server_list[server_id].task_id = task_id;
    node->cbs_server = &_Scheduler_CBS_Server_list[server_id];

    the_thread->budget_callout   = _Scheduler_CBS_Budget_callout;
    the_thread->budget_algorithm = THREAD_CPU_BUDGET_ALGORITHM_CALLOUT;
    the_thread->is_preemptible   = true;

    _Objects_Put( &the_thread->Object );
  } else {
    return SCHEDULER_CBS_ERROR_INVALID_PARAMETER;
  }

  return SCHEDULER_CBS_OK;
}