source: rtems/cpukit/score/include/rtems/score/objectimpl.h @ c42be504

5
Last change on this file since c42be504 was c42be504, checked in by Sebastian Huber <sebastian.huber@…>, on 11/16/16 at 13:50:09

posix: Add self-contained pthread spinlock

Turn pthread_spinlock_t into a self-contained object. On uni-processor
configurations, interrupts are disabled in the lock/trylock operations
and the previous interrupt status is restored in the corresponding
unlock operations. On SMP configurations, a ticket lock is a acquired
and released in addition.

The self-contained pthread_spinlock_t object is defined by Newlib in
<sys/_pthreadtypes.h>.

typedef struct {

struct _Ticket_lock_Control _lock;
uint32_t _interrupt_state;

} pthread_spinlock_t;

This implementation is simple and efficient. However, this test case of
the Linux Test Project would fail due to call of printf() and sleep()
during spin lock ownership:

https://github.com/linux-test-project/ltp/blob/master/testcases/open_posix_testsuite/conformance/interfaces/pthread_spin_lock/1-2.c

There is only limited support for profiling on SMP configurations.

Delete CORE spinlock implementation.

Update #2674.

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