Back to home page

LXR

 
 

    


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 */