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; }
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 */ }
void _Objects_MP_Close ( Objects_Information *information, Objects_Id the_id ) { Chain_Control *the_chain; Chain_Node *the_node; Objects_MP_Control *the_object; the_chain = &information->global_table[ _Objects_Get_node( the_id ) ]; for ( the_node = _Chain_First( the_chain ) ; !_Chain_Is_tail( the_chain, the_node ) ; the_node = _Chain_Next( the_node ) ) { the_object = (Objects_MP_Control *) the_node; if ( _Objects_Are_ids_equal( the_object->Object.id, the_id ) ) { _Chain_Extract( the_node ); _Objects_MP_Free_global_object( the_object ); return; } } _Terminate( INTERNAL_ERROR_CORE, true, INTERNAL_ERROR_INVALID_GLOBAL_ID ); }
void _Objects_MP_Is_remote ( Objects_Information *information, Objects_Id the_id, Objects_Locations *location, Objects_Control **the_object ) { uint32_t node; Chain_Control *the_chain; Chain_Node *the_node; Objects_MP_Control *the_global_object; node = _Objects_Get_node( the_id ); /* * NOTE: The local node was search (if necessary) by * _Objects_Name_to_id_XXX before this was invoked. * * The NODE field of an object id cannot be 0 * because 0 is an invalid node number. */ if ( node == 0 || _Objects_Is_local_node( node ) || node > _Objects_Maximum_nodes || information->global_table == NULL ) { *location = OBJECTS_ERROR; *the_object = NULL; return; } _Thread_Disable_dispatch(); the_chain = &information->global_table[ node ]; for ( the_node = _Chain_First( the_chain ) ; !_Chain_Is_tail( the_chain, the_node ) ; the_node = _Chain_Next( the_node ) ) { the_global_object = (Objects_MP_Control *) the_node; if ( _Objects_Are_ids_equal( the_global_object->Object.id, the_id ) ) { _Thread_Unnest_dispatch(); *location = OBJECTS_REMOTE; *the_object = (Objects_Control *) the_global_object; return; } } _Thread_Enable_dispatch(); *location = OBJECTS_ERROR; *the_object = NULL; }
/** * This function maps thread IDs to thread control * blocks. If ID corresponds to a local thread, then it * returns the_thread control pointer which maps to ID * and location is set to OBJECTS_LOCAL. If the thread ID is * global and resides on a remote node, then location is set * to OBJECTS_REMOTE, and the_thread is undefined. * Otherwise, location is set to OBJECTS_ERROR and * the_thread is undefined. * * @note The performance of many RTEMS services depends upon * the quick execution of the "good object" path in this * routine. If there is a possibility of saving a few * cycles off the execution time, this routine is worth * further optimization attention. */ Thread_Control *_Thread_Get ( Objects_Id id, Objects_Locations *location ) { uint32_t the_api; uint32_t the_class; Objects_Information **api_information; Objects_Information *information; Thread_Control *tp = (Thread_Control *) 0; if ( _Objects_Are_ids_equal( id, OBJECTS_ID_OF_SELF ) ) { _Thread_Disable_dispatch(); *location = OBJECTS_LOCAL; tp = _Thread_Executing; goto done; } the_api = _Objects_Get_API( id ); if ( !_Objects_Is_api_valid( the_api ) ) { *location = OBJECTS_ERROR; goto done; } the_class = _Objects_Get_class( id ); if ( the_class != 1 ) { /* threads are always first class :) */ *location = OBJECTS_ERROR; goto done; } api_information = _Objects_Information_table[ the_api ]; /* * There is no way for this to happen if POSIX is enabled. But there * is actually a test case in sp43 for this which trips it whether or * not POSIX is enabled. So in the interest of safety, this is left * on in all configurations. */ if ( !api_information ) { *location = OBJECTS_ERROR; goto done; } information = api_information[ the_class ]; if ( !information ) { *location = OBJECTS_ERROR; goto done; } tp = (Thread_Control *) _Objects_Get( information, id, location ); done: return tp; }
Thread_Control *_Thread_MP_Find_proxy ( Objects_Id the_id ) { Chain_Node *proxy_node; Thread_Control *the_thread; ISR_Level level; restart: _ISR_Disable( level ); for ( proxy_node = _Chain_First( &_Thread_MP_Active_proxies ); !_Chain_Is_tail( &_Thread_MP_Active_proxies, proxy_node ) ; ) { the_thread = (Thread_Control *) _Addresses_Subtract_offset( proxy_node, _Thread_MP_Proxy_Active_offset ); if ( _Objects_Are_ids_equal( the_thread->Object.id, the_id ) ) { _ISR_Enable( level ); return the_thread; } _ISR_Flash( level ); proxy_node = _Chain_Next( proxy_node ); /* * A proxy which is only dormant is not in a blocking state. * Therefore, we are looking at proxy which has been moved from * active to inactive chain (by an ISR) and need to restart * the search. */ if ( _States_Is_only_dormant( the_thread->current_state ) ) { _ISR_Enable( level ); goto restart; } } _ISR_Enable( level ); return NULL; }
Thread_Control *_Thread_Get ( Objects_Id id, Objects_Locations *location ) { uint32_t the_api; uint32_t the_class; Objects_Information **api_information; Objects_Information *information; Thread_Control *tp = (Thread_Control *) 0; if ( _Objects_Are_ids_equal( id, OBJECTS_ID_OF_SELF ) ) { _Thread_Disable_dispatch(); *location = OBJECTS_LOCAL; tp = _Thread_Executing; goto done; } the_api = _Objects_Get_API( id ); if ( !_Objects_Is_api_valid( the_api ) ) { *location = OBJECTS_ERROR; goto done; } the_class = _Objects_Get_class( id ); if ( the_class != 1 ) { /* threads are always first class :) */ *location = OBJECTS_ERROR; goto done; } api_information = _Objects_Information_table[ the_api ]; if ( !api_information ) { *location = OBJECTS_ERROR; goto done; } information = api_information[ the_class ]; if ( !information ) { *location = OBJECTS_ERROR; goto done; } tp = (Thread_Control *) _Objects_Get( information, id, location ); done: return tp; }
int pthread_equal( pthread_t t1, pthread_t t2 ) { /* * If the system is configured for debug, then we will do everything we * can to insure that both ids are valid. Otherwise, we will do the * cheapest possible thing to determine if they are equal. */ #ifndef RTEMS_DEBUG return _Objects_Are_ids_equal( t1, t2 ); #else int status; Objects_Locations location; Thread_Control *thread_1; Thread_Control *thread_2; /* * By default this is not a match. */ status = 0; /* * Validate the first id and return 0 if it is not valid */ thread_1 = _Thread_Get( t1, &location ); switch ( location ) { case OBJECTS_LOCAL: /* * Validate the second id and return 0 if it is not valid */ thread_2 = _Thread_Get( t2, &location ); switch ( location ) { case OBJECTS_LOCAL: status = _Objects_Are_ids_equal( t1, t2 ); _Objects_Put_without_thread_dispatch( &thread_2->Object ); _Objects_Put( &thread_1->Object ); break; case OBJECTS_ERROR: #if defined(RTEMS_MULTIPROCESSING) case OBJECTS_REMOTE: #endif /* t1 must have been valid so exit the critical section */ _Objects_Put( &thread_1->Object ); /* return status == 0 */ break; } break; #if defined(RTEMS_MULTIPROCESSING) case OBJECTS_REMOTE: #endif case OBJECTS_ERROR: /* return status == 0 */ break; } return status; #endif }