File indexing completed on 2025-05-11 08:24:26
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045 #ifdef HAVE_CONFIG_H
0046 #include "config.h"
0047 #endif
0048
0049 #include <rtems/score/objectimpl.h>
0050 #include <rtems/score/interr.h>
0051 #include <rtems/score/isrlock.h>
0052 #include <rtems/config.h>
0053
0054 #define OBJECTS_MP_CONTROL_OF_ID_LOOKUP_NODE( node ) \
0055 RTEMS_CONTAINER_OF( node, Objects_MP_Control, Nodes.Active.Id_lookup )
0056
0057 #define OBJECTS_MP_CONTROL_OF_NAME_LOOKUP_NODE( node ) \
0058 RTEMS_CONTAINER_OF( node, Objects_MP_Control, Nodes.Active.Name_lookup )
0059
0060 typedef struct {
0061 uint32_t name;
0062 uint32_t node;
0063 } Objects_MP_Name_and_node;
0064
0065 uint16_t _Objects_Local_node;
0066
0067 uint16_t _Objects_Maximum_nodes;
0068
0069 uint32_t _Objects_MP_Maximum_global_objects;
0070
0071 static CHAIN_DEFINE_EMPTY( _Objects_MP_Inactive_global_objects );
0072
0073 #if ISR_LOCK_NEEDS_OBJECT
0074 static ISR_lock_Control _Objects_MP_Global_lock =
0075 ISR_LOCK_INITIALIZER( "MP Objects" );
0076 #endif
0077
0078 static void _Objects_MP_Global_acquire( ISR_lock_Context *lock_context )
0079 {
0080 _ISR_lock_ISR_disable_and_acquire( &_Objects_MP_Global_lock, lock_context );
0081 }
0082
0083 static void _Objects_MP_Global_release( ISR_lock_Context *lock_context )
0084 {
0085 _ISR_lock_Release_and_ISR_enable( &_Objects_MP_Global_lock, lock_context );
0086 }
0087
0088 static bool _Objects_MP_Id_equal(
0089 const void *left,
0090 const RBTree_Node *right
0091 )
0092 {
0093 const Objects_Id *the_left;
0094 const Objects_MP_Control *the_right;
0095
0096 the_left = left;
0097 the_right = OBJECTS_MP_CONTROL_OF_ID_LOOKUP_NODE( right );
0098
0099 return *the_left == the_right->id;
0100 }
0101
0102 static bool _Objects_MP_Id_less(
0103 const void *left,
0104 const RBTree_Node *right
0105 )
0106 {
0107 const Objects_Id *the_left;
0108 const Objects_MP_Control *the_right;
0109
0110 the_left = left;
0111 the_right = OBJECTS_MP_CONTROL_OF_ID_LOOKUP_NODE( right );
0112
0113 return *the_left < the_right->id;
0114 }
0115
0116 static void *_Objects_MP_Id_map( RBTree_Node *node )
0117 {
0118 return OBJECTS_MP_CONTROL_OF_ID_LOOKUP_NODE( node );
0119 }
0120
0121 static bool _Objects_MP_Name_equal(
0122 const void *left,
0123 const RBTree_Node *right
0124 )
0125 {
0126 const uint32_t *the_left;
0127 const Objects_MP_Control *the_right;
0128
0129 the_left = left;
0130 the_right = OBJECTS_MP_CONTROL_OF_NAME_LOOKUP_NODE( right );
0131
0132 return *the_left == the_right->name;
0133 }
0134
0135 static bool _Objects_MP_Name_less(
0136 const void *left,
0137 const RBTree_Node *right
0138 )
0139 {
0140 const uint32_t *the_left;
0141 const Objects_MP_Control *the_right;
0142
0143 the_left = left;
0144 the_right = OBJECTS_MP_CONTROL_OF_NAME_LOOKUP_NODE( right );
0145
0146 return *the_left < the_right->name;
0147 }
0148
0149 static void *_Objects_MP_Name_map( RBTree_Node *node )
0150 {
0151 return OBJECTS_MP_CONTROL_OF_NAME_LOOKUP_NODE( node );
0152 }
0153
0154 static bool _Objects_MP_Name_and_node_equal(
0155 const void *left,
0156 const RBTree_Node *right
0157 )
0158 {
0159 const Objects_MP_Name_and_node *the_left;
0160 const Objects_MP_Control *the_right;
0161
0162 the_left = left;
0163 the_right = OBJECTS_MP_CONTROL_OF_NAME_LOOKUP_NODE( right );
0164
0165 return the_left->name == the_right->name
0166 && the_left->node == _Objects_Get_node( the_right->id );
0167 }
0168
0169 static bool _Objects_MP_Name_and_node_less(
0170 const void *left,
0171 const RBTree_Node *right
0172 )
0173 {
0174 const Objects_MP_Name_and_node *the_left;
0175 const Objects_MP_Control *the_right;
0176
0177 the_left = left;
0178 the_right = OBJECTS_MP_CONTROL_OF_NAME_LOOKUP_NODE( right );
0179
0180
0181
0182
0183
0184 return the_left->name < the_right->name
0185 || ( the_left->name == the_right->name
0186 && the_left->node > _Objects_Get_node( the_right->id ) );
0187 }
0188
0189 void _Objects_MP_Handler_early_initialization(void)
0190 {
0191 uint32_t node;
0192 uint32_t maximum_nodes;
0193
0194 node = _MPCI_Configuration.node;
0195 maximum_nodes = _MPCI_Configuration.maximum_nodes;
0196
0197 if ( node < 1 || node > maximum_nodes )
0198 _Internal_error( INTERNAL_ERROR_INVALID_NODE );
0199
0200 _Objects_Local_node = node;
0201 _Objects_Maximum_nodes = maximum_nodes;
0202 }
0203
0204 void _Objects_MP_Handler_initialization( void )
0205 {
0206 uint32_t maximum_global_objects;
0207
0208 maximum_global_objects = _MPCI_Configuration.maximum_global_objects;
0209
0210 _Objects_MP_Maximum_global_objects = maximum_global_objects;
0211
0212 if ( maximum_global_objects == 0 ) {
0213 return;
0214 }
0215
0216 _Chain_Initialize(
0217 &_Objects_MP_Inactive_global_objects,
0218 &_Objects_MP_Controls[ 0 ],
0219 maximum_global_objects,
0220 sizeof( _Objects_MP_Controls[ 0 ] )
0221 );
0222 }
0223
0224 void _Objects_MP_Open (
0225 Objects_Information *information,
0226 Objects_MP_Control *the_global_object,
0227 uint32_t the_name,
0228 Objects_Id the_id
0229 )
0230 {
0231 Objects_MP_Name_and_node name_and_node;
0232 ISR_lock_Context lock_context;
0233
0234 the_global_object->id = the_id;
0235 the_global_object->name = the_name;
0236
0237 name_and_node.name = the_name;
0238 name_and_node.node = _Objects_Get_node( the_id );
0239
0240 _Objects_MP_Global_acquire( &lock_context );
0241
0242 _RBTree_Insert_inline(
0243 &information->Global_by_id,
0244 &the_global_object->Nodes.Active.Id_lookup,
0245 &the_id,
0246 _Objects_MP_Id_less
0247 );
0248 _RBTree_Insert_inline(
0249 &information->Global_by_name,
0250 &the_global_object->Nodes.Active.Name_lookup,
0251 &name_and_node,
0252 _Objects_MP_Name_and_node_less
0253 );
0254
0255 _Objects_MP_Global_release( &lock_context );
0256 }
0257
0258 bool _Objects_MP_Allocate_and_open (
0259 Objects_Information *information,
0260 uint32_t the_name,
0261 Objects_Id the_id,
0262 bool is_fatal_error
0263 )
0264 {
0265 Objects_MP_Control *the_global_object;
0266
0267 the_global_object = _Objects_MP_Allocate_global_object();
0268
0269 if ( the_global_object == NULL ) {
0270 if ( !is_fatal_error ) {
0271 return false;
0272 }
0273
0274 _Internal_error( INTERNAL_ERROR_OUT_OF_GLOBAL_OBJECTS );
0275 }
0276
0277 _Objects_MP_Open( information, the_global_object, the_name, the_id );
0278
0279 return true;
0280 }
0281
0282 void _Objects_MP_Close (
0283 Objects_Information *information,
0284 Objects_Id the_id
0285 )
0286 {
0287 Objects_MP_Control *the_global_object;
0288 ISR_lock_Context lock_context;
0289
0290 _Objects_MP_Global_acquire( &lock_context );
0291
0292 the_global_object = _RBTree_Find_inline(
0293 &information->Global_by_id,
0294 &the_id,
0295 _Objects_MP_Id_equal,
0296 _Objects_MP_Id_less,
0297 _Objects_MP_Id_map
0298 );
0299
0300 if ( the_global_object != NULL ) {
0301 _RBTree_Extract(
0302 &information->Global_by_id,
0303 &the_global_object->Nodes.Active.Id_lookup
0304 );
0305 _RBTree_Extract(
0306 &information->Global_by_name,
0307 &the_global_object->Nodes.Active.Name_lookup
0308 );
0309 _Objects_MP_Free_global_object( the_global_object );
0310 _Objects_MP_Global_release( &lock_context );
0311 } else {
0312 _Objects_MP_Global_release( &lock_context );
0313
0314 _Internal_error( INTERNAL_ERROR_INVALID_GLOBAL_ID );
0315 }
0316 }
0317
0318 Status_Control _Objects_MP_Global_name_search(
0319 const Objects_Information *information,
0320 Objects_Name the_name,
0321 uint32_t nodes_to_search,
0322 Objects_Id *the_id
0323 )
0324 {
0325 Status_Control status;
0326 Objects_MP_Control *the_global_object;
0327 ISR_lock_Context lock_context;
0328
0329 if ( nodes_to_search > _Objects_Maximum_nodes ) {
0330 return STATUS_INVALID_NODE;
0331 }
0332
0333 _Objects_MP_Global_acquire( &lock_context );
0334
0335 if ( nodes_to_search == OBJECTS_SEARCH_ALL_NODES ) {
0336 the_global_object = _RBTree_Find_inline(
0337 &information->Global_by_name,
0338 &the_name.name_u32,
0339 _Objects_MP_Name_equal,
0340 _Objects_MP_Name_less,
0341 _Objects_MP_Name_map
0342 );
0343 } else {
0344 Objects_MP_Name_and_node name_and_node;
0345
0346 name_and_node.name = the_name.name_u32;
0347 name_and_node.node = nodes_to_search;
0348
0349 the_global_object = _RBTree_Find_inline(
0350 &information->Global_by_name,
0351 &name_and_node,
0352 _Objects_MP_Name_and_node_equal,
0353 _Objects_MP_Name_and_node_less,
0354 _Objects_MP_Name_map
0355 );
0356 }
0357
0358 if ( the_global_object != NULL ) {
0359 *the_id = the_global_object->id;
0360 _Assert( the_global_object->name != 0 );
0361 status = STATUS_SUCCESSFUL;
0362 } else {
0363 status = STATUS_INVALID_NAME;
0364 }
0365
0366 _Objects_MP_Global_release( &lock_context );
0367
0368 return status;
0369 }
0370
0371 bool _Objects_MP_Is_remote(
0372 Objects_Id the_id,
0373 const Objects_Information *information
0374 )
0375 {
0376 Objects_MP_Control *the_global_object;
0377 ISR_lock_Context lock_context;
0378
0379 _Objects_MP_Global_acquire( &lock_context );
0380
0381 the_global_object = _RBTree_Find_inline(
0382 &information->Global_by_id,
0383 &the_id,
0384 _Objects_MP_Id_equal,
0385 _Objects_MP_Id_less,
0386 _Objects_MP_Id_map
0387 );
0388
0389 _Objects_MP_Global_release( &lock_context );
0390
0391 return the_global_object != NULL;
0392 }
0393
0394 Objects_MP_Control *_Objects_MP_Allocate_global_object( void )
0395 {
0396 Objects_MP_Control *the_global_object;
0397 ISR_lock_Context lock_context;
0398
0399 _Objects_MP_Global_acquire( &lock_context );
0400
0401 the_global_object = (Objects_MP_Control *)
0402 _Chain_Get_unprotected( &_Objects_MP_Inactive_global_objects );
0403
0404 _Objects_MP_Global_release( &lock_context );
0405 return the_global_object;
0406 }
0407
0408 void _Objects_MP_Free_global_object( Objects_MP_Control *the_global_object )
0409 {
0410 ISR_lock_Context lock_context;
0411
0412 _Objects_MP_Global_acquire( &lock_context );
0413
0414 _Chain_Initialize_node( &the_global_object->Nodes.Inactive );
0415 _Chain_Append_unprotected(
0416 &_Objects_MP_Inactive_global_objects,
0417 &the_global_object->Nodes.Inactive
0418 );
0419
0420 _Objects_MP_Global_release( &lock_context );
0421 }