source: rtems/cpukit/include/rtems/score/objectimpl.h @ 36655b8

Last change on this file since 36655b8 was 36655b8, checked in by Sebastian Huber <sebastian.huber@…>, on 07/16/21 at 11:27:00

cpukit: occured -> occurred

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