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; }
rtems_status_code rtems_rate_monotonic_cancel( rtems_id id ) { Rate_monotonic_Control *the_period; Objects_Locations location; the_period = _Rate_monotonic_Get( id, &location ); switch ( location ) { case OBJECTS_LOCAL: if ( !_Thread_Is_executing( the_period->owner ) ) { _Objects_Put( &the_period->Object ); return RTEMS_NOT_OWNER_OF_RESOURCE; } (void) _Watchdog_Remove( &the_period->Timer ); the_period->state = RATE_MONOTONIC_INACTIVE; _Scheduler_Release_job( the_period->owner, 0 ); _Objects_Put( &the_period->Object ); return RTEMS_SUCCESSFUL; #if defined(RTEMS_MULTIPROCESSING) case OBJECTS_REMOTE: #endif case OBJECTS_ERROR: break; } return RTEMS_INVALID_ID; }
rtems_status_code rtems_timer_fire_after( rtems_id id, rtems_interval ticks, rtems_timer_service_routine_entry routine, void *user_data ) { Timer_Control *the_timer; Objects_Locations location; ISR_Level level; if ( ticks == 0 ) return RTEMS_INVALID_NUMBER; if ( !routine ) return RTEMS_INVALID_ADDRESS; the_timer = _Timer_Get( id, &location ); switch ( location ) { case OBJECTS_LOCAL: _Timer_Cancel( the_timer ); _ISR_Disable( level ); /* * Check to see if the watchdog has just been inserted by a * higher priority interrupt. If so, abandon this insert. */ if ( the_timer->Ticker.state != WATCHDOG_INACTIVE ) { _ISR_Enable( level ); _Objects_Put( &the_timer->Object ); return RTEMS_SUCCESSFUL; } /* * OK. Now we now the timer was not rescheduled by an interrupt * so we can atomically initialize it as in use. */ the_timer->the_class = TIMER_INTERVAL; _Watchdog_Initialize( &the_timer->Ticker, routine, id, user_data ); _ISR_Enable( level ); _Watchdog_Insert_ticks( &the_timer->Ticker, ticks ); _Objects_Put( &the_timer->Object ); return RTEMS_SUCCESSFUL; #if defined(RTEMS_MULTIPROCESSING) case OBJECTS_REMOTE: /* should never return this */ #endif case OBJECTS_ERROR: break; } return RTEMS_INVALID_ID; }
rtems_status_code rtems_timer_reset( rtems_id id ) { Timer_Control *the_timer; Objects_Locations location; rtems_status_code status = RTEMS_SUCCESSFUL; the_timer = _Timer_Get( id, &location ); switch ( location ) { case OBJECTS_LOCAL: if ( the_timer->the_class == TIMER_INTERVAL ) { _Watchdog_Remove( &the_timer->Ticker ); _Watchdog_Insert( &_Watchdog_Ticks_chain, &the_timer->Ticker ); } else if ( the_timer->the_class == TIMER_INTERVAL_ON_TASK ) { Timer_server_Control *timer_server = _Timer_server; /* * There is no way for a timer to have this class unless * it was scheduled as a server fire. That requires that * the Timer Server be initiated. So this error cannot * occur unless something is internally wrong. */ #if defined(RTEMS_DEBUG) if ( !timer_server ) { _Objects_Put( &the_timer->Object ); return RTEMS_INCORRECT_STATE; } #endif _Watchdog_Remove( &the_timer->Ticker ); (*timer_server->schedule_operation)( timer_server, the_timer ); } else { /* * Must be dormant or time of day timer (e.g. TIMER_DORMANT, * TIMER_TIME_OF_DAY, or TIMER_TIME_OF_DAY_ON_TASK). We * can only reset active interval timers. */ status = RTEMS_NOT_DEFINED; } _Objects_Put( &the_timer->Object ); return status; #if defined(RTEMS_MULTIPROCESSING) case OBJECTS_REMOTE: /* should never return this */ #endif case OBJECTS_ERROR: break; } return RTEMS_INVALID_ID; }
/* Set barriers to be interruptible by signals. */ static void pipe_interruptible(pipe_control_t *pipe) { Objects_Locations location; Barrier_Control *the_barrier; the_barrier = _Barrier_Get(pipe->readBarrier, &location); the_barrier->Barrier.Wait_queue.state |= STATES_INTERRUPTIBLE_BY_SIGNAL; _Objects_Put( &the_barrier->Object ); the_barrier = _Barrier_Get(pipe->writeBarrier, &location); the_barrier->Barrier.Wait_queue.state |= STATES_INTERRUPTIBLE_BY_SIGNAL; _Objects_Put( &the_barrier->Object ); }
rtems_status_code rtems_partition_delete( rtems_id id ) { Partition_Control *the_partition; Objects_Locations location; the_partition = _Partition_Get( id, &location ); switch ( location ) { case OBJECTS_LOCAL: if ( the_partition->number_of_used_blocks == 0 ) { _Objects_Close( &_Partition_Information, &the_partition->Object ); _Partition_Free( the_partition ); #if defined(RTEMS_MULTIPROCESSING) if ( _Attributes_Is_global( the_partition->attribute_set ) ) { _Objects_MP_Close( &_Partition_Information, the_partition->Object.id ); _Partition_MP_Send_process_packet( PARTITION_MP_ANNOUNCE_DELETE, the_partition->Object.id, 0, /* Not used */ 0 /* Not used */ ); } #endif _Objects_Put( &the_partition->Object ); return RTEMS_SUCCESSFUL; } _Objects_Put( &the_partition->Object ); return RTEMS_RESOURCE_IN_USE; #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 mq_notify( mqd_t mqdes, const struct sigevent *notification ) { POSIX_Message_queue_Control *the_mq; POSIX_Message_queue_Control_fd *the_mq_fd; Objects_Locations location; the_mq_fd = _POSIX_Message_queue_Get_fd( mqdes, &location ); switch ( location ) { case OBJECTS_LOCAL: the_mq = the_mq_fd->Queue; if ( notification ) { if ( _CORE_message_queue_Is_notify_enabled( &the_mq->Message_queue ) ) { _Objects_Put( &the_mq_fd->Object ); rtems_set_errno_and_return_minus_one( EBUSY ); } _CORE_message_queue_Set_notify( &the_mq->Message_queue, NULL, NULL ); the_mq->notification = *notification; _CORE_message_queue_Set_notify( &the_mq->Message_queue, _POSIX_Message_queue_Notify_handler, the_mq ); } else { _CORE_message_queue_Set_notify( &the_mq->Message_queue, NULL, NULL ); } _Objects_Put( &the_mq_fd->Object ); return 0; #if defined(RTEMS_MULTIPROCESSING) case OBJECTS_REMOTE: #endif case OBJECTS_ERROR: break; } rtems_set_errno_and_return_minus_one( EBADF ); }
rtems_status_code rtems_timer_cancel( rtems_id id ) { Timer_Control *the_timer; Objects_Locations location; the_timer = _Timer_Get( id, &location ); switch ( location ) { case OBJECTS_LOCAL: if ( !_Timer_Is_dormant_class( the_timer->the_class ) ) (void) _Watchdog_Remove( &the_timer->Ticker ); _Objects_Put( &the_timer->Object ); return RTEMS_SUCCESSFUL; #if defined(RTEMS_MULTIPROCESSING) case OBJECTS_REMOTE: /* should never return this */ #endif case OBJECTS_ERROR: break; } return RTEMS_INVALID_ID; }
rtems_status_code rtems_barrier_wait( rtems_id id, rtems_interval timeout ) { Barrier_Control *the_barrier; Objects_Locations location; Thread_Control *executing; the_barrier = _Barrier_Get( id, &location ); switch ( location ) { case OBJECTS_LOCAL: executing = _Thread_Executing; _CORE_barrier_Wait( &the_barrier->Barrier, executing, id, true, timeout, NULL ); _Objects_Put( &the_barrier->Object ); return _Barrier_Translate_core_barrier_return_code( executing->Wait.return_code ); #if defined(RTEMS_MULTIPROCESSING) case OBJECTS_REMOTE: #endif case OBJECTS_ERROR: break; } return RTEMS_INVALID_ID; }
rtems_status_code rtems_barrier_release( rtems_id id, uint32_t *released ) { Barrier_Control *the_barrier; Objects_Locations location; if ( !released ) return RTEMS_INVALID_ADDRESS; the_barrier = _Barrier_Get( id, &location ); switch ( location ) { case OBJECTS_LOCAL: *released = _CORE_barrier_Release( &the_barrier->Barrier, id, NULL ); _Objects_Put( &the_barrier->Object ); return RTEMS_SUCCESSFUL; #if defined(RTEMS_MULTIPROCESSING) case OBJECTS_REMOTE: #endif case OBJECTS_ERROR: break; } return RTEMS_INVALID_ID; }
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_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 sem_post( sem_t *sem ) { POSIX_Semaphore_Control *the_semaphore; Objects_Locations location; the_semaphore = _POSIX_Semaphore_Get( sem, &location ); switch ( location ) { case OBJECTS_LOCAL: _CORE_semaphore_Surrender( &the_semaphore->Semaphore, the_semaphore->Object.id, #if defined(RTEMS_MULTIPROCESSING) NULL /* POSIX Semaphores are local only */ #else NULL #endif ); _Objects_Put( &the_semaphore->Object ); return 0; #if defined(RTEMS_MULTIPROCESSING) case OBJECTS_REMOTE: #endif case OBJECTS_ERROR: break; } rtems_set_errno_and_return_minus_one( EINVAL ); }
int pthread_rwlock_unlock( pthread_rwlock_t *rwlock ) { POSIX_RWLock_Control *the_rwlock; Objects_Locations location; CORE_RWLock_Status status; if ( !rwlock ) return EINVAL; the_rwlock = _POSIX_RWLock_Get( rwlock, &location ); switch ( location ) { case OBJECTS_LOCAL: status = _CORE_RWLock_Release( &the_rwlock->RWLock, _Thread_Executing ); _Objects_Put( &the_rwlock->Object ); return _POSIX_RWLock_Translate_core_RWLock_return_code( status ); #if defined(RTEMS_MULTIPROCESSING) case OBJECTS_REMOTE: #endif case OBJECTS_ERROR: break; } return EINVAL; }
int sem_close( sem_t *sem ) { POSIX_Semaphore_Control *the_semaphore; Objects_Locations location; _Objects_Allocator_lock(); the_semaphore = _POSIX_Semaphore_Get( sem, &location ); switch ( location ) { case OBJECTS_LOCAL: the_semaphore->open_count -= 1; _POSIX_Semaphore_Delete( the_semaphore ); _Objects_Put( &the_semaphore->Object ); _Objects_Allocator_unlock(); return 0; #if defined(RTEMS_MULTIPROCESSING) case OBJECTS_REMOTE: #endif case OBJECTS_ERROR: break; } _Objects_Allocator_unlock(); rtems_set_errno_and_return_minus_one( EINVAL ); }
/* * 17.1.3 Thread-Specific Data Key Deletion, P1003.1c/Draft 10, p. 167 */ int pthread_key_delete( pthread_key_t key ) { POSIX_Keys_Control *the_key; Objects_Locations location; _Objects_Allocator_lock(); the_key = _POSIX_Keys_Get( key, &location ); switch ( location ) { case OBJECTS_LOCAL: _POSIX_Keys_Free_memory( the_key ); /* * NOTE: The destructor is not called and it is the responsibility * of the application to free the memory. */ _POSIX_Keys_Free( the_key ); _Objects_Put(&the_key->Object); _Objects_Allocator_unlock(); return 0; #if defined(RTEMS_MULTIPROCESSING) case OBJECTS_REMOTE: /* should never happen */ #endif case OBJECTS_ERROR: break; } _Objects_Allocator_unlock(); return EINVAL; }
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; }
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; }
rtems_status_code rtems_port_delete( rtems_id id ) { register Dual_ported_memory_Control *the_port; Objects_Locations location; the_port = _Dual_ported_memory_Get( id, &location ); switch ( location ) { case OBJECTS_LOCAL: _Objects_Close( &_Dual_ported_memory_Information, &the_port->Object ); _Dual_ported_memory_Free( the_port ); _Objects_Put( &the_port->Object ); return RTEMS_SUCCESSFUL; #if defined(RTEMS_MULTIPROCESSING) case OBJECTS_REMOTE: /* this error cannot be returned */ #endif case OBJECTS_ERROR: break; } return RTEMS_INVALID_ID; }
/** * 11.4.2 Initializing and Destroying a Condition Variable, * P1003.1c/Draft 10, p. 87 */ int pthread_cond_destroy( pthread_cond_t *cond ) { POSIX_Condition_variables_Control *the_cond; Objects_Locations location; _Objects_Allocator_lock(); the_cond = _POSIX_Condition_variables_Get( cond, &location ); switch ( location ) { case OBJECTS_LOCAL: if ( _Thread_queue_First( &the_cond->Wait_queue, POSIX_CONDITION_VARIABLES_TQ_OPERATIONS ) ) { _Objects_Put( &the_cond->Object ); _Objects_Allocator_unlock(); return EBUSY; } _Objects_Close( &_POSIX_Condition_variables_Information, &the_cond->Object ); _Objects_Put( &the_cond->Object ); _POSIX_Condition_variables_Free( the_cond ); _Objects_Allocator_unlock(); return 0; #if defined(RTEMS_MULTIPROCESSING) case OBJECTS_REMOTE: #endif case OBJECTS_ERROR: break; } _Objects_Allocator_unlock(); return EINVAL; }
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; }
rtems_status_code rtems_message_queue_delete( rtems_id id ) { register Message_queue_Control *the_message_queue; Objects_Locations location; the_message_queue = _Message_queue_Get( id, &location ); switch ( location ) { case OBJECTS_LOCAL: _Objects_Close( &_Message_queue_Information, &the_message_queue->Object ); _CORE_message_queue_Close( &the_message_queue->message_queue, #if defined(RTEMS_MULTIPROCESSING) _Message_queue_MP_Send_object_was_deleted, #else NULL, #endif CORE_MESSAGE_QUEUE_STATUS_WAS_DELETED ); _Message_queue_Free( the_message_queue ); #if defined(RTEMS_MULTIPROCESSING) if ( _Attributes_Is_global( the_message_queue->attribute_set ) ) { _Objects_MP_Close( &_Message_queue_Information, the_message_queue->Object.id ); _Message_queue_MP_Send_process_packet( MESSAGE_QUEUE_MP_ANNOUNCE_DELETE, the_message_queue->Object.id, 0, /* Not used */ 0 ); } #endif _Objects_Put( &the_message_queue->Object ); return RTEMS_SUCCESSFUL; #if defined(RTEMS_MULTIPROCESSING) case OBJECTS_REMOTE: _Thread_Dispatch(); return RTEMS_ILLEGAL_ON_REMOTE_OBJECT; #endif case OBJECTS_ERROR: break; } return RTEMS_INVALID_ID; }
/** * This directive allows a thread to delete a rwlock specified by * the rwlock id. The rwlock is freed back to the inactive * rwlock chain. * * @param[in] rwlock is the rwlock id * * @return This method returns 0 if there was not an * error. Otherwise, a status code is returned indicating the * source of the error. */ int pthread_rwlock_destroy( pthread_rwlock_t *rwlock ) { POSIX_RWLock_Control *the_rwlock = NULL; Objects_Locations location; if ( !rwlock ) return EINVAL; the_rwlock = _POSIX_RWLock_Get( rwlock, &location ); switch ( location ) { case OBJECTS_LOCAL: /* * If there is at least one thread waiting, then do not delete it. */ if ( _Thread_queue_First( &the_rwlock->RWLock.Wait_queue ) != NULL ) { _Objects_Put( &the_rwlock->Object ); return EBUSY; } /* * POSIX doesn't require behavior when it is locked. */ _Objects_Close( &_POSIX_RWLock_Information, &the_rwlock->Object ); _POSIX_RWLock_Free( the_rwlock ); _Objects_Put( &the_rwlock->Object ); return 0; #if defined(RTEMS_MULTIPROCESSING) case OBJECTS_REMOTE: #endif case OBJECTS_ERROR: break; } return EINVAL; }
rtems_status_code rtems_message_queue_urgent( rtems_id id, const void *buffer, size_t size ) { Message_queue_Control *the_message_queue; Objects_Locations location; CORE_message_queue_Status status; if ( !buffer ) return RTEMS_INVALID_ADDRESS; the_message_queue = _Message_queue_Get( id, &location ); switch ( location ) { case OBJECTS_LOCAL: status = _CORE_message_queue_Urgent( &the_message_queue->message_queue, buffer, size, id, MESSAGE_QUEUE_MP_HANDLER, false, /* sender does not block */ 0 /* no timeout */ ); _Objects_Put( &the_message_queue->Object ); /* * Since this API does not allow for blocking sends, we can directly * return the returned status. */ return _Message_queue_Translate_core_message_queue_return_code(status); #if defined(RTEMS_MULTIPROCESSING) case OBJECTS_REMOTE: return _Message_queue_MP_Send_request_packet( MESSAGE_QUEUE_MP_URGENT_REQUEST, id, buffer, &size, 0, /* option_set */ MPCI_DEFAULT_TIMEOUT ); #endif case OBJECTS_ERROR: break; } return RTEMS_INVALID_ID; }
rtems_status_code rtems_timer_server_fire_when( rtems_id id, rtems_time_of_day *wall_time, rtems_timer_service_routine_entry routine, void *user_data ) { Timer_Control *the_timer; Objects_Locations location; rtems_interval seconds; Timer_server_Control *timer_server = _Timer_server; if ( !timer_server ) return RTEMS_INCORRECT_STATE; if ( !_TOD_Is_set() ) return RTEMS_NOT_DEFINED; if ( !routine ) return RTEMS_INVALID_ADDRESS; if ( !_TOD_Validate( wall_time ) ) return RTEMS_INVALID_CLOCK; seconds = _TOD_To_seconds( wall_time ); if ( seconds <= _TOD_Seconds_since_epoch() ) return RTEMS_INVALID_CLOCK; the_timer = _Timer_Get( id, &location ); switch ( location ) { case OBJECTS_LOCAL: (void) _Watchdog_Remove( &the_timer->Ticker ); the_timer->the_class = TIMER_TIME_OF_DAY_ON_TASK; _Watchdog_Initialize( &the_timer->Ticker, routine, id, user_data ); the_timer->Ticker.initial = seconds - _TOD_Seconds_since_epoch(); (*timer_server->schedule_operation)( timer_server, the_timer ); _Objects_Put( &the_timer->Object ); return RTEMS_SUCCESSFUL; #if defined(RTEMS_MULTIPROCESSING) case OBJECTS_REMOTE: /* should never return this */ #endif case OBJECTS_ERROR: break; } return RTEMS_INVALID_ID; }
/* * _POSIX_Keys_Run_destructors * * 17.1.1 Thread-Specific Data Key Create, P1003.1c/Draft 10, p. 163 * * NOTE: This is the routine executed when a thread exits to * run through all the keys and do the destructor action. */ void _POSIX_Keys_Run_destructors( Thread_Control *thread ) { Chain_Control *chain; POSIX_Keys_Key_value_pair *iter, *next; void *value; void (*destructor) (void *); POSIX_Keys_Control *the_key; Objects_Locations location; _Thread_Disable_dispatch(); chain = &( (POSIX_API_Control *)thread->API_Extensions[ THREAD_API_POSIX ] )->Key_Chain; iter = (POSIX_Keys_Key_value_pair *) _Chain_First( chain ); while ( !_Chain_Is_tail( chain, &iter->Key_values_per_thread_node ) ) { next = (POSIX_Keys_Key_value_pair *) _Chain_Next( &iter->Key_values_per_thread_node ); /** * remove key from rbtree and chain. * here Chain_Node *iter can be convert to POSIX_Keys_Key_value_pair *, * because Chain_Node is the first member of POSIX_Keys_Key_value_pair * structure. */ _RBTree_Extract( &_POSIX_Keys_Key_value_lookup_tree, &iter->Key_value_lookup_node ); _Chain_Extract_unprotected( &iter->Key_values_per_thread_node ); /** * run key value's destructor if destructor and value are both non-null. */ the_key = _POSIX_Keys_Get( iter->key, &location ); destructor = the_key->destructor; value = iter->value; if ( destructor != NULL && value != NULL ) (*destructor)( value ); _Objects_Put( &the_key->Object ); _POSIX_Keys_Key_value_pair_free( iter ); iter = next; } _Thread_Enable_dispatch(); }
/** * This directive allows a thread to delete a barrier specified by * the barrier id. The barrier is freed back to the inactive * barrier chain. * * @param[in] barrier is the barrier id * * @return This method returns 0 if there was not an * error. Otherwise, a status code is returned indicating the * source of the error. */ int pthread_barrier_destroy( pthread_barrier_t *barrier ) { POSIX_Barrier_Control *the_barrier = NULL; Objects_Locations location; if ( !barrier ) return EINVAL; _Objects_Allocator_lock(); the_barrier = _POSIX_Barrier_Get( barrier, &location ); switch ( location ) { case OBJECTS_LOCAL: if ( the_barrier->Barrier.number_of_waiting_threads != 0 ) { _Objects_Put( &the_barrier->Object ); return EBUSY; } _Objects_Close( &_POSIX_Barrier_Information, &the_barrier->Object ); _Objects_Put( &the_barrier->Object ); _POSIX_Barrier_Free( the_barrier ); _Objects_Allocator_unlock(); return 0; #if defined(RTEMS_MULTIPROCESSING) case OBJECTS_REMOTE: #endif case OBJECTS_ERROR: break; } _Objects_Allocator_unlock(); return EINVAL; }
rtems_status_code rtems_task_suspend( rtems_id id ) { 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_Suspend( the_thread ); _Objects_Put( &the_thread->Object ); return RTEMS_SUCCESSFUL; } _Objects_Put( &the_thread->Object ); return RTEMS_ALREADY_SUSPENDED; #if defined(RTEMS_MULTIPROCESSING) case OBJECTS_REMOTE: return _RTEMS_tasks_MP_Send_request_packet( RTEMS_TASKS_MP_SUSPEND_REQUEST, id, 0, /* Not used */ 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; }