/*
|
/*
|
* Multiprocessing Support for the Object Handler
|
* Multiprocessing Support for the Object Handler
|
*
|
*
|
*
|
*
|
* COPYRIGHT (c) 1989-1999.
|
* COPYRIGHT (c) 1989-1999.
|
* On-Line Applications Research Corporation (OAR).
|
* On-Line Applications Research Corporation (OAR).
|
*
|
*
|
* The license and distribution terms for this file may be
|
* The license and distribution terms for this file may be
|
* found in the file LICENSE in this distribution or at
|
* found in the file LICENSE in this distribution or at
|
* http://www.OARcorp.com/rtems/license.html.
|
* http://www.OARcorp.com/rtems/license.html.
|
*
|
*
|
* $Id: objectmp.c,v 1.2 2001-09-27 11:59:34 chris Exp $
|
* $Id: objectmp.c,v 1.2 2001-09-27 11:59:34 chris Exp $
|
*/
|
*/
|
|
|
#include <rtems/system.h>
|
#include <rtems/system.h>
|
#include <rtems/score/interr.h>
|
#include <rtems/score/interr.h>
|
#include <rtems/score/object.h>
|
#include <rtems/score/object.h>
|
#include <rtems/score/wkspace.h>
|
#include <rtems/score/wkspace.h>
|
#include <rtems/score/thread.h>
|
#include <rtems/score/thread.h>
|
|
|
/*PAGE
|
/*PAGE
|
*
|
*
|
* _Objects_MP_Handler_initialization
|
* _Objects_MP_Handler_initialization
|
*
|
*
|
*/
|
*/
|
|
|
void _Objects_MP_Handler_initialization (
|
void _Objects_MP_Handler_initialization (
|
unsigned32 node,
|
unsigned32 node,
|
unsigned32 maximum_nodes,
|
unsigned32 maximum_nodes,
|
unsigned32 maximum_global_objects
|
unsigned32 maximum_global_objects
|
)
|
)
|
{
|
{
|
_Objects_MP_Maximum_global_objects = maximum_global_objects;
|
_Objects_MP_Maximum_global_objects = maximum_global_objects;
|
|
|
if ( maximum_global_objects == 0 ) {
|
if ( maximum_global_objects == 0 ) {
|
_Chain_Initialize_empty( &_Objects_MP_Inactive_global_objects );
|
_Chain_Initialize_empty( &_Objects_MP_Inactive_global_objects );
|
return;
|
return;
|
}
|
}
|
|
|
_Chain_Initialize(
|
_Chain_Initialize(
|
&_Objects_MP_Inactive_global_objects,
|
&_Objects_MP_Inactive_global_objects,
|
_Workspace_Allocate_or_fatal_error(
|
_Workspace_Allocate_or_fatal_error(
|
maximum_global_objects * sizeof( Objects_MP_Control )
|
maximum_global_objects * sizeof( Objects_MP_Control )
|
),
|
),
|
maximum_global_objects,
|
maximum_global_objects,
|
sizeof( Objects_MP_Control )
|
sizeof( Objects_MP_Control )
|
);
|
);
|
|
|
}
|
}
|
|
|
/*PAGE
|
/*PAGE
|
*
|
*
|
* _Objects_MP_Open
|
* _Objects_MP_Open
|
*
|
*
|
*/
|
*/
|
|
|
void _Objects_MP_Open (
|
void _Objects_MP_Open (
|
Objects_Information *information,
|
Objects_Information *information,
|
Objects_MP_Control *the_global_object,
|
Objects_MP_Control *the_global_object,
|
unsigned32 the_name, /* XXX -- wrong for variable */
|
unsigned32 the_name, /* XXX -- wrong for variable */
|
Objects_Id the_id
|
Objects_Id the_id
|
)
|
)
|
{
|
{
|
the_global_object->Object.id = the_id;
|
the_global_object->Object.id = the_id;
|
the_global_object->name = the_name;
|
the_global_object->name = the_name;
|
|
|
_Chain_Prepend(
|
_Chain_Prepend(
|
&information->global_table[ _Objects_Get_node( the_id ) ],
|
&information->global_table[ _Objects_Get_node( the_id ) ],
|
&the_global_object->Object.Node
|
&the_global_object->Object.Node
|
);
|
);
|
|
|
}
|
}
|
|
|
/*PAGE
|
/*PAGE
|
*
|
*
|
* _Objects_MP_Allocate_and_open
|
* _Objects_MP_Allocate_and_open
|
*
|
*
|
*/
|
*/
|
|
|
boolean _Objects_MP_Allocate_and_open (
|
boolean _Objects_MP_Allocate_and_open (
|
Objects_Information *information,
|
Objects_Information *information,
|
unsigned32 the_name, /* XXX -- wrong for variable */
|
unsigned32 the_name, /* XXX -- wrong for variable */
|
Objects_Id the_id,
|
Objects_Id the_id,
|
boolean is_fatal_error
|
boolean is_fatal_error
|
)
|
)
|
{
|
{
|
Objects_MP_Control *the_global_object;
|
Objects_MP_Control *the_global_object;
|
|
|
the_global_object = _Objects_MP_Allocate_global_object();
|
the_global_object = _Objects_MP_Allocate_global_object();
|
if ( _Objects_MP_Is_null_global_object( the_global_object ) ) {
|
if ( _Objects_MP_Is_null_global_object( the_global_object ) ) {
|
|
|
if ( is_fatal_error == FALSE )
|
if ( is_fatal_error == FALSE )
|
return FALSE;
|
return FALSE;
|
|
|
_Internal_error_Occurred(
|
_Internal_error_Occurred(
|
INTERNAL_ERROR_CORE,
|
INTERNAL_ERROR_CORE,
|
TRUE,
|
TRUE,
|
INTERNAL_ERROR_OUT_OF_GLOBAL_OBJECTS
|
INTERNAL_ERROR_OUT_OF_GLOBAL_OBJECTS
|
);
|
);
|
|
|
}
|
}
|
|
|
_Objects_MP_Open( information, the_global_object, the_name, the_id );
|
_Objects_MP_Open( information, the_global_object, the_name, the_id );
|
|
|
return TRUE;
|
return TRUE;
|
}
|
}
|
|
|
/*PAGE
|
/*PAGE
|
*
|
*
|
* _Objects_MP_Close
|
* _Objects_MP_Close
|
*
|
*
|
*/
|
*/
|
|
|
void _Objects_MP_Close (
|
void _Objects_MP_Close (
|
Objects_Information *information,
|
Objects_Information *information,
|
Objects_Id the_id
|
Objects_Id the_id
|
)
|
)
|
{
|
{
|
Chain_Control *the_chain;
|
Chain_Control *the_chain;
|
Chain_Node *the_node;
|
Chain_Node *the_node;
|
Objects_MP_Control *the_object;
|
Objects_MP_Control *the_object;
|
|
|
the_chain = &information->global_table[ _Objects_Get_node( the_id ) ];
|
the_chain = &information->global_table[ _Objects_Get_node( the_id ) ];
|
|
|
for ( the_node = the_chain->first ;
|
for ( the_node = the_chain->first ;
|
!_Chain_Is_tail( the_chain, the_node ) ;
|
!_Chain_Is_tail( the_chain, the_node ) ;
|
the_node = the_node->next ) {
|
the_node = the_node->next ) {
|
|
|
the_object = (Objects_MP_Control *) the_node;
|
the_object = (Objects_MP_Control *) the_node;
|
|
|
if ( _Objects_Are_ids_equal( the_object->Object.id, the_id ) ) {
|
if ( _Objects_Are_ids_equal( the_object->Object.id, the_id ) ) {
|
|
|
_Chain_Extract( the_node );
|
_Chain_Extract( the_node );
|
_Objects_MP_Free_global_object( the_object );
|
_Objects_MP_Free_global_object( the_object );
|
return;
|
return;
|
}
|
}
|
|
|
}
|
}
|
|
|
_Internal_error_Occurred(
|
_Internal_error_Occurred(
|
INTERNAL_ERROR_CORE,
|
INTERNAL_ERROR_CORE,
|
TRUE,
|
TRUE,
|
INTERNAL_ERROR_INVALID_GLOBAL_ID
|
INTERNAL_ERROR_INVALID_GLOBAL_ID
|
);
|
);
|
}
|
}
|
|
|
/*PAGE
|
/*PAGE
|
*
|
*
|
* _Objects_MP_Global_name_search
|
* _Objects_MP_Global_name_search
|
*
|
*
|
*/
|
*/
|
|
|
Objects_Name_to_id_errors _Objects_MP_Global_name_search (
|
Objects_Name_to_id_errors _Objects_MP_Global_name_search (
|
Objects_Information *information,
|
Objects_Information *information,
|
Objects_Name the_name,
|
Objects_Name the_name,
|
unsigned32 nodes_to_search,
|
unsigned32 nodes_to_search,
|
Objects_Id *the_id
|
Objects_Id *the_id
|
)
|
)
|
{
|
{
|
unsigned32 low_node;
|
unsigned32 low_node;
|
unsigned32 high_node;
|
unsigned32 high_node;
|
unsigned32 node_index;
|
unsigned32 node_index;
|
Chain_Control *the_chain;
|
Chain_Control *the_chain;
|
Chain_Node *the_node;
|
Chain_Node *the_node;
|
Objects_MP_Control *the_object;
|
Objects_MP_Control *the_object;
|
unsigned32 name_to_use = *(unsigned32 *)the_name; /* XXX variable */
|
unsigned32 name_to_use = *(unsigned32 *)the_name; /* XXX variable */
|
|
|
if ( nodes_to_search > _Objects_Maximum_nodes )
|
if ( nodes_to_search > _Objects_Maximum_nodes )
|
return OBJECTS_INVALID_NODE;
|
return OBJECTS_INVALID_NODE;
|
|
|
if ( information->global_table == NULL )
|
if ( information->global_table == NULL )
|
return OBJECTS_INVALID_NAME;
|
return OBJECTS_INVALID_NAME;
|
|
|
if ( nodes_to_search == OBJECTS_SEARCH_ALL_NODES ||
|
if ( nodes_to_search == OBJECTS_SEARCH_ALL_NODES ||
|
nodes_to_search == OBJECTS_SEARCH_OTHER_NODES ) {
|
nodes_to_search == OBJECTS_SEARCH_OTHER_NODES ) {
|
low_node = 1;
|
low_node = 1;
|
high_node = _Objects_Maximum_nodes;
|
high_node = _Objects_Maximum_nodes;
|
} else {
|
} else {
|
low_node =
|
low_node =
|
high_node = nodes_to_search;
|
high_node = nodes_to_search;
|
}
|
}
|
|
|
_Thread_Disable_dispatch();
|
_Thread_Disable_dispatch();
|
|
|
for ( node_index = low_node ; node_index <= high_node ; node_index++ ) {
|
for ( node_index = low_node ; node_index <= high_node ; node_index++ ) {
|
|
|
/*
|
/*
|
* NOTE: The local node was search (if necessary) by
|
* NOTE: The local node was search (if necessary) by
|
* _Objects_Name_to_id before this was invoked.
|
* _Objects_Name_to_id before this was invoked.
|
*/
|
*/
|
|
|
if ( !_Objects_Is_local_node( node_index ) ) {
|
if ( !_Objects_Is_local_node( node_index ) ) {
|
the_chain = &information->global_table[ node_index ];
|
the_chain = &information->global_table[ node_index ];
|
|
|
for ( the_node = the_chain->first ;
|
for ( the_node = the_chain->first ;
|
!_Chain_Is_tail( the_chain, the_node ) ;
|
!_Chain_Is_tail( the_chain, the_node ) ;
|
the_node = the_node->next ) {
|
the_node = the_node->next ) {
|
|
|
the_object = (Objects_MP_Control *) the_node;
|
the_object = (Objects_MP_Control *) the_node;
|
|
|
if ( the_object->name == name_to_use ) {
|
if ( the_object->name == name_to_use ) {
|
*the_id = the_object->Object.id;
|
*the_id = the_object->Object.id;
|
_Thread_Enable_dispatch();
|
_Thread_Enable_dispatch();
|
return OBJECTS_SUCCESSFUL;
|
return OBJECTS_SUCCESSFUL;
|
}
|
}
|
}
|
}
|
}
|
}
|
}
|
}
|
|
|
_Thread_Enable_dispatch();
|
_Thread_Enable_dispatch();
|
return OBJECTS_INVALID_NAME;
|
return OBJECTS_INVALID_NAME;
|
}
|
}
|
|
|
/*PAGE
|
/*PAGE
|
*
|
*
|
* _Objects_MP_Is_remote
|
* _Objects_MP_Is_remote
|
*
|
*
|
*/
|
*/
|
|
|
void _Objects_MP_Is_remote (
|
void _Objects_MP_Is_remote (
|
Objects_Information *information,
|
Objects_Information *information,
|
Objects_Id the_id,
|
Objects_Id the_id,
|
Objects_Locations *location,
|
Objects_Locations *location,
|
Objects_Control **the_object
|
Objects_Control **the_object
|
)
|
)
|
{
|
{
|
unsigned32 node;
|
unsigned32 node;
|
Chain_Control *the_chain;
|
Chain_Control *the_chain;
|
Chain_Node *the_node;
|
Chain_Node *the_node;
|
Objects_MP_Control *the_global_object;
|
Objects_MP_Control *the_global_object;
|
|
|
node = _Objects_Get_node( the_id );
|
node = _Objects_Get_node( the_id );
|
|
|
/*
|
/*
|
* NOTE: The local node was search (if necessary) by
|
* NOTE: The local node was search (if necessary) by
|
* _Objects_Name_to_id before this was invoked.
|
* _Objects_Name_to_id before this was invoked.
|
*
|
*
|
* The NODE field of an object id cannot be 0
|
* The NODE field of an object id cannot be 0
|
* because 0 is an invalid node number.
|
* because 0 is an invalid node number.
|
*/
|
*/
|
|
|
if ( node == 0 ||
|
if ( node == 0 ||
|
_Objects_Is_local_node( node ) ||
|
_Objects_Is_local_node( node ) ||
|
node > _Objects_Maximum_nodes ||
|
node > _Objects_Maximum_nodes ||
|
information->global_table == NULL ) {
|
information->global_table == NULL ) {
|
|
|
*location = OBJECTS_ERROR;
|
*location = OBJECTS_ERROR;
|
*the_object = NULL;
|
*the_object = NULL;
|
return;
|
return;
|
}
|
}
|
|
|
_Thread_Disable_dispatch();
|
_Thread_Disable_dispatch();
|
|
|
the_chain = &information->global_table[ node ];
|
the_chain = &information->global_table[ node ];
|
|
|
for ( the_node = the_chain->first ;
|
for ( the_node = the_chain->first ;
|
!_Chain_Is_tail( the_chain, the_node ) ;
|
!_Chain_Is_tail( the_chain, the_node ) ;
|
the_node = the_node->next ) {
|
the_node = the_node->next ) {
|
|
|
the_global_object = (Objects_MP_Control *) the_node;
|
the_global_object = (Objects_MP_Control *) the_node;
|
|
|
if ( _Objects_Are_ids_equal( the_global_object->Object.id, the_id ) ) {
|
if ( _Objects_Are_ids_equal( the_global_object->Object.id, the_id ) ) {
|
_Thread_Unnest_dispatch();
|
_Thread_Unnest_dispatch();
|
*location = OBJECTS_REMOTE;
|
*location = OBJECTS_REMOTE;
|
*the_object = (Objects_Control *) the_global_object;
|
*the_object = (Objects_Control *) the_global_object;
|
return;
|
return;
|
}
|
}
|
}
|
}
|
|
|
_Thread_Enable_dispatch();
|
_Thread_Enable_dispatch();
|
*location = OBJECTS_ERROR;
|
*location = OBJECTS_ERROR;
|
*the_object = NULL;
|
*the_object = NULL;
|
|
|
}
|
}
|
|
|