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(); }
rtems_status_code rtems_clock_set( rtems_time_of_day *time_buffer ) { struct timespec newtime; if ( !time_buffer ) return RTEMS_INVALID_ADDRESS; if ( _TOD_Validate( time_buffer ) ) { newtime.tv_sec = _TOD_To_seconds( time_buffer ); newtime.tv_nsec = time_buffer->ticks * (_TOD_Microseconds_per_tick * TOD_NANOSECONDS_PER_MICROSECOND); _Thread_Disable_dispatch(); _TOD_Set( &newtime ); _Thread_Enable_dispatch(); return RTEMS_SUCCESSFUL; } return RTEMS_INVALID_CLOCK; }
bool _Debug_Is_owner_of_allocator( void ) { API_Mutex_Control *mutex = _RTEMS_Allocator_Mutex; bool owner; /* * We have to synchronize with the _CORE_mutex_Surrender() operation, * otherwise we may observe an outdated mutex holder. */ _Thread_Disable_dispatch(); if ( mutex != NULL ) { owner = mutex->Mutex.holder == _Thread_Executing; } else { owner = false; } _Thread_Enable_dispatch(); return owner; }
static void test_change_priority(void) { rtems_status_code sc; rtems_id task_id; Thread_Control *executing; Scheduler_SMP_Node *node; size_t i; size_t j; size_t k; task_id = start_task(3); _Thread_Disable_dispatch(); executing = _Thread_Executing; node = _Scheduler_SMP_Thread_get_node( executing ); for (i = 0; i < RTEMS_ARRAY_SIZE(states); ++i) { for (j = 0; j < RTEMS_ARRAY_SIZE(priorities); ++j) { for (k = 0; k < RTEMS_ARRAY_SIZE(prepend_it); ++k) { test_case_change_priority( executing, node, states[i], priorities[j], prepend_it[k], states[j] ); } } } _Thread_Change_priority(executing, 1, true); rtems_test_assert(node->state == SCHEDULER_SMP_NODE_SCHEDULED); _Thread_Enable_dispatch(); sc = rtems_task_delete(task_id); rtems_test_assert(sc == RTEMS_SUCCESSFUL); }
rtems_status_code rtems_message_queue_flush( rtems_id id, uint32_t *count ) { register Message_queue_Control *the_message_queue; Objects_Locations location; if ( !count ) return RTEMS_INVALID_ADDRESS; the_message_queue = _Message_queue_Get( id, &location ); switch ( location ) { case OBJECTS_LOCAL: *count = _CORE_message_queue_Flush( &the_message_queue->message_queue ); _Thread_Enable_dispatch(); return RTEMS_SUCCESSFUL; #if defined(RTEMS_MULTIPROCESSING) case OBJECTS_REMOTE: _Thread_Executing->Wait.return_argument = count; return _Message_queue_MP_Send_request_packet( MESSAGE_QUEUE_MP_FLUSH_REQUEST, id, 0, /* buffer not used */ 0, /* size */ 0, /* option_set not used */ MPCI_DEFAULT_TIMEOUT ); #endif case OBJECTS_ERROR: break; } return RTEMS_INVALID_ID; }
int _POSIX_Semaphore_Wait_support( sem_t *sem, bool blocking, Watchdog_Interval timeout ) { POSIX_Semaphore_Control *the_semaphore; Objects_Locations location; the_semaphore = _POSIX_Semaphore_Get( sem, &location ); switch ( location ) { case OBJECTS_LOCAL: _CORE_semaphore_Seize( &the_semaphore->Semaphore, the_semaphore->Object.id, blocking, timeout ); _Thread_Enable_dispatch(); if ( !_Thread_Executing->Wait.return_code ) return 0; rtems_set_errno_and_return_minus_one( _POSIX_Semaphore_Translate_core_semaphore_return_code( _Thread_Executing->Wait.return_code ) ); #if defined(RTEMS_MULTIPROCESSING) case OBJECTS_REMOTE: #endif case OBJECTS_ERROR: break; } rtems_set_errno_and_return_minus_one( EINVAL ); }
static void test_scheduler_move_heir(void) { bool per_cpu_state_ok; _Thread_Disable_dispatch(); suspend(2); suspend(3); suspend(0); resume(2); suspend(1); resume(3); resume(0); per_cpu_state_ok = is_per_cpu_state_ok(); resume(1); _Thread_Enable_dispatch(); rtems_test_assert(per_cpu_state_ok); }
rtems_status_code rtems_semaphore_flush( rtems_id id ) { register Semaphore_Control *the_semaphore; Objects_Locations location; the_semaphore = _Semaphore_Get( id, &location ); switch ( location ) { case OBJECTS_LOCAL: if ( !_Attributes_Is_counting_semaphore(the_semaphore->attribute_set) ) { _CORE_mutex_Flush( &the_semaphore->Core_control.mutex, SEND_OBJECT_WAS_DELETED, CORE_MUTEX_STATUS_UNSATISFIED_NOWAIT ); } else { _CORE_semaphore_Flush( &the_semaphore->Core_control.semaphore, SEND_OBJECT_WAS_DELETED, CORE_SEMAPHORE_STATUS_UNSATISFIED_NOWAIT ); } _Thread_Enable_dispatch(); 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; }
static void deferred_release(void) { rtems_filesystem_global_location_t *current = NULL; do { int count = 0; _Thread_Disable_dispatch(); current = deferred_released_global_locations; if (current != NULL) { deferred_released_global_locations = current->deferred_released_next; count = current->deferred_released_count; current->deferred_released_next = NULL; current->deferred_released_count = 0; } _Thread_Enable_dispatch(); if (current != NULL) { release_with_count(current, count); } } while (current != NULL); }
int mq_close( mqd_t mqdes ) { 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 ); if ( location == OBJECTS_LOCAL ) { /* OBJECTS_LOCAL: * * First update the actual message queue to reflect this descriptor * being disassociated. This may result in the queue being really * deleted. */ the_mq = the_mq_fd->Queue; the_mq->open_count -= 1; _POSIX_Message_queue_Delete( the_mq ); /* * Now close this file descriptor. */ _Objects_Close( &_POSIX_Message_queue_Information_fds, &the_mq_fd->Object ); _POSIX_Message_queue_Free_fd( the_mq_fd ); _Thread_Enable_dispatch(); return 0; } /* * OBJECTS_REMOTE: * OBJECTS_ERROR: */ rtems_set_errno_and_return_minus_one( EBADF ); }
rtems_status_code rtems_event_receive( rtems_event_set event_in, rtems_option option_set, rtems_interval ticks, rtems_event_set *event_out ) { rtems_status_code sc; if ( event_out != NULL ) { Thread_Control *executing = _Thread_Get_executing(); RTEMS_API_Control *api = executing->API_Extensions[ THREAD_API_RTEMS ]; Event_Control *event = &api->Event; if ( !_Event_sets_Is_empty( event_in ) ) { _Thread_Disable_dispatch(); _Event_Seize( event_in, option_set, ticks, event_out, executing, event, &_Event_Sync_state, STATES_WAITING_FOR_EVENT ); _Thread_Enable_dispatch(); sc = executing->Wait.return_code; } else { *event_out = event->pending_events; sc = RTEMS_SUCCESSFUL; } } else { sc = RTEMS_INVALID_ADDRESS; } return sc; }
void epicsEventShow(epicsEventId id, unsigned int level) { #if __RTEMS_VIOLATE_KERNEL_VISIBILITY__ rtems_id sid = (rtems_id)id; Semaphore_Control *the_semaphore; Semaphore_Control semaphore; Objects_Locations location; the_semaphore = _Semaphore_Get (sid, &location); if (location != OBJECTS_LOCAL) return; /* * Yes, there's a race condition here since an interrupt might * change things while the copy is in progress, but the information * is only for display, so it's not that critical. */ semaphore = *the_semaphore; _Thread_Enable_dispatch(); printf (" %8.8x ", (int)sid); if (_Attributes_Is_counting_semaphore (semaphore.attribute_set)) { printf ("Count: %d", (int)semaphore.Core_control.semaphore.count); } else { if (_CORE_mutex_Is_locked(&semaphore.Core_control.mutex)) { char name[30]; epicsThreadGetName ((epicsThreadId)semaphore.Core_control.mutex.holder_id, name, sizeof name); printf ("Held by:%8.8x (%s) Nest count:%d", (unsigned int)semaphore.Core_control.mutex.holder_id, name, (int)semaphore.Core_control.mutex.nest_count); } else { printf ("Not Held"); } } printf ("\n"); #endif }
int mq_getattr( mqd_t mqdes, struct mq_attr *mqstat ) { POSIX_Message_queue_Control *the_mq; POSIX_Message_queue_Control_fd *the_mq_fd; Objects_Locations location; if ( !mqstat ) rtems_set_errno_and_return_minus_one( EINVAL ); the_mq_fd = _POSIX_Message_queue_Get_fd( mqdes, &location ); switch ( location ) { case OBJECTS_LOCAL: the_mq = the_mq_fd->Queue; /* * Return the old values. */ mqstat->mq_flags = the_mq_fd->oflag; mqstat->mq_msgsize = the_mq->Message_queue.maximum_message_size; mqstat->mq_maxmsg = the_mq->Message_queue.maximum_pending_messages; mqstat->mq_curmsgs = the_mq->Message_queue.number_of_pending_messages; _Thread_Enable_dispatch(); return 0; #if defined(RTEMS_MULTIPROCESSING) case OBJECTS_REMOTE: #endif case OBJECTS_ERROR: break; } rtems_set_errno_and_return_minus_one( EBADF ); }
int pthread_getschedparam( pthread_t thread, int *policy, struct sched_param *param ) { Objects_Locations location; POSIX_API_Control *api; register Thread_Control *the_thread; if ( !policy || !param ) return EINVAL; the_thread = _Thread_Get( thread, &location ); switch ( location ) { case OBJECTS_LOCAL: api = the_thread->API_Extensions[ THREAD_API_POSIX ]; if ( policy ) *policy = api->schedpolicy; if ( param ) { *param = api->schedparam; param->sched_priority = _POSIX_Priority_From_core( the_thread->current_priority ); } _Thread_Enable_dispatch(); return 0; #if defined(RTEMS_MULTIPROCESSING) case OBJECTS_REMOTE: #endif case OBJECTS_ERROR: break; } return ESRCH; }
rtems_status_code rtems_message_queue_get_number_pending( Objects_Id id, uint32_t *count ) { register Message_queue_Control *the_message_queue; Objects_Locations location; if ( !count ) return RTEMS_INVALID_ADDRESS; the_message_queue = _Message_queue_Get( id, &location ); switch ( location ) { case OBJECTS_REMOTE: #if defined(RTEMS_MULTIPROCESSING) _Thread_Executing->Wait.return_argument = count; return _Message_queue_MP_Send_request_packet( MESSAGE_QUEUE_MP_GET_NUMBER_PENDING_REQUEST, id, 0, /* buffer not used */ 0, /* size */ 0, /* option_set not used */ MPCI_DEFAULT_TIMEOUT ); #endif case OBJECTS_ERROR: return RTEMS_INVALID_ID; case OBJECTS_LOCAL: *count = the_message_queue->message_queue.number_of_pending_messages; _Thread_Enable_dispatch(); return RTEMS_SUCCESSFUL; } return RTEMS_INTERNAL_ERROR; /* unreached - only to remove warnings */ }
void _TOD_Set_with_timestamp( const Timestamp_Control *tod ) { Watchdog_Interval seconds_next = _Timestamp_Get_seconds( tod ); Watchdog_Interval seconds_now; _Thread_Disable_dispatch(); _TOD_Deactivate(); seconds_now = _TOD_Seconds_since_epoch(); if ( seconds_next < seconds_now ) _Watchdog_Adjust_seconds( WATCHDOG_BACKWARD, seconds_now - seconds_next ); else _Watchdog_Adjust_seconds( WATCHDOG_FORWARD, seconds_next - seconds_now ); _TOD_Now = *tod; _TOD_Is_set = true; _TOD_Activate(); _Thread_Enable_dispatch(); }
uint32_t _MPCI_Send_request_packet ( uint32_t destination, MP_packet_Prefix *the_packet, States_Control extra_state ) { the_packet->source_tid = _Thread_Executing->Object.id; the_packet->source_priority = _Thread_Executing->current_priority; the_packet->to_convert = ( the_packet->to_convert - sizeof(MP_packet_Prefix) ) / sizeof(uint32_t); _Thread_Executing->Wait.id = the_packet->id; _Thread_Executing->Wait.queue = &_MPCI_Remote_blocked_threads; _Thread_Disable_dispatch(); (*_MPCI_table->send_packet)( destination, the_packet ); _Thread_queue_Enter_critical_section( &_MPCI_Remote_blocked_threads ); /* * See if we need a default timeout */ if (the_packet->timeout == MPCI_DEFAULT_TIMEOUT) the_packet->timeout = _MPCI_table->default_timeout; _Thread_queue_Enqueue( &_MPCI_Remote_blocked_threads, the_packet->timeout ); _Thread_Executing->current_state = _States_Set( extra_state, _Thread_Executing->current_state ); _Thread_Enable_dispatch(); return _Thread_Executing->Wait.return_code; }
rtems_status_code rtems_task_wake_when( rtems_time_of_day *time_buffer ) { Watchdog_Interval seconds; if ( !_TOD_Is_set() ) return RTEMS_NOT_DEFINED; if ( !time_buffer ) return RTEMS_INVALID_ADDRESS; time_buffer->ticks = 0; if ( !_TOD_Validate( time_buffer ) ) return RTEMS_INVALID_CLOCK; seconds = _TOD_To_seconds( time_buffer ); if ( seconds <= _TOD_Seconds_since_epoch() ) return RTEMS_INVALID_CLOCK; _Thread_Disable_dispatch(); _Thread_Set_state( _Thread_Executing, STATES_WAITING_FOR_TIME ); _Watchdog_Initialize( &_Thread_Executing->Timer, _Thread_Delay_ended, _Thread_Executing->Object.id, NULL ); _Watchdog_Insert_seconds( &_Thread_Executing->Timer, seconds - _TOD_Seconds_since_epoch() ); _Thread_Enable_dispatch(); return RTEMS_SUCCESSFUL; }
int pthread_rwlock_wrlock( pthread_rwlock_t *rwlock ) { POSIX_RWLock_Control *the_rwlock; Objects_Locations location; if ( !rwlock ) return EINVAL; the_rwlock = _POSIX_RWLock_Get( rwlock, &location ); switch ( location ) { case OBJECTS_LOCAL: _CORE_RWLock_Obtain_for_writing( &the_rwlock->RWLock, *rwlock, true, /* do not timeout -- wait forever */ 0, NULL ); _Thread_Enable_dispatch(); return _POSIX_RWLock_Translate_core_RWLock_return_code( (CORE_RWLock_Status) _Thread_Executing->Wait.return_code ); #if defined(RTEMS_MULTIPROCESSING) case OBJECTS_REMOTE: #endif case OBJECTS_ERROR: break; } return EINVAL; }
rtems_status_code rtems_rate_monotonic_reset_statistics( rtems_id id ) { Objects_Locations location; Rate_monotonic_Control *the_period; the_period = _Rate_monotonic_Get( id, &location ); switch ( location ) { case OBJECTS_LOCAL: _Rate_monotonic_Reset_statistics( the_period ); _Thread_Enable_dispatch(); 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_clock_set( const rtems_time_of_day *tod ) { if ( !tod ) return RTEMS_INVALID_ADDRESS; if ( _TOD_Validate( tod ) ) { Timestamp_Control tod_as_timestamp; uint32_t seconds = _TOD_To_seconds( tod ); uint32_t nanoseconds = tod->ticks * rtems_configuration_get_nanoseconds_per_tick(); _Timestamp_Set( &tod_as_timestamp, seconds, nanoseconds ); _Thread_Disable_dispatch(); _TOD_Set_with_timestamp( &tod_as_timestamp ); _Thread_Enable_dispatch(); return RTEMS_SUCCESSFUL; } return RTEMS_INVALID_CLOCK; }
int _Scheduler_CBS_Detach_thread ( Scheduler_CBS_Server_id server_id, rtems_id task_id ) { Objects_Locations location; Thread_Control *the_thread; Scheduler_CBS_Per_thread *sched_info; the_thread = _Thread_Get(task_id, &location); /* The routine _Thread_Get may disable dispatch and not enable again. */ if ( the_thread ) { _Thread_Enable_dispatch(); } if ( server_id >= _Scheduler_CBS_Maximum_servers ) return SCHEDULER_CBS_ERROR_INVALID_PARAMETER; if ( !the_thread ) return SCHEDULER_CBS_ERROR_INVALID_PARAMETER; /* Server is not valid. */ if ( !_Scheduler_CBS_Server_list[server_id] ) return SCHEDULER_CBS_ERROR_NOSERVER; /* Thread and server are not attached. */ if ( _Scheduler_CBS_Server_list[server_id]->task_id != task_id ) return SCHEDULER_CBS_ERROR_INVALID_PARAMETER; _Scheduler_CBS_Server_list[server_id]->task_id = -1; sched_info = (Scheduler_CBS_Per_thread *) the_thread->scheduler_info; sched_info->cbs_server = NULL; the_thread->budget_algorithm = the_thread->Start.budget_algorithm; the_thread->budget_callout = the_thread->Start.budget_callout; the_thread->is_preemptible = the_thread->Start.is_preemptible; return SCHEDULER_CBS_OK; }
int pthread_key_delete( pthread_key_t key ) { register POSIX_Keys_Control *the_key; Objects_Locations location; uint32_t the_api; the_key = _POSIX_Keys_Get( key, &location ); switch ( location ) { case OBJECTS_LOCAL: _Objects_Close( &_POSIX_Keys_Information, &the_key->Object ); for ( the_api = 1; the_api <= OBJECTS_APIS_LAST; the_api++ ) if ( the_key->Values[ the_api ] ) _Workspace_Free( the_key->Values[ the_api ] ); /* * NOTE: The destructor is not called and it is the responsibility * of the application to free the memory. */ _POSIX_Keys_Free( the_key ); _Thread_Enable_dispatch(); return 0; #if defined(RTEMS_MULTIPROCESSING) case OBJECTS_REMOTE: /* should never happen */ #endif case OBJECTS_ERROR: break; } return EINVAL; }
void _TOD_Set( const struct timespec *time ) { long seconds; _Thread_Disable_dispatch(); _TOD_Deactivate(); seconds = _TOD_Seconds_since_epoch(); if ( time->tv_sec < seconds ) _Watchdog_Adjust_seconds( WATCHDOG_BACKWARD, seconds - time->tv_sec ); else _Watchdog_Adjust_seconds( WATCHDOG_FORWARD, time->tv_sec - seconds ); /* POSIX format TOD (timespec) */ _Timestamp_Set( &_TOD_Now, time->tv_sec, time->tv_nsec ); _TOD_Is_set = true; _TOD_Activate(); _Thread_Enable_dispatch(); }
rtems_status_code rtems_event_send( rtems_id id, rtems_event_set event_in ) { register Thread_Control *the_thread; Objects_Locations location; RTEMS_API_Control *api; the_thread = _Thread_Get( id, &location ); switch ( location ) { case OBJECTS_LOCAL: api = the_thread->API_Extensions[ THREAD_API_RTEMS ]; _Event_sets_Post( event_in, &api->pending_events ); _Event_Surrender( the_thread ); _Thread_Enable_dispatch(); return RTEMS_SUCCESSFUL; #if defined(RTEMS_MULTIPROCESSING) case OBJECTS_REMOTE: return( _Event_MP_Send_request_packet( EVENT_MP_SEND_REQUEST, id, event_in ) ); #endif case OBJECTS_ERROR: break; } return RTEMS_INVALID_ID; }
rtems_status_code rtems_event_receive( rtems_event_set event_in, rtems_option option_set, rtems_interval ticks, rtems_event_set *event_out ) { RTEMS_API_Control *api; if ( !event_out ) return RTEMS_INVALID_ADDRESS; api = _Thread_Executing->API_Extensions[ THREAD_API_RTEMS ]; if ( _Event_sets_Is_empty( event_in ) ) { *event_out = api->pending_events; return RTEMS_SUCCESSFUL; } _Thread_Disable_dispatch(); _Event_Seize( event_in, option_set, ticks, event_out ); _Thread_Enable_dispatch(); return( _Thread_Executing->Wait.return_code ); }
int timer_delete( timer_t timerid ) { /* * IDEA: This function must probably stop the timer first and then delete it * * It will have to do a call to rtems_timer_cancel and then another * call to rtems_timer_delete. * The call to rtems_timer_delete will be probably unnecessary, * because rtems_timer_delete stops the timer before deleting it. */ POSIX_Timer_Control *ptimer; Objects_Locations location; ptimer = _POSIX_Timer_Get( timerid, &location ); switch ( location ) { case OBJECTS_REMOTE: #if defined(RTEMS_MULTIPROCESSING) _Thread_Dispatch(); rtems_set_errno_and_return_minus_one( EINVAL ); #endif case OBJECTS_ERROR: rtems_set_errno_and_return_minus_one( EINVAL ); case OBJECTS_LOCAL: _Objects_Close( &_POSIX_Timer_Information, &ptimer->Object ); ptimer->state = POSIX_TIMER_STATE_FREE; (void) _Watchdog_Remove( &ptimer->Timer ); _POSIX_Timer_Free( ptimer ); _Thread_Enable_dispatch(); return 0; } return -1; /* unreached - only to remove warnings */ }
ER dly_tsk( DLYTIME dlytim ) { Watchdog_Interval ticks; ticks = TOD_MILLISECONDS_TO_TICKS(dlytim); _Thread_Disable_dispatch(); if ( ticks == 0 ) { _Thread_Yield_processor(); } else { _Thread_Set_state( _Thread_Executing, STATES_DELAYING ); _Watchdog_Initialize( &_Thread_Executing->Timer, _Thread_Delay_ended, _Thread_Executing->Object.id, NULL ); _Watchdog_Insert_ticks( &_Thread_Executing->Timer, ticks ); } _Thread_Enable_dispatch(); return E_OK; }
int sigtimedwait( const sigset_t *set, siginfo_t *info, const struct timespec *timeout ) { Thread_Control *the_thread; POSIX_API_Control *api; Watchdog_Interval interval; siginfo_t signal_information; siginfo_t *the_info; int signo; ISR_Level level; /* * Error check parameters before disabling interrupts. */ if ( !set ) rtems_set_errno_and_return_minus_one( EINVAL ); /* NOTE: This is very specifically a RELATIVE not ABSOLUTE time * in the Open Group specification. */ interval = 0; if ( timeout ) { if ( !_Timespec_Is_valid( timeout ) ) rtems_set_errno_and_return_minus_one( EINVAL ); interval = _Timespec_To_ticks( timeout ); if ( !interval ) rtems_set_errno_and_return_minus_one( EINVAL ); } /* * Initialize local variables. */ the_info = ( info ) ? info : &signal_information; the_thread = _Thread_Executing; api = the_thread->API_Extensions[ THREAD_API_POSIX ]; /* * What if they are already pending? */ /* API signals pending? */ _ISR_Disable( level ); if ( *set & api->signals_pending ) { /* XXX real info later */ the_info->si_signo = _POSIX_signals_Get_highest( api->signals_pending ); _POSIX_signals_Clear_signals( api, the_info->si_signo, the_info, false, false ); _ISR_Enable( level ); the_info->si_code = SI_USER; the_info->si_value.sival_int = 0; return the_info->si_signo; } /* Process pending signals? */ if ( *set & _POSIX_signals_Pending ) { signo = _POSIX_signals_Get_highest( _POSIX_signals_Pending ); _POSIX_signals_Clear_signals( api, signo, the_info, true, false ); _ISR_Enable( level ); the_info->si_signo = signo; the_info->si_code = SI_USER; the_info->si_value.sival_int = 0; return signo; } the_info->si_signo = -1; _Thread_Disable_dispatch(); the_thread->Wait.queue = &_POSIX_signals_Wait_queue; the_thread->Wait.return_code = EINTR; the_thread->Wait.option = *set; the_thread->Wait.return_argument = the_info; _Thread_queue_Enter_critical_section( &_POSIX_signals_Wait_queue ); _ISR_Enable( level ); _Thread_queue_Enqueue( &_POSIX_signals_Wait_queue, interval ); _Thread_Enable_dispatch(); /* * When the thread is set free by a signal, it is need to eliminate * the signal. */ _POSIX_signals_Clear_signals( api, the_info->si_signo, the_info, false, false ); errno = _Thread_Executing->Wait.return_code; return the_info->si_signo; }
void _Thread_Handler( void ) { ISR_Level level; Thread_Control *executing; #if defined(EXECUTE_GLOBAL_CONSTRUCTORS) static char doneConstructors; char doneCons; #endif executing = _Thread_Executing; /* * Some CPUs need to tinker with the call frame or registers when the * thread actually begins to execute for the first time. This is a * hook point where the port gets a shot at doing whatever it requires. */ _Context_Initialization_at_thread_begin(); /* * have to put level into a register for those cpu's that use * inline asm here */ level = executing->Start.isr_level; _ISR_Set_level(level); #if defined(EXECUTE_GLOBAL_CONSTRUCTORS) doneCons = doneConstructors; doneConstructors = 1; #endif #if ( CPU_HARDWARE_FP == TRUE ) || ( CPU_SOFTWARE_FP == TRUE ) #if ( CPU_USE_DEFERRED_FP_SWITCH == TRUE ) if ( (executing->fp_context != NULL) && !_Thread_Is_allocated_fp( executing ) ) { if ( _Thread_Allocated_fp != NULL ) _Context_Save_fp( &_Thread_Allocated_fp->fp_context ); _Thread_Allocated_fp = executing; } #endif #endif /* * Take care that 'begin' extensions get to complete before * 'switch' extensions can run. This means must keep dispatch * disabled until all 'begin' extensions complete. */ _User_extensions_Thread_begin( executing ); /* * At this point, the dispatch disable level BETTER be 1. */ _Thread_Enable_dispatch(); #if defined(EXECUTE_GLOBAL_CONSTRUCTORS) /* * _init could be a weak symbol and we SHOULD test it but it isn't * in any configuration I know of and it generates a warning on every * RTEMS target configuration. --joel (12 May 2007) */ if (!doneCons) /* && (volatile void *)_init) */ { INIT_NAME (); } #endif if ( executing->Start.prototype == THREAD_START_NUMERIC ) { executing->Wait.return_argument = (*(Thread_Entry_numeric) executing->Start.entry_point)( executing->Start.numeric_argument ); } #if defined(RTEMS_POSIX_API) else if ( executing->Start.prototype == THREAD_START_POINTER ) { executing->Wait.return_argument = (*(Thread_Entry_pointer) executing->Start.entry_point)( executing->Start.pointer_argument ); } #endif #if defined(FUNCTIONALITY_NOT_CURRENTLY_USED_BY_ANY_API) else if ( executing->Start.prototype == THREAD_START_BOTH_POINTER_FIRST ) { executing->Wait.return_argument = (*(Thread_Entry_both_pointer_first) executing->Start.entry_point)( executing->Start.pointer_argument, executing->Start.numeric_argument ); } else if ( executing->Start.prototype == THREAD_START_BOTH_NUMERIC_FIRST ) { executing->Wait.return_argument = (*(Thread_Entry_both_numeric_first) executing->Start.entry_point)( executing->Start.numeric_argument, executing->Start.pointer_argument ); } #endif /* * In the switch above, the return code from the user thread body * was placed in return_argument. This assumed that if it returned * anything (which is not supporting in all APIs), then it would be * able to fit in a (void *). */ _User_extensions_Thread_exitted( executing ); _Internal_error_Occurred( INTERNAL_ERROR_CORE, true, INTERNAL_ERROR_THREAD_EXITTED ); }