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 */ }
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; }
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; }
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; }
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; }
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; }
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; }
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; }
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; }
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; }
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; }
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; }
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; }
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; }
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; }
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 ); }
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; }
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; } }
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'; }
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 ); }
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; }
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; }
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; }
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; }
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; }
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; }
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; }
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; }
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; }
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; }