[ac7d5ef0] | 1 | /* |
---|
| 2 | * Object Handler |
---|
| 3 | * |
---|
| 4 | * |
---|
| 5 | * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. |
---|
| 6 | * On-Line Applications Research Corporation (OAR). |
---|
| 7 | * All rights assigned to U.S. Government, 1994. |
---|
| 8 | * |
---|
| 9 | * This material may be reproduced by or for the U.S. Government pursuant |
---|
| 10 | * to the copyright license under the clause at DFARS 252.227-7013. This |
---|
| 11 | * notice must appear in all copies of this file and its derivatives. |
---|
| 12 | * |
---|
| 13 | * $Id$ |
---|
| 14 | */ |
---|
[b06e68ef] | 15 | |
---|
[ac7d5ef0] | 16 | #include <rtems/system.h> |
---|
[3a4ae6c] | 17 | #include <rtems/core/chain.h> |
---|
| 18 | #include <rtems/core/object.h> |
---|
[be650a84] | 19 | #include <rtems/core/objectmp.h> |
---|
[3a4ae6c] | 20 | #include <rtems/core/thread.h> |
---|
| 21 | #include <rtems/core/wkspace.h> |
---|
[be650a84] | 22 | #include <rtems/core/sysstate.h> |
---|
[ac7d5ef0] | 23 | |
---|
| 24 | /*PAGE |
---|
| 25 | * |
---|
| 26 | * _Objects_Handler_initialization |
---|
| 27 | * |
---|
| 28 | * This routine initializes the object handler. |
---|
| 29 | * |
---|
| 30 | * Input parameters: |
---|
| 31 | * node - local node |
---|
[3a4ae6c] | 32 | * maximum_nodes - number of nodes in the system |
---|
[ac7d5ef0] | 33 | * maximum_global_objects - number of configured global objects |
---|
| 34 | * |
---|
| 35 | * Output parameters: NONE |
---|
| 36 | */ |
---|
| 37 | |
---|
| 38 | void _Objects_Handler_initialization( |
---|
| 39 | unsigned32 node, |
---|
[3a4ae6c] | 40 | unsigned32 maximum_nodes, |
---|
[ac7d5ef0] | 41 | unsigned32 maximum_global_objects |
---|
| 42 | ) |
---|
| 43 | { |
---|
[3a4ae6c] | 44 | if ( node < 1 || node > maximum_nodes ) |
---|
| 45 | _Internal_error_Occurred( |
---|
| 46 | INTERNAL_ERROR_CORE, |
---|
| 47 | TRUE, |
---|
| 48 | INTERNAL_ERROR_INVALID_NODE |
---|
| 49 | ); |
---|
| 50 | |
---|
| 51 | _Objects_Local_node = node; |
---|
| 52 | _Objects_Maximum_nodes = maximum_nodes; |
---|
[ac7d5ef0] | 53 | |
---|
[3a4ae6c] | 54 | _Objects_MP_Handler_initialization( |
---|
| 55 | node, |
---|
| 56 | maximum_nodes, |
---|
| 57 | maximum_global_objects |
---|
| 58 | ); |
---|
[ac7d5ef0] | 59 | } |
---|
| 60 | |
---|
| 61 | /*PAGE |
---|
| 62 | * |
---|
| 63 | * _Objects_Initialize_information |
---|
| 64 | * |
---|
| 65 | * This routine initializes all object information related data structures. |
---|
| 66 | * |
---|
| 67 | * Input parameters: |
---|
[9863dbf] | 68 | * information - object information table |
---|
| 69 | * the_class - object class |
---|
[ac7d5ef0] | 70 | * supports_global - TRUE if this is a global object class |
---|
| 71 | * maximum - maximum objects of this class |
---|
[3235ad9] | 72 | * is_string - TRUE if names for this object are strings |
---|
[ac7d5ef0] | 73 | * size - size of this object's control block |
---|
| 74 | * |
---|
| 75 | * Output parameters: NONE |
---|
| 76 | */ |
---|
| 77 | |
---|
| 78 | void _Objects_Initialize_information( |
---|
| 79 | Objects_Information *information, |
---|
[9863dbf] | 80 | Objects_Classes the_class, |
---|
| 81 | boolean supports_global, |
---|
| 82 | unsigned32 maximum, |
---|
[3235ad9] | 83 | unsigned32 size, |
---|
| 84 | boolean is_string, |
---|
[5250ff39] | 85 | unsigned32 maximum_name_length, |
---|
| 86 | boolean is_thread |
---|
[ac7d5ef0] | 87 | ) |
---|
| 88 | { |
---|
| 89 | unsigned32 minimum_index; |
---|
| 90 | unsigned32 index; |
---|
| 91 | Objects_Control *the_object; |
---|
[3235ad9] | 92 | unsigned32 name_length; |
---|
| 93 | void *name_area; |
---|
[ac7d5ef0] | 94 | |
---|
[9863dbf] | 95 | information->maximum = maximum; |
---|
| 96 | information->the_class = the_class; |
---|
[3235ad9] | 97 | information->is_string = is_string; |
---|
[5250ff39] | 98 | information->is_thread = is_thread; |
---|
| 99 | |
---|
| 100 | /* |
---|
| 101 | * Set the entry in the object information table. |
---|
| 102 | */ |
---|
| 103 | |
---|
| 104 | _Objects_Information_table[ the_class ] = information; |
---|
[3235ad9] | 105 | |
---|
| 106 | /* |
---|
| 107 | * Calculate minimum and maximum Id's |
---|
| 108 | */ |
---|
[ac7d5ef0] | 109 | |
---|
| 110 | if ( maximum == 0 ) minimum_index = 0; |
---|
| 111 | else minimum_index = 1; |
---|
| 112 | |
---|
| 113 | information->minimum_id = |
---|
[9863dbf] | 114 | _Objects_Build_id( the_class, _Objects_Local_node, minimum_index ); |
---|
[ac7d5ef0] | 115 | |
---|
| 116 | information->maximum_id = |
---|
[9863dbf] | 117 | _Objects_Build_id( the_class, _Objects_Local_node, maximum ); |
---|
[ac7d5ef0] | 118 | |
---|
[3235ad9] | 119 | /* |
---|
| 120 | * Allocate local pointer table |
---|
| 121 | */ |
---|
| 122 | |
---|
[ac7d5ef0] | 123 | information->local_table = _Workspace_Allocate_or_fatal_error( |
---|
| 124 | (maximum + 1) * sizeof(Objects_Control *) |
---|
| 125 | ); |
---|
| 126 | |
---|
[3235ad9] | 127 | /* |
---|
| 128 | * Allocate name table |
---|
| 129 | */ |
---|
| 130 | |
---|
| 131 | name_length = maximum_name_length; |
---|
| 132 | |
---|
| 133 | if (name_length & (OBJECTS_NAME_ALIGNMENT-1)) |
---|
| 134 | name_length = (name_length + OBJECTS_NAME_ALIGNMENT) & |
---|
| 135 | ~(OBJECTS_NAME_ALIGNMENT-1); |
---|
| 136 | |
---|
| 137 | information->name_length = name_length; |
---|
| 138 | |
---|
| 139 | name_area = _Workspace_Allocate_or_fatal_error( (maximum + 1) * name_length ); |
---|
| 140 | information->name_table = name_area; |
---|
| 141 | |
---|
| 142 | /* |
---|
| 143 | * Initialize local pointer table |
---|
| 144 | */ |
---|
[ac7d5ef0] | 145 | |
---|
[3235ad9] | 146 | for ( index=0 ; index <= maximum ; index++ ) { |
---|
[ac7d5ef0] | 147 | information->local_table[ index ] = NULL; |
---|
| 148 | } |
---|
| 149 | |
---|
[3235ad9] | 150 | /* |
---|
| 151 | * Initialize objects .. if there are any |
---|
| 152 | */ |
---|
| 153 | |
---|
[ac7d5ef0] | 154 | if ( maximum == 0 ) { |
---|
| 155 | _Chain_Initialize_empty( &information->Inactive ); |
---|
| 156 | } else { |
---|
| 157 | |
---|
| 158 | _Chain_Initialize( |
---|
| 159 | &information->Inactive, |
---|
| 160 | _Workspace_Allocate_or_fatal_error( maximum * size ), |
---|
| 161 | maximum, |
---|
| 162 | size |
---|
| 163 | ); |
---|
| 164 | |
---|
| 165 | the_object = (Objects_Control *) information->Inactive.first; |
---|
[3235ad9] | 166 | for ( index=1; index <= maximum ; index++ ) { |
---|
[9863dbf] | 167 | the_object->id = |
---|
| 168 | _Objects_Build_id( the_class, _Objects_Local_node, index ); |
---|
[3235ad9] | 169 | |
---|
| 170 | the_object->name = (void *) name_area; |
---|
| 171 | |
---|
| 172 | name_area = _Addresses_Add_offset( name_area, name_length ); |
---|
| 173 | |
---|
[ac7d5ef0] | 174 | the_object = (Objects_Control *) the_object->Node.next; |
---|
| 175 | } |
---|
| 176 | |
---|
| 177 | } |
---|
| 178 | |
---|
[3235ad9] | 179 | /* |
---|
| 180 | * Take care of multiprocessing |
---|
| 181 | */ |
---|
[ac7d5ef0] | 182 | |
---|
[3a4ae6c] | 183 | if ( supports_global == TRUE && _System_state_Is_multiprocessing ) { |
---|
[ac7d5ef0] | 184 | |
---|
[3235ad9] | 185 | information->global_table = _Workspace_Allocate_or_fatal_error( |
---|
[3a4ae6c] | 186 | (_Objects_Maximum_nodes + 1) * sizeof(Chain_Control) |
---|
[3235ad9] | 187 | ); |
---|
| 188 | |
---|
[3a4ae6c] | 189 | for ( index=1; index <= _Objects_Maximum_nodes ; index++ ) |
---|
[3235ad9] | 190 | _Chain_Initialize_empty( &information->global_table[ index ] ); |
---|
| 191 | } |
---|
| 192 | else |
---|
| 193 | information->global_table = NULL; |
---|
| 194 | } |
---|
| 195 | |
---|
| 196 | /*PAGE |
---|
| 197 | * |
---|
| 198 | * _Objects_Clear_name |
---|
| 199 | * |
---|
| 200 | * XXX |
---|
| 201 | */ |
---|
| 202 | |
---|
| 203 | void _Objects_Clear_name( |
---|
| 204 | void *name, |
---|
| 205 | unsigned32 length |
---|
| 206 | ) |
---|
| 207 | { |
---|
| 208 | unsigned32 index; |
---|
| 209 | unsigned32 maximum = length / OBJECTS_NAME_ALIGNMENT; |
---|
| 210 | unsigned32 *name_ptr = name; |
---|
| 211 | |
---|
| 212 | for ( index=0 ; index < maximum ; index++ ) |
---|
| 213 | *name_ptr++ = 0; |
---|
| 214 | } |
---|
| 215 | |
---|
| 216 | /*PAGE |
---|
| 217 | * |
---|
| 218 | * _Objects_Copy_name_string |
---|
| 219 | * |
---|
| 220 | * XXX |
---|
| 221 | */ |
---|
| 222 | |
---|
| 223 | void _Objects_Copy_name_string( |
---|
| 224 | void *source, |
---|
| 225 | void *destination |
---|
| 226 | ) |
---|
| 227 | { |
---|
| 228 | unsigned8 *source_p = source; |
---|
| 229 | unsigned8 *destination_p = destination; |
---|
| 230 | |
---|
| 231 | do { |
---|
| 232 | *destination_p++ = *source_p; |
---|
| 233 | } while ( *source_p++ ); |
---|
| 234 | } |
---|
| 235 | |
---|
| 236 | /*PAGE |
---|
| 237 | * |
---|
| 238 | * _Objects_Copy_name_raw |
---|
| 239 | * |
---|
| 240 | * XXX |
---|
| 241 | */ |
---|
| 242 | |
---|
| 243 | void _Objects_Copy_name_raw( |
---|
| 244 | void *source, |
---|
| 245 | void *destination, |
---|
| 246 | unsigned32 length |
---|
| 247 | ) |
---|
| 248 | { |
---|
| 249 | unsigned32 *source_p = source; |
---|
| 250 | unsigned32 *destination_p = destination; |
---|
| 251 | unsigned32 tmp_length = length / OBJECTS_NAME_ALIGNMENT; |
---|
| 252 | |
---|
| 253 | while ( tmp_length-- ) |
---|
| 254 | *destination_p++ = *source_p++; |
---|
| 255 | } |
---|
| 256 | |
---|
| 257 | /*PAGE |
---|
| 258 | * |
---|
| 259 | * _Objects_Compare_name_string |
---|
| 260 | * |
---|
| 261 | * XXX |
---|
| 262 | */ |
---|
| 263 | |
---|
| 264 | boolean _Objects_Compare_name_string( |
---|
| 265 | void *name_1, |
---|
| 266 | void *name_2, |
---|
| 267 | unsigned32 length |
---|
| 268 | ) |
---|
| 269 | { |
---|
| 270 | unsigned8 *name_1_p = name_1; |
---|
| 271 | unsigned8 *name_2_p = name_2; |
---|
| 272 | unsigned32 tmp_length = length; |
---|
| 273 | |
---|
| 274 | do { |
---|
| 275 | if ( *name_1_p++ != *name_2_p++ ) |
---|
| 276 | return FALSE; |
---|
| 277 | if ( !tmp_length-- ) |
---|
| 278 | return FALSE; |
---|
| 279 | } while ( *name_1_p ); |
---|
| 280 | |
---|
| 281 | return TRUE; |
---|
| 282 | } |
---|
| 283 | |
---|
| 284 | /*PAGE |
---|
| 285 | * |
---|
| 286 | * _Objects_Compare_name_raw |
---|
| 287 | * |
---|
| 288 | * XXX |
---|
| 289 | */ |
---|
| 290 | |
---|
| 291 | boolean _Objects_Compare_name_raw( |
---|
| 292 | void *name_1, |
---|
| 293 | void *name_2, |
---|
| 294 | unsigned32 length |
---|
| 295 | ) |
---|
| 296 | { |
---|
| 297 | unsigned32 *name_1_p = name_1; |
---|
| 298 | unsigned32 *name_2_p = name_2; |
---|
| 299 | unsigned32 tmp_length = length / OBJECTS_NAME_ALIGNMENT; |
---|
| 300 | |
---|
| 301 | while ( tmp_length-- ) |
---|
| 302 | if ( *name_1_p++ != *name_2_p++ ) |
---|
| 303 | return FALSE; |
---|
| 304 | |
---|
| 305 | return TRUE; |
---|
[ac7d5ef0] | 306 | } |
---|
| 307 | |
---|
[3235ad9] | 308 | |
---|
[ac7d5ef0] | 309 | /*PAGE |
---|
| 310 | * |
---|
| 311 | * _Objects_Name_to_id |
---|
| 312 | * |
---|
| 313 | * These kernel routines search the object table(s) for the given |
---|
| 314 | * object name and returns the associated object id. |
---|
| 315 | * |
---|
| 316 | * Input parameters: |
---|
| 317 | * information - object information |
---|
| 318 | * name - user defined object name |
---|
| 319 | * node - node indentifier (0 indicates any node) |
---|
| 320 | * id - address of return ID |
---|
| 321 | * |
---|
| 322 | * Output parameters: |
---|
[3a4ae6c] | 323 | * id - object id |
---|
| 324 | * OBJECTS_SUCCESSFUL - if successful |
---|
| 325 | * error code - if unsuccessful |
---|
[ac7d5ef0] | 326 | */ |
---|
| 327 | |
---|
[3a4ae6c] | 328 | Objects_Name_to_id_errors _Objects_Name_to_id( |
---|
[ac7d5ef0] | 329 | Objects_Information *information, |
---|
[3235ad9] | 330 | Objects_Name name, |
---|
| 331 | unsigned32 node, |
---|
| 332 | Objects_Id *id |
---|
[ac7d5ef0] | 333 | ) |
---|
| 334 | { |
---|
[3235ad9] | 335 | boolean search_local_node; |
---|
| 336 | Objects_Control **objects; |
---|
| 337 | Objects_Control *the_object; |
---|
| 338 | unsigned32 index; |
---|
| 339 | unsigned32 name_length; |
---|
| 340 | Objects_Name_comparators compare_them; |
---|
[ac7d5ef0] | 341 | |
---|
| 342 | if ( name == 0 ) |
---|
[3a4ae6c] | 343 | return OBJECTS_INVALID_NAME; |
---|
[ac7d5ef0] | 344 | |
---|
[61361688] | 345 | search_local_node = FALSE; |
---|
| 346 | |
---|
| 347 | if ( information->maximum != 0 && |
---|
[3a4ae6c] | 348 | (node == OBJECTS_SEARCH_ALL_NODES || node == OBJECTS_SEARCH_LOCAL_NODE || |
---|
[61361688] | 349 | _Objects_Is_local_node( node ) ) ) |
---|
| 350 | search_local_node = TRUE; |
---|
| 351 | |
---|
| 352 | if ( search_local_node ) { |
---|
| 353 | objects = information->local_table; |
---|
| 354 | |
---|
[3235ad9] | 355 | name_length = information->name_length; |
---|
| 356 | |
---|
| 357 | if ( information->is_string ) compare_them = _Objects_Compare_name_string; |
---|
| 358 | else compare_them = _Objects_Compare_name_raw; |
---|
| 359 | |
---|
[61361688] | 360 | for ( index = 1; index <= information->maximum; index++ ) { |
---|
| 361 | |
---|
| 362 | the_object = objects[ index ]; |
---|
| 363 | |
---|
| 364 | if ( !the_object || !the_object->name ) |
---|
| 365 | continue; |
---|
| 366 | |
---|
[3235ad9] | 367 | if ( (*compare_them)( name, the_object->name, name_length ) ) { |
---|
[61361688] | 368 | *id = the_object->id; |
---|
[3a4ae6c] | 369 | return OBJECTS_SUCCESSFUL; |
---|
[ac7d5ef0] | 370 | } |
---|
[61361688] | 371 | } |
---|
[ac7d5ef0] | 372 | } |
---|
| 373 | |
---|
[3a4ae6c] | 374 | if ( _Objects_Is_local_node( node ) || node == OBJECTS_SEARCH_LOCAL_NODE ) |
---|
| 375 | return OBJECTS_INVALID_NAME; |
---|
[ac7d5ef0] | 376 | |
---|
| 377 | return ( _Objects_MP_Global_name_search( information, name, node, id ) ); |
---|
| 378 | } |
---|
| 379 | |
---|
| 380 | /*PAGE |
---|
| 381 | * |
---|
| 382 | * _Objects_Get |
---|
| 383 | * |
---|
| 384 | * This routine sets the object pointer for the given |
---|
| 385 | * object id based on the given object information structure. |
---|
| 386 | * |
---|
| 387 | * Input parameters: |
---|
| 388 | * information - pointer to entry in table for this class |
---|
| 389 | * id - object id to search for |
---|
| 390 | * location - address of where to store the location |
---|
| 391 | * |
---|
| 392 | * Output parameters: |
---|
| 393 | * returns - address of object if local |
---|
| 394 | * location - one of the following: |
---|
| 395 | * OBJECTS_ERROR - invalid object ID |
---|
| 396 | * OBJECTS_REMOTE - remote object |
---|
| 397 | * OBJECTS_LOCAL - local object |
---|
| 398 | */ |
---|
| 399 | |
---|
| 400 | Objects_Control *_Objects_Get( |
---|
| 401 | Objects_Information *information, |
---|
[5250ff39] | 402 | Objects_Id id, |
---|
| 403 | Objects_Locations *location |
---|
[ac7d5ef0] | 404 | ) |
---|
| 405 | { |
---|
| 406 | Objects_Control *the_object; |
---|
| 407 | unsigned32 index; |
---|
| 408 | |
---|
| 409 | index = id - information->minimum_id; |
---|
[9863dbf] | 410 | |
---|
[ac7d5ef0] | 411 | if ( information->maximum >= index ) { |
---|
| 412 | _Thread_Disable_dispatch(); |
---|
| 413 | if ( (the_object = information->local_table[index+1]) != NULL ) { |
---|
| 414 | *location = OBJECTS_LOCAL; |
---|
| 415 | return( the_object ); |
---|
| 416 | } |
---|
| 417 | _Thread_Enable_dispatch(); |
---|
| 418 | *location = OBJECTS_ERROR; |
---|
| 419 | return( NULL ); |
---|
| 420 | } |
---|
| 421 | *location = OBJECTS_ERROR; |
---|
| 422 | _Objects_MP_Is_remote( information, id, location, &the_object ); |
---|
| 423 | return the_object; |
---|
| 424 | } |
---|
[b06e68ef] | 425 | |
---|
| 426 | |
---|
| 427 | /*PAGE |
---|
| 428 | * |
---|
| 429 | * _Objects_Get_next |
---|
| 430 | * |
---|
| 431 | * Like _Objects_Get, but considers the 'id' as a "hint" and |
---|
| 432 | * finds next valid one after that point. |
---|
| 433 | * Mostly used for monitor and debug traversal of an object. |
---|
| 434 | * |
---|
| 435 | * Input parameters: |
---|
| 436 | * information - pointer to entry in table for this class |
---|
| 437 | * id - object id to search for |
---|
| 438 | * location - address of where to store the location |
---|
| 439 | * next_id - address to store next id to try |
---|
| 440 | * |
---|
| 441 | * Output parameters: |
---|
| 442 | * returns - address of object if local |
---|
| 443 | * location - one of the following: |
---|
| 444 | * OBJECTS_ERROR - invalid object ID |
---|
| 445 | * OBJECTS_REMOTE - remote object |
---|
| 446 | * OBJECTS_LOCAL - local object |
---|
| 447 | * next_id - will contain a reasonable "next" id to continue traversal |
---|
| 448 | * |
---|
| 449 | * NOTE: |
---|
| 450 | * assumes can add '1' to an id to get to next index. |
---|
| 451 | */ |
---|
| 452 | |
---|
| 453 | Objects_Control * |
---|
| 454 | _Objects_Get_next( |
---|
| 455 | Objects_Information *information, |
---|
| 456 | Objects_Id id, |
---|
| 457 | unsigned32 *location_p, |
---|
| 458 | Objects_Id *next_id_p |
---|
| 459 | ) |
---|
| 460 | { |
---|
| 461 | Objects_Control *object; |
---|
| 462 | Objects_Id next_id; |
---|
| 463 | |
---|
[3a4ae6c] | 464 | if (_Objects_Get_index(id) == OBJECTS_ID_INITIAL_INDEX) |
---|
[b06e68ef] | 465 | next_id = information->minimum_id; |
---|
| 466 | else |
---|
| 467 | next_id = id; |
---|
| 468 | |
---|
| 469 | do { |
---|
| 470 | /* walked off end of list? */ |
---|
[3a4ae6c] | 471 | if (_Objects_Get_index(next_id) > information->maximum) |
---|
[b06e68ef] | 472 | { |
---|
| 473 | *location_p = OBJECTS_ERROR; |
---|
| 474 | goto final; |
---|
| 475 | } |
---|
| 476 | |
---|
| 477 | /* try to grab one */ |
---|
| 478 | object = _Objects_Get(information, next_id, location_p); |
---|
| 479 | |
---|
| 480 | next_id++; |
---|
| 481 | |
---|
| 482 | } while (*location_p != OBJECTS_LOCAL); |
---|
| 483 | |
---|
| 484 | *next_id_p = next_id; |
---|
| 485 | return object; |
---|
| 486 | |
---|
| 487 | final: |
---|
[3a4ae6c] | 488 | *next_id_p = OBJECTS_ID_FINAL; |
---|
[b06e68ef] | 489 | return 0; |
---|
| 490 | } |
---|
[7f6a24ab] | 491 | |
---|
| 492 | /*PAGE |
---|
| 493 | * |
---|
| 494 | * _Objects_Get_information |
---|
| 495 | * |
---|
| 496 | * XXX |
---|
| 497 | */ |
---|
| 498 | |
---|
| 499 | Objects_Information *_Objects_Get_information( |
---|
| 500 | Objects_Id id |
---|
| 501 | ) |
---|
| 502 | { |
---|
| 503 | Objects_Classes the_class; |
---|
| 504 | |
---|
[3a4ae6c] | 505 | the_class = _Objects_Get_class( id ); |
---|
[7f6a24ab] | 506 | |
---|
| 507 | if ( !_Objects_Is_class_valid( the_class ) ) |
---|
| 508 | return NULL; |
---|
| 509 | |
---|
| 510 | return _Objects_Information_table[ the_class ]; |
---|
| 511 | } |
---|
| 512 | |
---|