source: rtems/cpukit/include/rtems/score/objectimpl.h @ 3f732f0

5
Last change on this file since 3f732f0 was 3f732f0, checked in by Joel Sherrill <joel@…>, on 02/13/20 at 00:15:56

objectdata.h, objectimpl.h: Change structure member from free to deallocate

Without this change, rtems-libbsd does not compile. A macro turns
free into bsd_free.

Also the use of a standard library element as a program identifier
is a violation of a MISRA rule. Turns out that was a good rule. :)

  • Property mode set to 100644
File size: 28.8 KB
Line 
1/**
2 * @file
3 *
4 * @ingroup RTEMSScoreObject
5 *
6 * @brief Inlined Routines in the Object Handler
7 *
8 * This include file contains the static inline implementation of all
9 * of the inlined routines in the Object Handler.
10 */
11
12/*
13 *  COPYRIGHT (c) 1989-2011.
14 *  On-Line Applications Research Corporation (OAR).
15 *
16 *  The license and distribution terms for this file may be
17 *  found in the file LICENSE in this distribution or at
18 *  http://www.rtems.org/license/LICENSE.
19 */
20
21#ifndef _RTEMS_SCORE_OBJECTIMPL_H
22#define _RTEMS_SCORE_OBJECTIMPL_H
23
24#include <rtems/score/objectdata.h>
25#include <rtems/score/apimutex.h>
26#include <rtems/score/assert.h>
27#include <rtems/score/isrlock.h>
28#include <rtems/score/sysstate.h>
29#include <rtems/score/threaddispatch.h>
30
31#ifdef __cplusplus
32extern "C" {
33#endif
34
35/**
36 * @addtogroup RTEMSScoreObject
37 *
38 * @{
39 */
40
41/**
42 *  Functions which compare names are prototyped like this.
43 */
44typedef bool    (*Objects_Name_comparators)(
45  void       * /* name_1 */,
46  void       * /* name_2 */,
47  uint16_t     /* length */
48);
49
50/** This macro is used to generically specify the last API index. */
51#define OBJECTS_INTERNAL_CLASSES_LAST OBJECTS_INTERNAL_THREADS
52
53/** This macro is used to generically specify the last API index. */
54#define OBJECTS_RTEMS_CLASSES_LAST OBJECTS_RTEMS_BARRIERS
55
56/** This macro is used to generically specify the last API index. */
57#define OBJECTS_POSIX_CLASSES_LAST OBJECTS_POSIX_SHMS
58
59/*
60 * For fake objects, which have an object identifier, but no objects
61 * information block.
62 */
63typedef enum {
64  OBJECTS_FAKE_OBJECTS_NO_CLASS   = 0,
65  OBJECTS_FAKE_OBJECTS_SCHEDULERS = 1
66} Objects_Fake_objects_API;
67
68/**
69 *  The following is referenced to the number of nodes in the system.
70 */
71#if defined(RTEMS_MULTIPROCESSING)
72extern uint16_t _Objects_Maximum_nodes;
73#else
74#define _Objects_Maximum_nodes 1
75#endif
76
77/**
78 * This is the minimum object ID index associated with an object.
79 */
80#define OBJECTS_INDEX_MINIMUM 1U
81
82/**
83 *  The following is the list of information blocks per API for each object
84 *  class.  From the ID, we can go to one of these information blocks,
85 *  and obtain a pointer to the appropriate object control block.
86 */
87extern Objects_Information ** const
88_Objects_Information_table[ OBJECTS_APIS_LAST + 1 ];
89
90/**
91 * @brief Extends an object class information record.
92 *
93 * @param information Points to an object class information block.
94 *
95 * @retval 0 The extend operation failed.
96 * @retval block The block index of the new objects block.
97 */
98Objects_Maximum _Objects_Extend_information(
99  Objects_Information *information
100);
101
102/**
103 * @brief Free the objects block with the specified index.
104 *
105 * @param information The objects information.
106 * @param block The block index.
107 */
108void _Objects_Free_objects_block(
109  Objects_Information *information,
110  Objects_Maximum      block
111);
112
113/**
114 * @brief Shrinks an object class information record.
115 *
116 * This function shrinks an object class information record.
117 * The object's name and object space are released. The local_table
118 * etc block does not shrink. The InActive list needs to be scanned
119 * to find the objects are remove them.
120 *
121 * @param information Points to an object class information block.
122 */
123void _Objects_Shrink_information(
124  Objects_Information *information
125);
126
127/**
128 * @brief Initializes the specified objects information.
129 *
130 * The objects information must be statically pre-initialized with the
131 * OBJECTS_INFORMATION_DEFINE() macro before this function is called.
132 *
133 * @param information The object information to be initialized.
134 */
135void _Objects_Initialize_information( Objects_Information *information );
136
137/**
138 * @brief Returns highest numeric value of a valid API for the specified API.
139 *
140 * This function returns the highest numeric value of a valid
141 * API for the specified @a api.
142 *
143 * @param api The API of interest.
144 *
145 * @retval some_value Positive integer on success.
146 * @retval 0 The method failed.
147 */
148unsigned int _Objects_API_maximum_class(
149  uint32_t api
150);
151
152/**
153 * @brief Allocates an object.
154 *
155 * This function locks the object allocator mutex via
156 * _Objects_Allocator_lock().  The caller must later unlock the object
157 * allocator mutex via _Objects_Allocator_unlock().  The caller must unlock the
158 * mutex in any case, even if the allocation failed due to resource shortage.
159 *
160 * A typical object allocation code looks like this:
161 * @code
162 * rtems_status_code some_create( rtems_id *id )
163 * {
164 *   rtems_status_code  sc;
165 *   Some_Control      *some;
166 *
167 *   // The object allocator mutex protects the executing thread from
168 *   // asynchronous thread restart and deletion.
169 *   some = (Some_Control *) _Objects_Allocate( &_Some_Information );
170 *
171 *   if ( some != NULL ) {
172 *     _Some_Initialize( some );
173 *     sc = RTEMS_SUCCESSFUL;
174 *   } else {
175 *     sc = RTEMS_TOO_MANY;
176 *   }
177 *
178 *   _Objects_Allocator_unlock();
179 *
180 *   return sc;
181 * }
182 * @endcode
183 *
184 * @param[in, out] information The object information block.
185 *
186 * @retval object The allocated object.
187 * @retval NULL No object available.
188 *
189 * @see _Objects_Free().
190 */
191Objects_Control *_Objects_Allocate( Objects_Information *information );
192
193/**
194 *  This function implements the common portion of the object
195 *  identification directives.  This directive returns the object
196 *  id associated with name.  If more than one object of this class
197 *  is named name, then the object to which the id belongs is
198 *  arbitrary.  Node indicates the extent of the search for the
199 *  id of the object named name.  If the object class supports global
200 *  objects, then the search can be limited to a particular node
201 *  or allowed to encompass all nodes.
202 */
203typedef enum {
204  OBJECTS_NAME_OR_ID_LOOKUP_SUCCESSFUL,
205  OBJECTS_INVALID_NAME,
206  OBJECTS_INVALID_ADDRESS,
207  OBJECTS_INVALID_ID,
208  OBJECTS_INVALID_NODE
209} Objects_Name_or_id_lookup_errors;
210
211/**
212 *  This macro defines the first entry in the
213 *  @ref Objects_Name_or_id_lookup_errors enumerated list.
214 */
215#define OBJECTS_NAME_ERRORS_FIRST OBJECTS_NAME_OR_ID_LOOKUP_SUCCESSFUL
216
217/**
218 *  This macro defines the last entry in the
219 *  @ref Objects_Name_or_id_lookup_errors enumerated list.
220 */
221#define OBJECTS_NAME_ERRORS_LAST  OBJECTS_INVALID_NODE
222
223/**
224 * @brief Converts an object name to an Id.
225 *
226 * This method converts an object name to an Id.  It performs a look up
227 * using the object information block for this object class.
228 *
229 * @param information points to an object class information block.
230 * @param name is the name of the object to find.
231 * @param node is the set of nodes to search.
232 * @param[out] id will contain the Id if the search is successful.
233 *
234 * @retval OBJECTS_NAME_OR_ID_LOOKUP_SUCCESSFUL The operations was successful
235 *      @a id contains the ID.
236 * @retval OBJECTS_INVALID_NAME The name was invalid.
237 * @retval OBJECTS_INVALID_ID The id is not 0 before the operation.
238 */
239Objects_Name_or_id_lookup_errors _Objects_Name_to_id_u32(
240  Objects_Information *information,
241  uint32_t             name,
242  uint32_t             node,
243  Objects_Id          *id
244);
245
246typedef enum {
247  OBJECTS_GET_BY_NAME_INVALID_NAME,
248  OBJECTS_GET_BY_NAME_NAME_TOO_LONG,
249  OBJECTS_GET_BY_NAME_NO_OBJECT
250} Objects_Get_by_name_error;
251
252/**
253 * @brief Gets an object control block identified by its name.
254 *
255 * The object information must use string names.
256 *
257 * @param information The object information.  Must not be NULL.
258 * @param name The object name.
259 * @param[out] name_length_p Optional parameter to return the name length.
260 * @param[out] error The error indication in case of failure.  Must not be NULL.
261 *
262 * @retval pointer The first object according to object index associated with
263 *      this name.
264 * @retval NULL No object exists for this name or invalid parameters.
265 */
266Objects_Control *_Objects_Get_by_name(
267  const Objects_Information *information,
268  const char                *name,
269  size_t                    *name_length_p,
270  Objects_Get_by_name_error *error
271);
272
273/**
274 * @brief Returns the name associated with object id.
275 *
276 * This function implements the common portion of the object Id
277 * to name directives.  This function returns the name
278 * associated with object id.
279 *
280 * @param id is the Id of the object whose name we are locating.
281 * @param[out] name will contain the name of the object, if found.
282 *
283 * @retval OBJECTS_NAME_OR_ID_LOOKUP_SUCCESSFUL The operation succeeded.  @a name
284 *      contains the name of the object.
285 * @retval OBJECTS_INVALID_ID The id is invalid, the operation failed.
286 *
287 * @note This function currently does not support string names.
288 */
289Objects_Name_or_id_lookup_errors _Objects_Id_to_name (
290  Objects_Id      id,
291  Objects_Name   *name
292);
293
294/**
295 * @brief Maps the specified object identifier to the associated local object
296 * control block.
297 *
298 * In this function interrupts are disabled during the object lookup.  In case
299 * an associated object exists, then interrupts remain disabled, otherwise the
300 * previous interrupt state is restored.
301 *
302 * @param id The object identifier.  This is the first parameter since usual
303 *      callers get the object identifier as the first parameter themself.
304 * @param lock_context The interrupt lock context.  This is the second
305 *      parameter since usual callers get the interrupt lock context as the second
306 *      parameter themself.
307 * @param information The object class information block.
308 *
309 * @retval pointer The pointer to the associated object control block.
310 *      Interrupts are now disabled and must be restored using the specified lock
311 *      context via _ISR_lock_ISR_enable() or _ISR_lock_Release_and_ISR_enable().
312 * @retval NULL No associated object exists.
313 */
314Objects_Control *_Objects_Get(
315  Objects_Id                 id,
316  ISR_lock_Context          *lock_context,
317  const Objects_Information *information
318);
319
320/**
321 * @brief  Maps object ids to object control blocks.
322 *
323 * This function maps object ids to object control blocks.
324 * If id corresponds to a local object, then it returns
325 * the_object control pointer which maps to id and location
326 * is set to OBJECTS_LOCAL.  If the object class supports global
327 * objects and the object id is global and resides on a remote
328 * node, then location is set to OBJECTS_REMOTE, and the_object
329 * is undefined.  Otherwise, location is set to OBJECTS_ERROR
330 * and the_object is undefined.
331 *
332 * @param id The Id of the object whose name we are locating.
333 *   This is the first parameter since usual callers get the object identifier
334 *   as the first parameter themself.
335 * @param information Points to an object class information block.
336 *
337 * @retval pointer The local object corresponding to the given id.
338 * @retval NULL The object to the given id was not found locally.
339 */
340Objects_Control *_Objects_Get_no_protection(
341  Objects_Id                 id,
342  const Objects_Information *information
343);
344
345/**
346 * @brief Gets the next open object after the specified object identifier.
347 *
348 * Locks the object allocator mutex in case a next object exists.
349 *
350 * @param id The Id of the object whose name we are locating.
351 *   This is the first parameter since usual callers get the object identifier
352 *   as the first parameter themself.
353 * @param information Points to an object class information block.
354 * @param[in, out] next_id_p The Id of the next object we will look at.
355 *
356 * @retval pointer Pointer to the located object.
357 * @retval NULL An error occured.
358 */
359Objects_Control *_Objects_Get_next(
360  Objects_Id                 id,
361  const Objects_Information *information,
362  Objects_Id                *next_id_p
363);
364
365/**
366 * @brief Gets object information.
367 *
368 * This function returns the information structure given
369 * an API and Class.  This can be done independent of the
370 * existence of any objects created by the API.
371 *
372 * @param the_api Indicates the API for the information we want
373 * @param the_class Indicates the Class for the information we want
374 *
375 * @retval pointer Pointer to the Object Information Table
376 *         for the class of objects which corresponds to this object ID.
377 * @retval NULL An error occured.
378 */
379Objects_Information *_Objects_Get_information(
380  Objects_APIs   the_api,
381  uint16_t       the_class
382);
383
384/**
385 * @brief Gets information of an object from an ID.
386 *
387 * This function returns the information structure given
388 * an @a id of an object.
389 *
390 * @param id The object ID to get the information from.
391 *
392 * @retval pointer Pointer to the Object Information Table
393 *         for the class of objects which corresponds to this object ID.
394 * @retval NULL An error occured.
395 */
396Objects_Information *_Objects_Get_information_id(
397  Objects_Id  id
398);
399
400/**
401 * @brief Returns if the object has a string name.
402 *
403 * @param information The object information table.
404 *
405 * @retval true The object has a string name.
406 * @retval false The object does not have a string name.
407 */
408RTEMS_INLINE_ROUTINE bool _Objects_Has_string_name(
409  const Objects_Information *information
410)
411{
412  return information->name_length > 0;
413}
414
415/**
416 * @brief Gets object name in the form of a C string.
417 *
418 * This method gets the name of an object and returns its name
419 * in the form of a C string.  It attempts to be careful about
420 * overflowing the user's string and about returning unprintable characters.
421 *
422 * @param id The object to obtain the name of.
423 * @param length Indicates the length of the caller's buffer.
424 * @param[out] name A string which will be filled in.
425 *
426 * @retval @a name The operation was succeeded and the string was correctly filled in.
427 * @retval NULL An error occured.
428 */
429char *_Objects_Get_name_as_string(
430  Objects_Id   id,
431  size_t       length,
432  char        *name
433);
434
435/**
436 * @brief Converts the specified object name to a text representation.
437 *
438 * Non-printable characters according to isprint() are converted to '*'.
439 *
440 * @param name The object name.
441 * @param is_string Indicates if the object name is a string or a four
442 *   character array (32-bit unsigned integer).
443 * @param[out] buffer The string buffer for the text representation.
444 * @param buffer_size The buffer size in characters.
445 *
446 * @return The length of the text representation.  May be greater than or equal
447 * to the buffer size if truncation occurred.
448 */
449size_t _Objects_Name_to_string(
450  Objects_Name  name,
451  bool          is_string,
452  char         *buffer,
453  size_t        buffer_size
454);
455
456/**
457 * @brief Sets objects name.
458 *
459 * This method sets the object name to either a copy of a string
460 * or up to the first four characters of the string based upon
461 * whether this object class uses strings for names.
462 *
463 * @param information points to the object information structure
464 * @param[out] the_object is the object to operate upon
465 * @param name is a pointer to the name to use
466 *
467 * @retval true The operation succeeded.
468 * @retval false The operation failed.
469 */
470bool _Objects_Set_name(
471  const Objects_Information *information,
472  Objects_Control           *the_object,
473  const char                *name
474);
475
476/**
477 * @brief Removes object with a 32-bit integer name from its namespace.
478 *
479 * @param information The corresponding object information table.
480 * @param[out] the_object The object to operate upon.
481 */
482RTEMS_INLINE_ROUTINE void _Objects_Namespace_remove_u32(
483  const Objects_Information *information,
484  Objects_Control           *the_object
485)
486{
487  _Assert( !_Objects_Has_string_name( information ) );
488  the_object->name.name_u32 = 0;
489}
490
491/**
492 * @brief Removes object with a string name from its namespace.
493 *
494 * @param information The corresponding object information table.
495 * @param[out] the_object The object the object to operate upon.
496 */
497void _Objects_Namespace_remove_string(
498  const Objects_Information *information,
499  Objects_Control           *the_object
500);
501
502/**
503 * @brief Closes object.
504 *
505 * This function removes the_object control pointer and object name
506 * in the Local Pointer and Local Name Tables.
507 *
508 * @param information Points to an Object Information Table.
509 * @param[out] the_object A pointer to an object.
510 */
511void _Objects_Close(
512  const Objects_Information *information,
513  Objects_Control           *the_object
514);
515
516/**
517 * @brief Returns the count of active objects.
518 *
519 * @param information The object information table.
520 *
521 * @return The count of active objects.
522 */
523Objects_Maximum _Objects_Active_count(
524  const Objects_Information *information
525);
526
527/**
528 * @brief Returns the object's objects per block.
529 *
530 * @param information The object information table.
531 *
532 * @return The number of objects per block of @a information.
533 */
534RTEMS_INLINE_ROUTINE Objects_Maximum _Objects_Extend_size(
535  const Objects_Information *information
536)
537{
538  return information->objects_per_block;
539}
540
541/**
542 * @brief Checks if the api is valid.
543 *
544 * @param the_api is the api portion of an object ID.
545 *
546 * @retval true The specified api value is valid.
547 * @retval false The specified api value is not valid.
548 */
549RTEMS_INLINE_ROUTINE bool _Objects_Is_api_valid(
550  uint32_t   the_api
551)
552{
553  if ( !the_api || the_api > OBJECTS_APIS_LAST )
554   return false;
555  return true;
556}
557
558/**
559 * @brief Checks if the node is of the local object.
560 *
561 * @param node The node number and corresponds to the node number
562 *        portion of an object ID.
563 *
564 * @retval true The specified node is the local node.
565 * @retval false The specified node is not the local node.
566 */
567RTEMS_INLINE_ROUTINE bool _Objects_Is_local_node(
568  uint32_t   node
569)
570{
571  return ( node == _Objects_Local_node );
572}
573
574/**
575 * @brief Checks if the id is of a local object.
576 *
577 * @param id The object ID.
578 *
579 * @retval true The specified object Id is local.
580 * @retval false The specified object Id is not local.
581 *
582 * @note On a single processor configuration, this always returns true.
583 */
584RTEMS_INLINE_ROUTINE bool _Objects_Is_local_id(
585#if defined(RTEMS_MULTIPROCESSING)
586  Objects_Id id
587#else
588  Objects_Id id RTEMS_UNUSED
589#endif
590)
591{
592#if defined(RTEMS_MULTIPROCESSING)
593  return _Objects_Is_local_node( _Objects_Get_node(id) );
594#else
595  return true;
596#endif
597}
598
599/**
600 * @brief Checks if two object IDs are equal.
601 *
602 * @param left The Id on the left hand side of the comparison.
603 * @param right The Id on the right hand side of the comparison.
604 *
605 * @retval true The specified object IDs are equal.
606 * @retval false The specified object IDs are not equal.
607 */
608RTEMS_INLINE_ROUTINE bool _Objects_Are_ids_equal(
609  Objects_Id left,
610  Objects_Id right
611)
612{
613  return ( left == right );
614}
615
616/**
617 * @brief Returns the identifier with the minimum index for the specified identifier.
618 *
619 * The specified identifier must have valid API, class and node fields.
620 *
621 * @param id The identifier to be processed.
622 *
623 * @return The corresponding ID with the minimum index.
624 */
625RTEMS_INLINE_ROUTINE Objects_Id _Objects_Get_minimum_id( Objects_Id id )
626{
627  id &= ~OBJECTS_INDEX_MASK;
628  id += (Objects_Id) OBJECTS_INDEX_MINIMUM << OBJECTS_INDEX_START_BIT;
629  return id;
630}
631
632/**
633 * @brief Returns the maximum index of the specified object class.
634 *
635 * @param information The object information.
636 *
637 * @return The maximum index of the specified object class.
638 */
639RTEMS_INLINE_ROUTINE Objects_Maximum _Objects_Get_maximum_index(
640  const Objects_Information *information
641)
642{
643  return _Objects_Get_index( information->maximum_id );
644}
645
646/**
647 * @brief Get an inactive object or NULL.
648 *
649 * @retval NULL No inactive object is available.
650 * @retval object An inactive object.
651 */
652RTEMS_INLINE_ROUTINE Objects_Control *_Objects_Get_inactive(
653  Objects_Information *information
654)
655{
656  return (Objects_Control *) _Chain_Get_unprotected( &information->Inactive );
657}
658
659/**
660 * @brief Checks if the automatic object extension (unlimited objects) is
661 * enabled.
662 *
663 * @param information The object information.
664 *
665 * @retval true The automatic object extension (unlimited objects) is enabled.
666 * @retval false The automatic object extension (unlimited objects) is not enabled.
667 */
668RTEMS_INLINE_ROUTINE Objects_Maximum _Objects_Is_auto_extend(
669  const Objects_Information *information
670)
671{
672  return information->objects_per_block != 0;
673}
674
675/**
676 * @brief Sets the pointer to the local_table object
677 * referenced by the index.
678 *
679 * @param[in, out] information Points to an Object Information Table.
680 * @param index The index of the object the caller wants to access.
681 * @param the_object The local object pointer.
682 *
683 * @note This routine is ONLY to be called in places where the
684 *       index portion of the Id is known to be good.  This is
685 *       OK since it is normally called from object create/init
686 *       or delete/destroy operations.
687 */
688
689RTEMS_INLINE_ROUTINE void _Objects_Set_local_object(
690  const Objects_Information *information,
691  uint32_t                   index,
692  Objects_Control           *the_object
693)
694{
695  /*
696   *  This routine is ONLY to be called from places in the code
697   *  where the Id is known to be good.  Therefore, this should NOT
698   *  occur in normal situations.
699   */
700  _Assert( index >= OBJECTS_INDEX_MINIMUM );
701  _Assert( index <= _Objects_Get_maximum_index( information ) );
702
703  information->local_table[ index - OBJECTS_INDEX_MINIMUM ] = the_object;
704}
705
706/**
707 * @brief Invalidates an object Id.
708 *
709 * This function sets the pointer to the local_table object
710 * referenced by the index to NULL so the object Id is invalid
711 * after this call.
712 *
713 * @param[in, out] information points to an Object Information Table.
714 * @param the_object The local object pointer.
715 *
716 * @note This routine is ONLY to be called in places where the
717 *       index portion of the Id is known to be good.  This is
718 *       OK since it is normally called from object create/init
719 *       or delete/destroy operations.
720 */
721
722RTEMS_INLINE_ROUTINE void _Objects_Invalidate_Id(
723  const Objects_Information *information,
724  Objects_Control           *the_object
725)
726{
727  _Assert( information != NULL );
728  _Assert( the_object != NULL );
729
730  _Objects_Set_local_object(
731    information,
732    _Objects_Get_index( the_object->id ),
733    NULL
734  );
735}
736
737/**
738 * @brief Places the_object control pointer and object name
739 *      in the Local Pointer and Local Name Tables, respectively.
740 *
741 * This method uses Objects_Name for the object name.
742 *
743 * @param[in, out] information Points to an Object Information Table.
744 * @param the_object Pointer to an object.
745 * @param name The name of the object to make accessible.
746 */
747RTEMS_INLINE_ROUTINE void _Objects_Open(
748  Objects_Information *information,
749  Objects_Control     *the_object,
750  Objects_Name         name
751)
752{
753  _Assert( information != NULL );
754  _Assert( the_object != NULL );
755
756  the_object->name = name;
757
758  _Objects_Set_local_object(
759    information,
760    _Objects_Get_index( the_object->id ),
761    the_object
762  );
763}
764
765/**
766 * @brief Places the_object control pointer and object name
767 *      in the Local Pointer and Local Name Tables, respectively.
768 *
769 * This method uses uint32_t for the object name.
770 *
771 * @param[in, out] information Points to an Object Information Table.
772 * @param the_object Pointer to an object.
773 * @param name The name of the object to make accessible.
774 */
775RTEMS_INLINE_ROUTINE void _Objects_Open_u32(
776  const Objects_Information *information,
777  Objects_Control           *the_object,
778  uint32_t                   name
779)
780{
781  _Assert( !_Objects_Has_string_name( information ) );
782  the_object->name.name_u32 = name;
783
784  _Objects_Set_local_object(
785    information,
786    _Objects_Get_index( the_object->id ),
787    the_object
788  );
789}
790
791/**
792 * @brief Places the_object control pointer and object name
793 *      in the Local Pointer and Local Name Tables, respectively.
794 *
795 * This method uses a String for the object name.
796 *
797 * @param[in, out] information Points to an Object Information Table.
798 * @param the_object Pointer to an object.
799 * @param name The name of the object to make accessible.
800 */
801RTEMS_INLINE_ROUTINE void _Objects_Open_string(
802  const Objects_Information *information,
803  Objects_Control           *the_object,
804  const char                *name
805)
806{
807  _Assert( _Objects_Has_string_name( information ) );
808  the_object->name.name_p = name;
809
810  _Objects_Set_local_object(
811    information,
812    _Objects_Get_index( the_object->id ),
813    the_object
814  );
815}
816
817/**
818 * @brief Locks the object allocator mutex.
819 *
820 * While holding the allocator mutex the executing thread is protected from
821 * asynchronous thread restart and deletion.
822 *
823 * The usage of the object allocator mutex with the thread life protection
824 * makes it possible to allocate and free objects without thread dispatching
825 * disabled.  The usage of a unified workspace and unlimited objects may lead
826 * to heap fragmentation.  Thus the execution time of the _Objects_Allocate()
827 * function may increase during system run-time.
828 *
829 * @see _Objects_Allocator_unlock() and _Objects_Allocate().
830 */
831RTEMS_INLINE_ROUTINE void _Objects_Allocator_lock( void )
832{
833  _RTEMS_Lock_allocator();
834}
835
836/**
837 * @brief Unlocks the object allocator mutex.
838 *
839 * In case the mutex is fully unlocked, then this function restores the
840 * previous thread life protection state and thus may not return if the
841 * executing thread was restarted or deleted in the mean-time.
842 */
843RTEMS_INLINE_ROUTINE void _Objects_Allocator_unlock( void )
844{
845  _RTEMS_Unlock_allocator();
846}
847
848/**
849 * @brief Checks if the allocator is the owner of the object allocator mutex
850 *
851 * @retval true The allocator is the owner of the object allocator mutex.
852 * @retval false The allocato is not the owner of the object allocator mutex.
853 */
854RTEMS_INLINE_ROUTINE bool _Objects_Allocator_is_owner( void )
855{
856  return _RTEMS_Allocator_is_owner();
857}
858
859/**
860 * @brief Allocates an object without locking the allocator mutex.
861 *
862 * This function can be called in two contexts
863 * - the executing thread is the owner of the object allocator mutex, or
864 * - in case the system state is not up, e.g. during sequential system
865 *   initialization.
866 *
867 * @param[in, out] information The object information block.
868 *
869 * @retval object The allocated object.
870 * @retval NULL No object available.
871 *
872 * @see _Objects_Allocate() and _Objects_Free().
873 */
874RTEMS_INLINE_ROUTINE Objects_Control *_Objects_Allocate_unprotected(
875  Objects_Information *information
876)
877{
878  _Assert(
879    _Objects_Allocator_is_owner()
880      || !_System_state_Is_up( _System_state_Get() )
881  );
882
883  return ( *information->allocate )( information );
884}
885
886/**
887 * @brief Frees an object.
888 *
889 * Appends the object to the chain of inactive objects.
890 *
891 * @param information The object information block.
892 * @param[out] the_object The object to free.
893 *
894 * @see _Objects_Allocate().
895 *
896 * A typical object deletion code looks like this:
897 * @code
898 * rtems_status_code some_delete( rtems_id id )
899 * {
900 *   Some_Control      *some;
901 *
902 *   // The object allocator mutex protects the executing thread from
903 *   // asynchronous thread restart and deletion.
904 *   _Objects_Allocator_lock();
905 *
906 *   // Get the object under protection of the object allocator mutex.
907 *   some = (Semaphore_Control *)
908 *     _Objects_Get_no_protection( id, &_Some_Information );
909 *
910 *   if ( some == NULL ) {
911 *     _Objects_Allocator_unlock();
912 *     return RTEMS_INVALID_ID;
913 *   }
914 *
915 *   // After the object close an object get with this identifier will
916 *   // fail.
917 *   _Objects_Close( &_Some_Information, &some->Object );
918 *
919 *   _Some_Delete( some );
920 *
921 *   // Thread dispatching is enabled.  The object free is only protected
922 *   // by the object allocator mutex.
923 *   _Objects_Free( &_Some_Information, &some->Object );
924 *
925 *   _Objects_Allocator_unlock();
926 *   return RTEMS_SUCCESSFUL;
927 * }
928 * @endcode
929 */
930RTEMS_INLINE_ROUTINE void _Objects_Free(
931  Objects_Information *information,
932  Objects_Control     *the_object
933)
934{
935  _Assert( _Objects_Allocator_is_owner() );
936  _Assert( information->deallocate != NULL );
937  ( *information->deallocate )( information, the_object );
938}
939
940/**
941 * @brief Activate the object.
942 *
943 * This function must be only used in case this objects information supports
944 * unlimited objects.
945 *
946 * @param information The object information block.
947 * @param the_object The object to activate.
948 */
949RTEMS_INLINE_ROUTINE void _Objects_Activate_unlimited(
950  Objects_Information *information,
951  Objects_Control     *the_object
952)
953{
954  Objects_Maximum objects_per_block;
955  Objects_Maximum block;
956
957  _Assert( _Objects_Is_auto_extend( information ) );
958
959  objects_per_block = information->objects_per_block;
960  block = _Objects_Get_index( the_object->id ) - OBJECTS_INDEX_MINIMUM;
961
962  if ( block > objects_per_block ) {
963    block /= objects_per_block;
964
965    information->inactive_per_block[ block ]--;
966    information->inactive--;
967  }
968}
969
970/**
971 * @brief Allocate an object and extend the objects information on demand.
972 *
973 * This function must be only used in case this objects information supports
974 * unlimited objects.
975 *
976 * @param information The object information block.
977 * @param extend The object information extend handler.
978 */
979RTEMS_INLINE_ROUTINE Objects_Control *_Objects_Allocate_with_extend(
980  Objects_Information   *information,
981  void                ( *extend )( Objects_Information * )
982)
983{
984  Objects_Control *the_object;
985
986  _Assert( _Objects_Is_auto_extend( information ) );
987
988  the_object = _Objects_Get_inactive( information );
989
990  if ( the_object == NULL ) {
991    ( *extend )( information );
992    the_object = _Objects_Get_inactive( information );
993  }
994
995  if ( the_object != NULL ) {
996    _Objects_Activate_unlimited( information, the_object );
997  }
998
999  return the_object;
1000}
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 */
Note: See TracBrowser for help on using the repository browser.