void _SMP_Multicast_actions_process( void ) { SMP_lock_Context lock_context; uint32_t cpu_self_index; SMP_Multicast_action *node; SMP_Multicast_action *next; _SMP_lock_ISR_disable_and_acquire( &_SMP_Multicast.Lock, &lock_context ); cpu_self_index = _SMP_Get_current_processor(); node = (SMP_Multicast_action *) _Chain_First( &_SMP_Multicast.Actions ); while ( !_Chain_Is_tail( &_SMP_Multicast.Actions, &node->Node ) ) { next = (SMP_Multicast_action *) _Chain_Next( &node->Node ); if ( _Processor_mask_Is_set( &node->targets, cpu_self_index ) ) { _Processor_mask_Clear( &node->targets, cpu_self_index ); ( *node->handler )( node->arg ); if ( _Processor_mask_Is_zero( &node->targets ) ) { _Chain_Extract_unprotected( &node->Node ); _Atomic_Store_ulong( &node->done, 1, ATOMIC_ORDER_RELEASE ); } } node = next; } _SMP_lock_Release_and_ISR_enable( &_SMP_Multicast.Lock, &lock_context ); }
bool _User_extensions_Thread_create ( Thread_Control *the_thread ) { Chain_Node *the_node; User_extensions_Control *the_extension; bool status; for ( the_node = _User_extensions_List.first ; !_Chain_Is_tail( &_User_extensions_List, the_node ) ; the_node = the_node->next ) { the_extension = (User_extensions_Control *) the_node; if ( the_extension->Callouts.thread_create != NULL ) { status = (*the_extension->Callouts.thread_create)( _Thread_Executing, the_thread ); if ( !status ) return false; } } return true; }
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; }
/* * _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(); }
void _API_extensions_Run_postswitch( void ) { Chain_Node *the_node; API_extensions_Control *the_extension; for ( the_node = _API_extensions_List.first ; !_Chain_Is_tail( &_API_extensions_List, the_node ) ; the_node = the_node->next ) { the_extension = (API_extensions_Control *) the_node; if ( the_extension->postswitch_hook ) (*the_extension->postswitch_hook)( _Thread_Executing ); } }
void _API_extensions_Run_postdriver( void ) { Chain_Node *the_node; API_extensions_Control *the_extension; for ( the_node = _API_extensions_List.first ; !_Chain_Is_tail( &_API_extensions_List, the_node ) ; the_node = the_node->next ) { the_extension = (API_extensions_Control *) the_node; if ( the_extension->postdriver_hook ) (*the_extension->postdriver_hook)(); } }
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; }
void _User_extensions_Thread_switch ( Thread_Control *executing, Thread_Control *heir ) { Chain_Node *the_node; User_extensions_Switch_control *the_extension_switch; for ( the_node = _Chain_First( &_User_extensions_Switches_list ); !_Chain_Is_tail( &_User_extensions_Switches_list, the_node ) ; the_node = the_node->next ) { the_extension_switch = (User_extensions_Switch_control *) the_node; (*the_extension_switch->thread_switch)( executing, heir ); } }
void _User_extensions_Thread_begin ( Thread_Control *executing ) { Chain_Node *the_node; User_extensions_Control *the_extension; for ( the_node = _Chain_First( &_User_extensions_List ); !_Chain_Is_tail( &_User_extensions_List, the_node ) ; the_node = the_node->next ) { the_extension = (User_extensions_Control *) the_node; if ( the_extension->Callouts.thread_begin != NULL ) (*the_extension->Callouts.thread_begin)( executing ); } }
void _User_extensions_Thread_restart ( Thread_Control *the_thread ) { Chain_Node *the_node; User_extensions_Control *the_extension; for ( the_node = _Chain_First( &_User_extensions_List ); !_Chain_Is_tail( &_User_extensions_List, the_node ) ; the_node = the_node->next ) { the_extension = (User_extensions_Control *) the_node; if ( the_extension->Callouts.thread_restart != NULL ) (*the_extension->Callouts.thread_restart)( _Thread_Executing, the_thread ); } }
/* * Reschedule threads -- select heirs for all cores */ void _Scheduler_simple_smp_Schedule(void) { Chain_Control *c; Chain_Node *n; Thread_Control *t; uint32_t cpu; c = (Chain_Control *)_Scheduler.information; cpu = 0; /* * Iterate over the first N (where N is the number of CPU cores) threads * on the ready chain. Attempt to assign each as heir on a core. When * unable to assign a thread as a new heir, then stop. */ for (n = _Chain_First(c); !_Chain_Is_tail(c, n); n = _Chain_Next(n)) { t = (Thread_Control *)n; if ( !_Scheduler_simple_smp_Assign( t ) ) break; if ( ++cpu >= _SMP_Processor_count ) break; } }
void _CORE_message_queue_Insert_message( CORE_message_queue_Control *the_message_queue, CORE_message_queue_Buffer_control *the_message, CORE_message_queue_Submit_types submit_type ) { ISR_Level level; #if defined(RTEMS_SCORE_COREMSG_ENABLE_NOTIFICATION) bool notify = false; #define SET_NOTIFY() \ do { \ if ( the_message_queue->number_of_pending_messages == 0 ) \ notify = true; \ } while (0) #else #define SET_NOTIFY() #endif _CORE_message_queue_Set_message_priority( the_message, submit_type ); #if !defined(RTEMS_SCORE_COREMSG_ENABLE_MESSAGE_PRIORITY) _ISR_Disable( level ); SET_NOTIFY(); the_message_queue->number_of_pending_messages++; if ( submit_type == CORE_MESSAGE_QUEUE_SEND_REQUEST ) _CORE_message_queue_Append_unprotected(the_message_queue, the_message); else _CORE_message_queue_Prepend_unprotected(the_message_queue, the_message); _ISR_Enable( level ); #else if ( submit_type == CORE_MESSAGE_QUEUE_SEND_REQUEST ) { _ISR_Disable( level ); SET_NOTIFY(); the_message_queue->number_of_pending_messages++; _CORE_message_queue_Append_unprotected(the_message_queue, the_message); _ISR_Enable( level ); } else if ( submit_type == CORE_MESSAGE_QUEUE_URGENT_REQUEST ) { _ISR_Disable( level ); SET_NOTIFY(); the_message_queue->number_of_pending_messages++; _CORE_message_queue_Prepend_unprotected(the_message_queue, the_message); _ISR_Enable( level ); } else { CORE_message_queue_Buffer_control *this_message; Chain_Node *the_node; Chain_Control *the_header; int the_priority; the_priority = _CORE_message_queue_Get_message_priority(the_message); the_header = &the_message_queue->Pending_messages; the_node = _Chain_First( the_header ); while ( !_Chain_Is_tail( the_header, the_node ) ) { int this_priority; this_message = (CORE_message_queue_Buffer_control *) the_node; this_priority = _CORE_message_queue_Get_message_priority(this_message); if ( this_priority <= the_priority ) { the_node = the_node->next; continue; } break; } _ISR_Disable( level ); SET_NOTIFY(); the_message_queue->number_of_pending_messages++; _Chain_Insert_unprotected( the_node->previous, &the_message->Node ); _ISR_Enable( level ); } #endif #if defined(RTEMS_SCORE_COREMSG_ENABLE_NOTIFICATION) /* * According to POSIX, does this happen before or after the message * is actually enqueued. It is logical to think afterwards, because * the message is actually in the queue at this point. */ if ( notify && the_message_queue->notify_handler ) (*the_message_queue->notify_handler)(the_message_queue->notify_argument); #endif }
int killinfo( pid_t pid, int sig, const union sigval *value ) { sigset_t mask; POSIX_API_Control *api; uint32_t the_api; uint32_t index; uint32_t maximum; Objects_Information *the_info; Objects_Control **object_table; Thread_Control *the_thread; Thread_Control *interested; Priority_Control interested_priority; Chain_Control *the_chain; Chain_Node *the_node; siginfo_t siginfo_struct; siginfo_t *siginfo; POSIX_signals_Siginfo_node *psiginfo; /* * Only supported for the "calling process" (i.e. this node). */ if ( pid != getpid() ) rtems_set_errno_and_return_minus_one( ESRCH ); /* * Validate the signal passed. */ if ( !sig ) rtems_set_errno_and_return_minus_one( EINVAL ); if ( !is_valid_signo(sig) ) rtems_set_errno_and_return_minus_one( EINVAL ); /* * If the signal is being ignored, then we are out of here. */ if ( _POSIX_signals_Vectors[ sig ].sa_handler == SIG_IGN ) return 0; /* * P1003.1c/Draft 10, p. 33 says that certain signals should always * be directed to the executing thread such as those caused by hardware * faults. */ if ( (sig == SIGFPE) || (sig == SIGILL) || (sig == SIGSEGV ) ) return pthread_kill( pthread_self(), sig ); mask = signo_to_mask( sig ); /* * Build up a siginfo structure */ siginfo = &siginfo_struct; siginfo->si_signo = sig; siginfo->si_code = SI_USER; if ( !value ) { siginfo->si_value.sival_int = 0; } else { siginfo->si_value = *value; } _Thread_Disable_dispatch(); /* * Is the currently executing thread interested? If so then it will * get it an execute it as soon as the dispatcher executes. */ the_thread = _Thread_Executing; api = the_thread->API_Extensions[ THREAD_API_POSIX ]; if ( _POSIX_signals_Is_interested( api, mask ) ) { goto process_it; } /* * Is an interested thread waiting for this signal (sigwait())? * * There is no requirement on the order of threads pending on a sigwait(). */ /* XXX violation of visibility -- need to define thread queue support */ the_chain = &_POSIX_signals_Wait_queue.Queues.Fifo; for ( the_node = _Chain_First( the_chain ); !_Chain_Is_tail( the_chain, the_node ) ; the_node = the_node->next ) { the_thread = THREAD_CHAIN_NODE_TO_THREAD( the_node ); api = the_thread->API_Extensions[ THREAD_API_POSIX ]; #if defined(DEBUG_SIGNAL_PROCESSING) printk( "Waiting Thread=%p option=0x%08x mask=0x%08x blocked=0x%08x\n", the_thread, the_thread->Wait.option, mask, api->signals_blocked); #endif /* * Is this thread is actually blocked waiting for the signal? */ if (the_thread->Wait.option & mask) goto process_it; /* * Is this thread is blocked waiting for another signal but has * not blocked this one? */ if (~api->signals_blocked & mask) goto process_it; } /* * Is any other thread interested? The highest priority interested * thread is selected. In the event of a tie, then the following * additional criteria is used: * * + ready thread over blocked * + blocked on call interruptible by signal (can return EINTR) * + blocked on call not interruptible by signal * * This looks at every thread in the system regardless of the creating API. * * NOTES: * * + rtems internal threads do not receive signals. */ interested = NULL; interested_priority = PRIORITY_MAXIMUM + 1; for (the_api = OBJECTS_CLASSIC_API; the_api <= OBJECTS_APIS_LAST; the_api++) { /* * This can occur when no one is interested and an API is not configured. */ if ( !_Objects_Information_table[ the_api ] ) continue; the_info = _Objects_Information_table[ the_api ][ 1 ]; #if defined(RTEMS_DEBUG) /* * This cannot happen in the current (as of June 2009) implementation * of initialization but at some point, the object information * structure for a particular manager may not be installed. */ if ( !the_info ) continue; #endif maximum = the_info->maximum; object_table = the_info->local_table; for ( index = 1 ; index <= maximum ; index++ ) { the_thread = (Thread_Control *) object_table[ index ]; if ( !the_thread ) continue; #if defined(DEBUG_SIGNAL_PROCESSING) printk("\n 0x%08x/0x%08x %d/%d 0x%08x 1", the_thread->Object.id, ((interested) ? interested->Object.id : 0), the_thread->current_priority, interested_priority, the_thread->current_state ); #endif /* * If this thread is of lower priority than the interested thread, * go on to the next thread. */ if ( the_thread->current_priority > interested_priority ) continue; DEBUG_STEP("2"); /* * If this thread is not interested, then go on to the next thread. */ api = the_thread->API_Extensions[ THREAD_API_POSIX ]; #if defined(RTEMS_DEBUG) if ( !api ) continue; #endif if ( !_POSIX_signals_Is_interested( api, mask ) ) continue; DEBUG_STEP("3"); /* * Now we know the thread under consideration is interested. * If the thread under consideration is of higher priority, then * it becomes the interested thread. * * NOTE: We initialized interested_priority to PRIORITY_MAXIMUM + 1 * so we never have to worry about deferencing a NULL * interested thread. */ if ( the_thread->current_priority < interested_priority ) { interested = the_thread; interested_priority = the_thread->current_priority; continue; } DEBUG_STEP("4"); /* * Now the thread and the interested thread have the same priority. * We have to sort through the combinations of blocked/not blocked * and blocking interruptibutable by signal. * * If the interested thread is ready, don't think about changing. */ if ( interested && !_States_Is_ready( interested->current_state ) ) { /* preferred ready over blocked */ DEBUG_STEP("5"); if ( _States_Is_ready( the_thread->current_state ) ) { interested = the_thread; interested_priority = the_thread->current_priority; continue; } DEBUG_STEP("6"); /* prefer blocked/interruptible over blocked/not interruptible */ if ( !_States_Is_interruptible_by_signal(interested->current_state) ) { DEBUG_STEP("7"); if ( _States_Is_interruptible_by_signal(the_thread->current_state) ) { DEBUG_STEP("8"); interested = the_thread; interested_priority = the_thread->current_priority; continue; } } } } } if ( interested ) { the_thread = interested; goto process_it; } /* * OK so no threads were interested right now. It will be left on the * global pending until a thread receives it. The global set of threads * can change interest in this signal in one of the following ways: * * + a thread is created with the signal unblocked, * + pthread_sigmask() unblocks the signal, * + sigprocmask() unblocks the signal, OR * + sigaction() which changes the handler to SIG_IGN. */ the_thread = NULL; goto post_process_signal; /* * We found a thread which was interested, so now we mark that this * thread needs to do the post context switch extension so it can * evaluate the signals pending. */ process_it: /* * Returns true if the signal was synchronously given to a thread * blocked waiting for the signal. */ if ( _POSIX_signals_Unblock_thread( the_thread, sig, siginfo ) ) { _Thread_Enable_dispatch(); return 0; } post_process_signal: /* * We may have woken up a thread but we definitely need to post the * signal to the process wide information set. */ _POSIX_signals_Set_process_signals( mask ); if ( _POSIX_signals_Vectors[ sig ].sa_flags == SA_SIGINFO ) { psiginfo = (POSIX_signals_Siginfo_node *) _Chain_Get( &_POSIX_signals_Inactive_siginfo ); if ( !psiginfo ) { _Thread_Enable_dispatch(); rtems_set_errno_and_return_minus_one( EAGAIN ); } psiginfo->Info = *siginfo; _Chain_Append( &_POSIX_signals_Siginfo[ sig ], &psiginfo->Node ); } DEBUG_STEP("\n"); _Thread_Enable_dispatch(); return 0; }
Thread_blocking_operation_States _Thread_queue_Enqueue_priority ( Thread_queue_Control *the_thread_queue, Thread_Control *the_thread, ISR_Level *level_p ) { Priority_Control search_priority; Thread_Control *search_thread; ISR_Level level; Chain_Control *header; uint32_t header_index; Chain_Node *the_node; Chain_Node *next_node; Chain_Node *previous_node; Chain_Node *search_node; Priority_Control priority; States_Control block_state; _Chain_Initialize_empty( &the_thread->Wait.Block2n ); priority = the_thread->current_priority; header_index = _Thread_queue_Header_number( priority ); header = &the_thread_queue->Queues.Priority[ header_index ]; block_state = the_thread_queue->state; if ( _Thread_queue_Is_reverse_search( priority ) ) goto restart_reverse_search; restart_forward_search: search_priority = PRIORITY_MINIMUM - 1; _ISR_Disable( level ); search_thread = (Thread_Control *) header->first; while ( !_Chain_Is_tail( header, (Chain_Node *)search_thread ) ) { search_priority = search_thread->current_priority; if ( priority <= search_priority ) break; #if ( CPU_UNROLL_ENQUEUE_PRIORITY == TRUE ) search_thread = (Thread_Control *) search_thread->Object.Node.next; if ( _Chain_Is_tail( header, (Chain_Node *)search_thread ) ) break; search_priority = search_thread->current_priority; if ( priority <= search_priority ) break; #endif _ISR_Flash( level ); if ( !_States_Are_set( search_thread->current_state, block_state) ) { _ISR_Enable( level ); goto restart_forward_search; } search_thread = (Thread_Control *)search_thread->Object.Node.next; } if ( the_thread_queue->sync_state != THREAD_BLOCKING_OPERATION_NOTHING_HAPPENED ) goto synchronize; the_thread_queue->sync_state = THREAD_BLOCKING_OPERATION_SYNCHRONIZED; if ( priority == search_priority ) goto equal_priority; search_node = (Chain_Node *) search_thread; previous_node = search_node->previous; the_node = (Chain_Node *) the_thread; the_node->next = search_node; the_node->previous = previous_node; previous_node->next = the_node; search_node->previous = the_node; the_thread->Wait.queue = the_thread_queue; _ISR_Enable( level ); return THREAD_BLOCKING_OPERATION_NOTHING_HAPPENED; restart_reverse_search: search_priority = PRIORITY_MAXIMUM + 1; _ISR_Disable( level ); search_thread = (Thread_Control *) header->last; while ( !_Chain_Is_head( header, (Chain_Node *)search_thread ) ) { search_priority = search_thread->current_priority; if ( priority >= search_priority ) break; #if ( CPU_UNROLL_ENQUEUE_PRIORITY == TRUE ) search_thread = (Thread_Control *) search_thread->Object.Node.previous; if ( _Chain_Is_head( header, (Chain_Node *)search_thread ) ) break; search_priority = search_thread->current_priority; if ( priority >= search_priority ) break; #endif _ISR_Flash( level ); if ( !_States_Are_set( search_thread->current_state, block_state) ) { _ISR_Enable( level ); goto restart_reverse_search; } search_thread = (Thread_Control *) search_thread->Object.Node.previous; } if ( the_thread_queue->sync_state != THREAD_BLOCKING_OPERATION_NOTHING_HAPPENED ) goto synchronize; the_thread_queue->sync_state = THREAD_BLOCKING_OPERATION_SYNCHRONIZED; if ( priority == search_priority ) goto equal_priority; search_node = (Chain_Node *) search_thread; next_node = search_node->next; the_node = (Chain_Node *) the_thread; the_node->next = next_node; the_node->previous = search_node; search_node->next = the_node; next_node->previous = the_node; the_thread->Wait.queue = the_thread_queue; _ISR_Enable( level ); return THREAD_BLOCKING_OPERATION_NOTHING_HAPPENED; equal_priority: /* add at end of priority group */ search_node = _Chain_Tail( &search_thread->Wait.Block2n ); previous_node = search_node->previous; the_node = (Chain_Node *) the_thread; the_node->next = search_node; the_node->previous = previous_node; previous_node->next = the_node; search_node->previous = the_node; the_thread->Wait.queue = the_thread_queue; _ISR_Enable( level ); return THREAD_BLOCKING_OPERATION_NOTHING_HAPPENED; synchronize: /* * An interrupt completed the thread's blocking request. * For example, the blocking thread could have been given * the mutex by an ISR or timed out. * * WARNING! Returning with interrupts disabled! */ *level_p = level; return the_thread_queue->sync_state; }
Objects_Name_or_id_lookup_errors _Objects_MP_Global_name_search ( Objects_Information *information, Objects_Name the_name, uint32_t nodes_to_search, Objects_Id *the_id ) { uint32_t low_node; uint32_t high_node; uint32_t node_index; Chain_Control *the_chain; Chain_Node *the_node; Objects_MP_Control *the_object; uint32_t name_to_use; name_to_use = the_name.name_u32; /* XXX only fixed length names */ if ( nodes_to_search > _Objects_Maximum_nodes ) return OBJECTS_INVALID_NODE; if ( information->global_table == NULL ) return OBJECTS_INVALID_NAME; if ( nodes_to_search == OBJECTS_SEARCH_ALL_NODES || nodes_to_search == OBJECTS_SEARCH_OTHER_NODES ) { low_node = 1; high_node = _Objects_Maximum_nodes; } else { low_node = high_node = nodes_to_search; } _Thread_Disable_dispatch(); for ( node_index = low_node ; node_index <= high_node ; node_index++ ) { /* * NOTE: The local node was search (if necessary) by * _Objects_Name_to_id_XXX before this was invoked. */ if ( !_Objects_Is_local_node( node_index ) ) { the_chain = &information->global_table[ node_index ]; 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 ( the_object->name == name_to_use ) { *the_id = the_object->Object.id; _Thread_Enable_dispatch(); return OBJECTS_NAME_OR_ID_LOOKUP_SUCCESSFUL; } } } } _Thread_Enable_dispatch(); return OBJECTS_INVALID_NAME; }