![]() |
|
|||
File indexing completed on 2025-05-11 08:24:13
0001 /* SPDX-License-Identifier: BSD-2-Clause */ 0002 0003 /** 0004 * @file 0005 * 0006 * @ingroup RTEMSScoreObject 0007 * 0008 * @brief This header file provides interfaces of the 0009 * @ref RTEMSScoreObject which are only used by the implementation. 0010 */ 0011 0012 /* 0013 * COPYRIGHT (c) 1989-2011. 0014 * On-Line Applications Research Corporation (OAR). 0015 * 0016 * Redistribution and use in source and binary forms, with or without 0017 * modification, are permitted provided that the following conditions 0018 * are met: 0019 * 1. Redistributions of source code must retain the above copyright 0020 * notice, this list of conditions and the following disclaimer. 0021 * 2. Redistributions in binary form must reproduce the above copyright 0022 * notice, this list of conditions and the following disclaimer in the 0023 * documentation and/or other materials provided with the distribution. 0024 * 0025 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 0026 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 0027 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 0028 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 0029 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 0030 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 0031 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 0032 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 0033 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 0034 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 0035 * POSSIBILITY OF SUCH DAMAGE. 0036 */ 0037 0038 #ifndef _RTEMS_SCORE_OBJECTIMPL_H 0039 #define _RTEMS_SCORE_OBJECTIMPL_H 0040 0041 #include <rtems/score/objectdata.h> 0042 #include <rtems/score/apimutex.h> 0043 #include <rtems/score/assert.h> 0044 #include <rtems/score/isrlock.h> 0045 #include <rtems/score/status.h> 0046 #include <rtems/score/sysstate.h> 0047 #include <rtems/score/threaddispatch.h> 0048 0049 #ifdef __cplusplus 0050 extern "C" { 0051 #endif 0052 0053 /** 0054 * @addtogroup RTEMSScoreObject 0055 * 0056 * @{ 0057 */ 0058 0059 /** 0060 * Functions which compare names are prototyped like this. 0061 */ 0062 typedef bool (*Objects_Name_comparators)( 0063 void * /* name_1 */, 0064 void * /* name_2 */, 0065 uint16_t /* length */ 0066 ); 0067 0068 /** This macro is used to generically specify the last API index. */ 0069 #define OBJECTS_INTERNAL_CLASSES_LAST OBJECTS_INTERNAL_THREADS 0070 0071 /** This macro is used to generically specify the last API index. */ 0072 #define OBJECTS_RTEMS_CLASSES_LAST OBJECTS_RTEMS_BARRIERS 0073 0074 /** This macro is used to generically specify the last API index. */ 0075 #define OBJECTS_POSIX_CLASSES_LAST OBJECTS_POSIX_SHMS 0076 0077 /* 0078 * For fake objects, which have an object identifier, but no objects 0079 * information block. 0080 */ 0081 typedef enum { 0082 OBJECTS_FAKE_OBJECTS_NO_CLASS = 0, 0083 OBJECTS_FAKE_OBJECTS_SCHEDULERS = 1 0084 } Objects_Fake_objects_API; 0085 0086 /** 0087 * The following is referenced to the number of nodes in the system. 0088 */ 0089 #if defined(RTEMS_MULTIPROCESSING) 0090 extern uint16_t _Objects_Maximum_nodes; 0091 #else 0092 #define _Objects_Maximum_nodes 1 0093 #endif 0094 0095 /** 0096 * This is the minimum object ID index associated with an object. 0097 */ 0098 #define OBJECTS_INDEX_MINIMUM 1U 0099 0100 /** 0101 * The following is the list of information blocks per API for each object 0102 * class. From the ID, we can go to one of these information blocks, 0103 * and obtain a pointer to the appropriate object control block. 0104 */ 0105 extern Objects_Information ** const 0106 _Objects_Information_table[ OBJECTS_APIS_LAST + 1 ]; 0107 0108 /** 0109 * @brief Extends an object class information record. 0110 * 0111 * @param information Points to an object class information block. 0112 * 0113 * @retval 0 The extend operation failed. 0114 * @retval block The block index of the new objects block. 0115 */ 0116 Objects_Maximum _Objects_Extend_information( 0117 Objects_Information *information 0118 ); 0119 0120 /** 0121 * @brief Free the objects block with the specified index. 0122 * 0123 * @param information The objects information. 0124 * @param block The block index. 0125 */ 0126 void _Objects_Free_objects_block( 0127 Objects_Information *information, 0128 Objects_Maximum block 0129 ); 0130 0131 /** 0132 * @brief Shrinks an object class information record. 0133 * 0134 * This function shrinks an object class information record. 0135 * The object's name and object space are released. The local_table 0136 * etc block does not shrink. The InActive list needs to be scanned 0137 * to find the objects are remove them. 0138 * 0139 * @param information Points to an object class information block. 0140 */ 0141 void _Objects_Shrink_information( 0142 Objects_Information *information 0143 ); 0144 0145 /** 0146 * @brief Initializes the specified objects information. 0147 * 0148 * The objects information must be statically pre-initialized with the 0149 * OBJECTS_INFORMATION_DEFINE() macro before this function is called. 0150 * 0151 * @param information The object information to be initialized. 0152 */ 0153 void _Objects_Initialize_information( Objects_Information *information ); 0154 0155 /** 0156 * @brief Returns highest numeric value of a valid API for the specified API. 0157 * 0158 * This function returns the highest numeric value of a valid 0159 * API for the specified @a api. 0160 * 0161 * @param api The API of interest. 0162 * 0163 * @retval some_value Positive integer on success. 0164 * @retval 0 The method failed. 0165 */ 0166 unsigned int _Objects_API_maximum_class( 0167 uint32_t api 0168 ); 0169 0170 /** 0171 * @brief Allocates an object. 0172 * 0173 * This function locks the object allocator mutex via 0174 * _Objects_Allocator_lock(). The caller must later unlock the object 0175 * allocator mutex via _Objects_Allocator_unlock(). The caller must unlock the 0176 * mutex in any case, even if the allocation failed due to resource shortage. 0177 * 0178 * A typical object allocation code looks like this: 0179 * @code 0180 * rtems_status_code some_create( rtems_id *id ) 0181 * { 0182 * rtems_status_code sc; 0183 * Some_Control *some; 0184 * 0185 * // The object allocator mutex protects the executing thread from 0186 * // asynchronous thread restart and deletion. 0187 * some = (Some_Control *) _Objects_Allocate( &_Some_Information ); 0188 * 0189 * if ( some != NULL ) { 0190 * _Some_Initialize( some ); 0191 * sc = RTEMS_SUCCESSFUL; 0192 * } else { 0193 * sc = RTEMS_TOO_MANY; 0194 * } 0195 * 0196 * _Objects_Allocator_unlock(); 0197 * 0198 * return sc; 0199 * } 0200 * @endcode 0201 * 0202 * @param[in, out] information The object information block. 0203 * 0204 * @retval object The allocated object. 0205 * @retval NULL No object available. 0206 * 0207 * @see _Objects_Free(). 0208 */ 0209 Objects_Control *_Objects_Allocate( Objects_Information *information ); 0210 0211 /** 0212 * @brief Searches an object of the specified class with the specified name on 0213 * the specified set of nodes. 0214 * 0215 * This method converts an object name to an identifier. It performs a look up 0216 * using the object information block for this object class. 0217 * 0218 * @param name is the name of the object to find. 0219 * @param node is the set of nodes to search. 0220 * @param[out] id is the pointer to an object identifier variable or NULL. The 0221 * object identifier will be stored in the referenced variable, if the 0222 * operation was successful. 0223 * @param information is the pointer to an object class information block. 0224 * 0225 * @retval STATUS_SUCCESSFUL The operations was successful. 0226 * @retval STATUS_INVALID_ADDRESS The id parameter was NULL. 0227 * @retval STATUS_INVALID_NAME No object exists with the specified name on the 0228 * specified node set. 0229 */ 0230 Status_Control _Objects_Name_to_id_u32( 0231 uint32_t name, 0232 uint32_t node, 0233 Objects_Id *id, 0234 const Objects_Information *information 0235 ); 0236 0237 typedef enum { 0238 OBJECTS_GET_BY_NAME_INVALID_NAME, 0239 OBJECTS_GET_BY_NAME_NAME_TOO_LONG, 0240 OBJECTS_GET_BY_NAME_NO_OBJECT 0241 } Objects_Get_by_name_error; 0242 0243 /** 0244 * @brief Gets an object control block identified by its name. 0245 * 0246 * The object information must use string names. 0247 * 0248 * @param information The object information. Must not be NULL. 0249 * @param name The object name. 0250 * @param[out] name_length_p Optional parameter to return the name length. 0251 * @param[out] error The error indication in case of failure. Must not be NULL. 0252 * 0253 * @retval pointer The first object according to object index associated with 0254 * this name. 0255 * @retval NULL No object exists for this name or invalid parameters. 0256 */ 0257 Objects_Control *_Objects_Get_by_name( 0258 const Objects_Information *information, 0259 const char *name, 0260 size_t *name_length_p, 0261 Objects_Get_by_name_error *error 0262 ); 0263 0264 /** 0265 * @brief Returns the name associated with object id. 0266 * 0267 * This function implements the common portion of the object Id 0268 * to name directives. This function returns the name 0269 * associated with object id. 0270 * 0271 * @param id is the Id of the object whose name we are locating. 0272 * @param[out] name will contain the name of the object, if found. 0273 * 0274 * @retval STATUS_SUCCESSFUL The operation succeeded. @a name 0275 * contains the name of the object. 0276 * @retval STATUS_INVALID_ID The id is invalid, the operation failed. 0277 * 0278 * @note This function currently does not support string names. 0279 */ 0280 Status_Control _Objects_Id_to_name ( 0281 Objects_Id id, 0282 Objects_Name *name 0283 ); 0284 0285 /** 0286 * @brief Maps the specified object identifier to the associated local object 0287 * control block. 0288 * 0289 * In this function interrupts are disabled during the object lookup. In case 0290 * an associated object exists, then interrupts remain disabled, otherwise the 0291 * previous interrupt state is restored. 0292 * 0293 * @param id The object identifier. This is the first parameter since usual 0294 * callers get the object identifier as the first parameter themself. 0295 * @param lock_context The interrupt lock context. This is the second 0296 * parameter since usual callers get the interrupt lock context as the second 0297 * parameter themself. 0298 * @param information The object class information block. 0299 * 0300 * @retval pointer The pointer to the associated object control block. 0301 * Interrupts are now disabled and must be restored using the specified lock 0302 * context via _ISR_lock_ISR_enable() or _ISR_lock_Release_and_ISR_enable(). 0303 * @retval NULL No associated object exists. 0304 */ 0305 Objects_Control *_Objects_Get( 0306 Objects_Id id, 0307 ISR_lock_Context *lock_context, 0308 const Objects_Information *information 0309 ); 0310 0311 /** 0312 * @brief Maps object ids to object control blocks. 0313 * 0314 * This function maps object ids to object control blocks. 0315 * If id corresponds to a local object, then it returns 0316 * the_object control pointer which maps to id and location 0317 * is set to OBJECTS_LOCAL. If the object class supports global 0318 * objects and the object id is global and resides on a remote 0319 * node, then location is set to OBJECTS_REMOTE, and the_object 0320 * is undefined. Otherwise, location is set to OBJECTS_ERROR 0321 * and the_object is undefined. 0322 * 0323 * @param id The Id of the object whose name we are locating. 0324 * This is the first parameter since usual callers get the object identifier 0325 * as the first parameter themself. 0326 * @param information Points to an object class information block. 0327 * 0328 * @retval pointer The local object corresponding to the given id. 0329 * @retval NULL The object to the given id was not found locally. 0330 */ 0331 Objects_Control *_Objects_Get_no_protection( 0332 Objects_Id id, 0333 const Objects_Information *information 0334 ); 0335 0336 /** 0337 * @brief Gets the next open object after the specified object identifier. 0338 * 0339 * Locks the object allocator mutex in case a next object exists. 0340 * 0341 * @param id The Id of the object whose name we are locating. 0342 * This is the first parameter since usual callers get the object identifier 0343 * as the first parameter themself. 0344 * @param information Points to an object class information block. 0345 * @param[in, out] next_id_p The Id of the next object we will look at. 0346 * 0347 * @retval pointer Pointer to the located object. 0348 * @retval NULL An error occurred. 0349 */ 0350 Objects_Control *_Objects_Get_next( 0351 Objects_Id id, 0352 const Objects_Information *information, 0353 Objects_Id *next_id_p 0354 ); 0355 0356 /** 0357 * @brief Gets object information. 0358 * 0359 * This function returns the information structure given 0360 * an API and Class. This can be done independent of the 0361 * existence of any objects created by the API. 0362 * 0363 * @param the_api Indicates the API for the information we want 0364 * @param the_class Indicates the Class for the information we want 0365 * 0366 * @retval pointer Pointer to the Object Information Table 0367 * for the class of objects which corresponds to this object ID. 0368 * @retval NULL An error occurred. 0369 */ 0370 Objects_Information *_Objects_Get_information( 0371 Objects_APIs the_api, 0372 uint16_t the_class 0373 ); 0374 0375 /** 0376 * @brief Gets information of an object from an ID. 0377 * 0378 * This function returns the information structure given 0379 * an @a id of an object. 0380 * 0381 * @param id The object ID to get the information from. 0382 * 0383 * @retval pointer Pointer to the Object Information Table 0384 * for the class of objects which corresponds to this object ID. 0385 * @retval NULL An error occurred. 0386 */ 0387 Objects_Information *_Objects_Get_information_id( 0388 Objects_Id id 0389 ); 0390 0391 /** 0392 * @brief Returns if the object has a string name. 0393 * 0394 * @param information The object information table. 0395 * 0396 * @retval true The object has a string name. 0397 * @retval false The object does not have a string name. 0398 */ 0399 static inline bool _Objects_Has_string_name( 0400 const Objects_Information *information 0401 ) 0402 { 0403 return information->name_length > 0; 0404 } 0405 0406 /** 0407 * @brief Gets object name in the form of a C string. 0408 * 0409 * This method gets the name of an object and returns its name 0410 * in the form of a C string. It attempts to be careful about 0411 * overflowing the user's string and about returning unprintable characters. 0412 * 0413 * @param id The object to obtain the name of. 0414 * @param length Indicates the length of the caller's buffer. 0415 * @param[out] name A string which will be filled in. 0416 * 0417 * @retval @a name The operation was succeeded and the string was correctly filled in. 0418 * @retval NULL An error occurred. 0419 */ 0420 char *_Objects_Get_name_as_string( 0421 Objects_Id id, 0422 size_t length, 0423 char *name 0424 ); 0425 0426 /** 0427 * @brief Converts the specified object name to a text representation. 0428 * 0429 * Non-printable characters according to isprint() are converted to '*'. 0430 * 0431 * @param name The object name. 0432 * @param is_string Indicates if the object name is a string or a four 0433 * character array (32-bit unsigned integer). 0434 * @param[out] buffer The string buffer for the text representation. 0435 * @param buffer_size The buffer size in characters. 0436 * 0437 * @return The length of the text representation. May be greater than or equal 0438 * to the buffer size if truncation occurred. 0439 */ 0440 size_t _Objects_Name_to_string( 0441 Objects_Name name, 0442 bool is_string, 0443 char *buffer, 0444 size_t buffer_size 0445 ); 0446 0447 /** 0448 * @brief Sets objects name. 0449 * 0450 * This method sets the object name to either a copy of a string 0451 * or up to the first four characters of the string based upon 0452 * whether this object class uses strings for names. 0453 * 0454 * @param information points to the object information. 0455 * @param[out] the_object is the object to operate upon. 0456 * @param name is a pointer to the name to use. 0457 * 0458 * @retval STATUS_SUCCESSFUL The operation succeeded. 0459 * 0460 * @retval STATUS_NO_MEMORY There was no memory available to duplicate the name. 0461 */ 0462 Status_Control _Objects_Set_name( 0463 const Objects_Information *information, 0464 Objects_Control *the_object, 0465 const char *name 0466 ); 0467 0468 /** 0469 * @brief Removes object with a 32-bit integer name from its namespace. 0470 * 0471 * @param information The corresponding object information table. 0472 * @param[out] the_object The object to operate upon. 0473 */ 0474 static inline void _Objects_Namespace_remove_u32( 0475 const Objects_Information *information, 0476 Objects_Control *the_object 0477 ) 0478 { 0479 _Assert( !_Objects_Has_string_name( information ) ); 0480 the_object->name.name_u32 = 0; 0481 } 0482 0483 /** 0484 * @brief Removes object with a string name from its namespace. 0485 * 0486 * @param information The corresponding object information table. 0487 * @param[out] the_object The object the object to operate upon. 0488 */ 0489 void _Objects_Namespace_remove_string( 0490 const Objects_Information *information, 0491 Objects_Control *the_object 0492 ); 0493 0494 /** 0495 * @brief Closes object. 0496 * 0497 * This function removes the_object control pointer and object name 0498 * in the Local Pointer and Local Name Tables. 0499 * 0500 * @param information Points to an Object Information Table. 0501 * @param[out] the_object A pointer to an object. 0502 */ 0503 void _Objects_Close( 0504 const Objects_Information *information, 0505 Objects_Control *the_object 0506 ); 0507 0508 /** 0509 * @brief Returns the count of active objects. 0510 * 0511 * @param information The object information table. 0512 * 0513 * @return The count of active objects. 0514 */ 0515 Objects_Maximum _Objects_Active_count( 0516 const Objects_Information *information 0517 ); 0518 0519 /** 0520 * @brief Returns the object's objects per block. 0521 * 0522 * @param information The object information table. 0523 * 0524 * @return The number of objects per block of @a information. 0525 */ 0526 static inline Objects_Maximum _Objects_Extend_size( 0527 const Objects_Information *information 0528 ) 0529 { 0530 return information->objects_per_block; 0531 } 0532 0533 /** 0534 * @brief Checks if the api is valid. 0535 * 0536 * @param the_api is the api portion of an object ID. 0537 * 0538 * @retval true The specified api value is valid. 0539 * @retval false The specified api value is not valid. 0540 */ 0541 static inline bool _Objects_Is_api_valid( 0542 uint32_t the_api 0543 ) 0544 { 0545 return ( 1 <= the_api && the_api <= OBJECTS_APIS_LAST ); 0546 } 0547 0548 /** 0549 * @brief Checks if the node is of the local object. 0550 * 0551 * @param node The node number and corresponds to the node number 0552 * portion of an object ID. 0553 * 0554 * @retval true The specified node is the local node. 0555 * @retval false The specified node is not the local node. 0556 */ 0557 static inline bool _Objects_Is_local_node( 0558 uint32_t node 0559 ) 0560 { 0561 return ( node == _Objects_Local_node ); 0562 } 0563 0564 /** 0565 * @brief Checks if the id is of a local object. 0566 * 0567 * @param id The object ID. 0568 * 0569 * @retval true The specified object Id is local. 0570 * @retval false The specified object Id is not local. 0571 * 0572 * @note On a single processor configuration, this always returns true. 0573 */ 0574 static inline bool _Objects_Is_local_id( 0575 #if defined(RTEMS_MULTIPROCESSING) 0576 Objects_Id id 0577 #else 0578 Objects_Id id RTEMS_UNUSED 0579 #endif 0580 ) 0581 { 0582 #if defined(RTEMS_MULTIPROCESSING) 0583 return _Objects_Is_local_node( _Objects_Get_node(id) ); 0584 #else 0585 return true; 0586 #endif 0587 } 0588 0589 /** 0590 * @brief Checks if two object IDs are equal. 0591 * 0592 * @param left The Id on the left hand side of the comparison. 0593 * @param right The Id on the right hand side of the comparison. 0594 * 0595 * @retval true The specified object IDs are equal. 0596 * @retval false The specified object IDs are not equal. 0597 */ 0598 static inline bool _Objects_Are_ids_equal( 0599 Objects_Id left, 0600 Objects_Id right 0601 ) 0602 { 0603 return ( left == right ); 0604 } 0605 0606 /** 0607 * @brief Returns the identifier with the minimum index for the specified identifier. 0608 * 0609 * The specified identifier must have valid API, class and node fields. 0610 * 0611 * @param id The identifier to be processed. 0612 * 0613 * @return The corresponding ID with the minimum index. 0614 */ 0615 static inline Objects_Id _Objects_Get_minimum_id( Objects_Id id ) 0616 { 0617 id &= ~OBJECTS_INDEX_MASK; 0618 id += (Objects_Id) OBJECTS_INDEX_MINIMUM << OBJECTS_INDEX_START_BIT; 0619 return id; 0620 } 0621 0622 /** 0623 * @brief Returns the maximum index of the specified object class. 0624 * 0625 * @param information The object information. 0626 * 0627 * @return The maximum index of the specified object class. 0628 */ 0629 static inline Objects_Maximum _Objects_Get_maximum_index( 0630 const Objects_Information *information 0631 ) 0632 { 0633 return _Objects_Get_index( information->maximum_id ); 0634 } 0635 0636 /** 0637 * @brief Get an inactive object or NULL. 0638 * 0639 * @retval NULL No inactive object is available. 0640 * @retval object An inactive object. 0641 */ 0642 static inline Objects_Control *_Objects_Get_inactive( 0643 Objects_Information *information 0644 ) 0645 { 0646 return (Objects_Control *) _Chain_Get_unprotected( &information->Inactive ); 0647 } 0648 0649 /** 0650 * @brief Checks if the automatic object extension (unlimited objects) is 0651 * enabled. 0652 * 0653 * @param information The object information. 0654 * 0655 * @retval true The automatic object extension (unlimited objects) is enabled. 0656 * @retval false The automatic object extension (unlimited objects) is not enabled. 0657 */ 0658 static inline Objects_Maximum _Objects_Is_auto_extend( 0659 const Objects_Information *information 0660 ) 0661 { 0662 return information->objects_per_block != 0; 0663 } 0664 0665 /** 0666 * @brief Sets the pointer to the local_table object 0667 * referenced by the index. 0668 * 0669 * @param[in, out] information Points to an Object Information Table. 0670 * @param index The index of the object the caller wants to access. 0671 * @param the_object The local object pointer. 0672 * 0673 * @note This routine is ONLY to be called in places where the 0674 * index portion of the Id is known to be good. This is 0675 * OK since it is normally called from object create/init 0676 * or delete/destroy operations. 0677 */ 0678 0679 static inline void _Objects_Set_local_object( 0680 const Objects_Information *information, 0681 uint32_t index, 0682 Objects_Control *the_object 0683 ) 0684 { 0685 /* 0686 * This routine is ONLY to be called from places in the code 0687 * where the Id is known to be good. Therefore, this should NOT 0688 * occur in normal situations. 0689 */ 0690 _Assert( index >= OBJECTS_INDEX_MINIMUM ); 0691 _Assert( index <= _Objects_Get_maximum_index( information ) ); 0692 0693 information->local_table[ index - OBJECTS_INDEX_MINIMUM ] = the_object; 0694 } 0695 0696 /** 0697 * @brief Invalidates an object Id. 0698 * 0699 * This function sets the pointer to the local_table object 0700 * referenced by the index to NULL so the object Id is invalid 0701 * after this call. 0702 * 0703 * @param[in, out] information points to an Object Information Table. 0704 * @param the_object The local object pointer. 0705 * 0706 * @note This routine is ONLY to be called in places where the 0707 * index portion of the Id is known to be good. This is 0708 * OK since it is normally called from object create/init 0709 * or delete/destroy operations. 0710 */ 0711 0712 static inline void _Objects_Invalidate_Id( 0713 const Objects_Information *information, 0714 Objects_Control *the_object 0715 ) 0716 { 0717 _Assert( information != NULL ); 0718 _Assert( the_object != NULL ); 0719 0720 _Objects_Set_local_object( 0721 information, 0722 _Objects_Get_index( the_object->id ), 0723 NULL 0724 ); 0725 } 0726 0727 /** 0728 * @brief Assigns the 32-bit unsigned integer name to the object and places the 0729 * object in the local object table. 0730 * 0731 * @param information is the object information. 0732 * 0733 * @param[in, out] the_object is the object to open. 0734 * 0735 * @param name is the name of the object to open. 0736 * 0737 * @return Returns the identifier of the object which is now valid. 0738 */ 0739 static inline Objects_Id _Objects_Open_u32( 0740 const Objects_Information *information, 0741 Objects_Control *the_object, 0742 uint32_t name 0743 ) 0744 { 0745 _Assert( information != NULL ); 0746 _Assert( !_Objects_Has_string_name( information ) ); 0747 _Assert( the_object != NULL ); 0748 0749 the_object->name.name_u32 = name; 0750 0751 _Objects_Set_local_object( 0752 information, 0753 _Objects_Get_index( the_object->id ), 0754 the_object 0755 ); 0756 0757 return the_object->id; 0758 } 0759 0760 /** 0761 * @brief Assigns the string name to the object and places the object in the 0762 * local object table. 0763 * 0764 * @param information is the object information. 0765 * 0766 * @param[in, out] the_object is the object to open. 0767 * 0768 * @param name is the name of the object to open. 0769 */ 0770 static inline void _Objects_Open_string( 0771 const Objects_Information *information, 0772 Objects_Control *the_object, 0773 const char *name 0774 ) 0775 { 0776 _Assert( information != NULL ); 0777 _Assert( _Objects_Has_string_name( information ) ); 0778 _Assert( the_object != NULL ); 0779 0780 the_object->name.name_p = name; 0781 0782 _Objects_Set_local_object( 0783 information, 0784 _Objects_Get_index( the_object->id ), 0785 the_object 0786 ); 0787 } 0788 0789 /** 0790 * @brief Locks the object allocator mutex. 0791 * 0792 * While holding the allocator mutex the executing thread is protected from 0793 * asynchronous thread restart and deletion. 0794 * 0795 * The usage of the object allocator mutex with the thread life protection 0796 * makes it possible to allocate and free objects without thread dispatching 0797 * disabled. The usage of a unified workspace and unlimited objects may lead 0798 * to heap fragmentation. Thus the execution time of the _Objects_Allocate() 0799 * function may increase during system run-time. 0800 * 0801 * @see _Objects_Allocator_unlock() and _Objects_Allocate(). 0802 */ 0803 static inline void _Objects_Allocator_lock( void ) 0804 { 0805 _RTEMS_Lock_allocator(); 0806 } 0807 0808 /** 0809 * @brief Unlocks the object allocator mutex. 0810 * 0811 * In case the mutex is fully unlocked, then this function restores the 0812 * previous thread life protection state and thus may not return if the 0813 * executing thread was restarted or deleted in the mean-time. 0814 */ 0815 static inline void _Objects_Allocator_unlock( void ) 0816 { 0817 _RTEMS_Unlock_allocator(); 0818 } 0819 0820 /** 0821 * @brief Checks if the allocator is the owner of the object allocator mutex 0822 * 0823 * @retval true The allocator is the owner of the object allocator mutex. 0824 * @retval false The allocato is not the owner of the object allocator mutex. 0825 */ 0826 static inline bool _Objects_Allocator_is_owner( void ) 0827 { 0828 return _RTEMS_Allocator_is_owner(); 0829 } 0830 0831 /** 0832 * @brief Allocates an object without locking the allocator mutex. 0833 * 0834 * This function can be called in two contexts 0835 * - the executing thread is the owner of the object allocator mutex, or 0836 * - in case the system state is not up, e.g. during sequential system 0837 * initialization. 0838 * 0839 * @param[in, out] information The object information block. 0840 * 0841 * @retval object The allocated object. 0842 * @retval NULL No object available. 0843 * 0844 * @see _Objects_Allocate() and _Objects_Free(). 0845 */ 0846 static inline Objects_Control *_Objects_Allocate_unprotected( 0847 Objects_Information *information 0848 ) 0849 { 0850 _Assert( 0851 _Objects_Allocator_is_owner() 0852 || !_System_state_Is_up( _System_state_Get() ) 0853 ); 0854 0855 return ( *information->allocate )( information ); 0856 } 0857 0858 /** 0859 * @brief Frees an object. 0860 * 0861 * Appends the object to the chain of inactive objects. 0862 * 0863 * @param information The object information block. 0864 * @param[out] the_object The object to free. 0865 * 0866 * @see _Objects_Allocate(). 0867 * 0868 * A typical object deletion code looks like this: 0869 * @code 0870 * rtems_status_code some_delete( rtems_id id ) 0871 * { 0872 * Some_Control *some; 0873 * 0874 * // The object allocator mutex protects the executing thread from 0875 * // asynchronous thread restart and deletion. 0876 * _Objects_Allocator_lock(); 0877 * 0878 * // Get the object under protection of the object allocator mutex. 0879 * some = (Semaphore_Control *) 0880 * _Objects_Get_no_protection( id, &_Some_Information ); 0881 * 0882 * if ( some == NULL ) { 0883 * _Objects_Allocator_unlock(); 0884 * return RTEMS_INVALID_ID; 0885 * } 0886 * 0887 * // After the object close an object get with this identifier will 0888 * // fail. 0889 * _Objects_Close( &_Some_Information, &some->Object ); 0890 * 0891 * _Some_Delete( some ); 0892 * 0893 * // Thread dispatching is enabled. The object free is only protected 0894 * // by the object allocator mutex. 0895 * _Objects_Free( &_Some_Information, &some->Object ); 0896 * 0897 * _Objects_Allocator_unlock(); 0898 * return RTEMS_SUCCESSFUL; 0899 * } 0900 * @endcode 0901 */ 0902 static inline void _Objects_Free( 0903 Objects_Information *information, 0904 Objects_Control *the_object 0905 ) 0906 { 0907 _Assert( _Objects_Allocator_is_owner() ); 0908 _Assert( information->deallocate != NULL ); 0909 ( *information->deallocate )( information, the_object ); 0910 } 0911 0912 /** 0913 * @brief Returns true, if the object associated with the zero-based index is 0914 * contained in an allocated block of objects, otherwise false. 0915 * 0916 * @param index is the zero-based object index. 0917 * @param objects_per_block is the object count per block. 0918 * 0919 * @retval true The object associated with the zero-based index is in an 0920 * allocated block of objects. 0921 * @retval false Otherwise. 0922 */ 0923 static inline bool _Objects_Is_in_allocated_block( 0924 Objects_Maximum index, 0925 Objects_Maximum objects_per_block 0926 ) 0927 { 0928 return index >= objects_per_block; 0929 } 0930 0931 /** 0932 * @brief Activate the object. 0933 * 0934 * This function must be only used in case this objects information supports 0935 * unlimited objects. 0936 * 0937 * @param information The object information block. 0938 * @param the_object The object to activate. 0939 */ 0940 static inline void _Objects_Activate_unlimited( 0941 Objects_Information *information, 0942 Objects_Control *the_object 0943 ) 0944 { 0945 Objects_Maximum objects_per_block; 0946 Objects_Maximum index; 0947 0948 _Assert( _Objects_Is_auto_extend( information ) ); 0949 0950 objects_per_block = information->objects_per_block; 0951 index = _Objects_Get_index( the_object->id ) - OBJECTS_INDEX_MINIMUM; 0952 0953 if ( _Objects_Is_in_allocated_block( index, objects_per_block ) ) { 0954 Objects_Maximum block; 0955 0956 block = index / objects_per_block; 0957 0958 information->inactive_per_block[ block ]--; 0959 information->inactive--; 0960 } 0961 } 0962 0963 /** 0964 * @brief Allocate an object and extend the objects information on demand. 0965 * 0966 * This function must be only used in case this objects information supports 0967 * unlimited objects. 0968 * 0969 * @param information The object information block. 0970 * @param extend The object information extend handler. 0971 */ 0972 static inline Objects_Control *_Objects_Allocate_with_extend( 0973 Objects_Information *information, 0974 void ( *extend )( Objects_Information * ) 0975 ) 0976 { 0977 Objects_Control *the_object; 0978 0979 _Assert( _Objects_Is_auto_extend( information ) ); 0980 0981 the_object = _Objects_Get_inactive( information ); 0982 0983 if ( the_object == NULL ) { 0984 ( *extend )( information ); 0985 the_object = _Objects_Get_inactive( information ); 0986 } 0987 0988 if ( the_object != NULL ) { 0989 _Objects_Activate_unlimited( information, the_object ); 0990 } 0991 0992 return the_object; 0993 } 0994 0995 /** 0996 * @brief This function does nothing. 0997 * 0998 * @param ptr is not used. 0999 */ 1000 void _Objects_Free_nothing( void *ptr ); 1001 1002 /** @} */ 1003 1004 #ifdef __cplusplus 1005 } 1006 #endif 1007 1008 #if defined(RTEMS_MULTIPROCESSING) 1009 #include <rtems/score/objectmp.h> 1010 #endif 1011 1012 1013 #endif 1014 /* end of include file */
[ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |
![]() ![]() |