Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:24:12

0001 /* SPDX-License-Identifier: BSD-2-Clause */
0002 
0003 /*
0004  *  COPYRIGHT (c) 2012, 2018 Chris Johns <chrisj@rtems.org>
0005  *
0006  * Redistribution and use in source and binary forms, with or without
0007  * modification, are permitted provided that the following conditions
0008  * are met:
0009  * 1. Redistributions of source code must retain the above copyright
0010  *    notice, this list of conditions and the following disclaimer.
0011  * 2. Redistributions in binary form must reproduce the above copyright
0012  *    notice, this list of conditions and the following disclaimer in the
0013  *    documentation and/or other materials provided with the distribution.
0014  *
0015  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
0016  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
0017  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
0018  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
0019  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
0020  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
0021  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
0022  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
0023  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
0024  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
0025  * POSSIBILITY OF SUCH DAMAGE.
0026  */
0027 /**
0028  * @file
0029  *
0030  * @ingroup rtems_rtl
0031  *
0032  * @brief RTEMS Run-Time Linker Indirect Pointer Management allows memory
0033  *        compaction in the allocator.
0034  */
0035 
0036 #if !defined (_RTEMS_RTL_INDIRECT_PTR_H_)
0037 #define _RTEMS_RTL_INDIRECT_PTR_H_
0038 
0039 #ifdef __cplusplus
0040 extern "C" {
0041 #endif /* __cplusplus */
0042 
0043 #include <rtems/chain.h>
0044 
0045 /**
0046  * The RTL Indirect pointer.
0047  */
0048 struct rtems_rtl_ptr {
0049   rtems_chain_node node;     /**< Indirect pointers are held on lists. */
0050   void*            pointer;  /**< The actual pointer. */
0051 };
0052 
0053 typedef struct rtems_rtl_ptr rtems_rtl_ptr;
0054 
0055 /**
0056  * The RTL Indirect size and pointer.
0057  */
0058 struct rtems_rtl_sptr {
0059   rtems_rtl_ptr  ptr;      /**< The indirect pointer. */
0060   size_t         size;     /**< The size of the memory block. */
0061 };
0062 
0063 typedef struct rtems_rtl_sptr rtems_rtl_sptr;
0064 
0065 /**
0066  * A chain of indirect pointers for users to chain in applications.
0067  *
0068  * @note The chain the pointer is on is internal to the allocator and cannot be
0069  *       used by applications.
0070  */
0071 struct rtems_rtl_ptr_chain {
0072   rtems_chain_node node;  /**< Chain of indirect pointers. */
0073   rtems_rtl_ptr    ptr;   /**< The indirect pointer. */
0074 };
0075 
0076 typedef struct rtems_rtl_ptr_chain rtems_rtl_ptr_chain;
0077 
0078 /**
0079  * A chain of indirect sized pointers for users to chain in applications.
0080  *
0081  * @note The chain the pointer is on is internal to the allocator and cannot be
0082  *       used by applications.
0083  */
0084 struct rtems_rtl_sptr_chain {
0085   rtems_chain_node node; /**< Chain of indirect pointers. */
0086   rtems_rtl_sptr   ptr;  /**< The indirect pointer. */
0087 };
0088 
0089 typedef struct rtems_rtl_sptr_chain rtems_rtl_sptr_chain;
0090 
0091 /**
0092  * Get the pointer given an indirect handle.
0093  *
0094  * @param handle The handle the pointer is returned from.
0095  * @return void* The pointer held in the handle.
0096  */
0097 static inline void* rtems_rtl_ptr_get (rtems_rtl_ptr* handle)
0098 {
0099   return handle->pointer;
0100 }
0101 
0102 /**
0103  * Set the pointer given an indirect handle and the pointer.
0104  *
0105  * @param handle The handle the pointer is returned from.
0106  * @param pointer The pointer to set in the handle.
0107  */
0108 static inline void rtems_rtl_ptr_set (rtems_rtl_ptr* handle, void* pointer)
0109 {
0110   handle->pointer = pointer;
0111 }
0112 
0113 /**
0114  * Initialise the indirect handle.
0115  *
0116  * @param handle The handle to initialise.
0117  */
0118 static inline void rtems_rtl_ptr_init (rtems_rtl_ptr* handle)
0119 {
0120   rtems_chain_set_off_chain (&handle->node);
0121   handle->pointer = NULL;
0122 }
0123 
0124 /**
0125  * Is the indirect handle NULL ?
0126  *
0127  * @param handle The handle to test.
0128  * @return bool True if the pointer is NULL.
0129  */
0130 static inline bool rtems_rtl_ptr_null (rtems_rtl_ptr* handle)
0131 {
0132   return handle->pointer == NULL;
0133 }
0134 
0135 /**
0136  * Move the allocated pointer from one handle to another. The source handle is
0137  * cleared and removed from the list of handles.
0138  *
0139  * @param src The source handle to move the pointer from.
0140  * @param dst The destination handle to receive the pointer.
0141  */
0142 static inline void rtems_rtl_ptr_move (rtems_rtl_ptr* dst, rtems_rtl_ptr* src)
0143 {
0144   /*
0145    * We do not know which chain the src handle resides on so insert the dst
0146    * handle after the src handle then extract the src handle.
0147    */
0148   rtems_chain_insert_unprotected (&src->node, &dst->node);
0149   rtems_chain_extract_unprotected (&src->node);
0150   dst->pointer = src->pointer;
0151   rtems_rtl_ptr_init (src);
0152 }
0153 
0154 /**
0155  * Return the pointer as the type provided.
0156  *
0157  * @param _h The handle.
0158  * @param _t The type.
0159  */
0160 #define rtems_rtl_ptr_type_get(_h, _t) ((_t*) rtems_rtl_ptr_get (_h))
0161 
0162 /**
0163  * Get the pointer given an indirect handle.
0164  *
0165  * @param handle The handle the pointer is returned from.
0166  * @return void* The pointer held in the handle.
0167  */
0168 static inline void* rtems_rtl_sptr_get (rtems_rtl_sptr* handle)
0169 {
0170   return rtems_rtl_ptr_get (&handle->ptr);
0171 }
0172 
0173 /**
0174  * Set the pointer given an indirect handle and the pointer.
0175  *
0176  * @param handle The handle the pointer is returned from.
0177  * @param pointer The pointer to set in the handle.
0178  */
0179 static inline void rtems_rtl_sptr_set (rtems_rtl_sptr* handle, void* pointer)
0180 {
0181   rtems_rtl_ptr_set (&handle->ptr, pointer);
0182 }
0183 
0184 /**
0185  * Initialise the indirect handle.
0186  *
0187  * @param handle The handle to initialise.
0188  */
0189 static inline void rtems_rtl_sptr_init (rtems_rtl_sptr* handle)
0190 {
0191   rtems_rtl_ptr_init (&handle->ptr);
0192   handle->size = 0;
0193 }
0194 
0195 /**
0196  * Is the indirect handle NULL ?
0197  *
0198  * @param handle The handle to test.
0199  * @return bool True if the pointer is NULL.
0200  */
0201 static inline bool rtems_rtl_sptr_null (rtems_rtl_sptr* handle)
0202 {
0203   return rtems_rtl_ptr_null (&handle->ptr);
0204 }
0205 
0206 /**
0207  * Move the allocated pointer from one handle to another. The source handle is
0208  * cleared and removed from the list of handles.
0209  *
0210  * @param src The source handle to move the pointer from.
0211  * @param dst The destination handle to receive the pointer.
0212  */
0213 static inline void rtems_rtl_sptr_move (rtems_rtl_sptr* dst, rtems_rtl_sptr* src)
0214 {
0215   rtems_rtl_ptr_move (&dst->ptr, &src->ptr);
0216   dst->size = src->size;
0217   src->size = 0;
0218 }
0219 
0220 /**
0221  * Get the size.
0222  *
0223  * @param handle The handle to get the size from.
0224  * @return size_t The size_t.
0225  */
0226 static inline size_t rtems_rtl_sptr_get_size (rtems_rtl_sptr* handle)
0227 {
0228   return handle->size;
0229 }
0230 
0231 /**
0232  * Set the size.
0233  *
0234  * @param handle The handle to set the size.
0235  * @param size The size to set..
0236  */
0237 static inline void rtems_rtl_sptr_set_size (rtems_rtl_sptr* handle, size_t size)
0238 {
0239   handle->size = size;
0240 }
0241 
0242 /**
0243  * Return the pointer as the type provided.
0244  *
0245  * @param _h The handle.
0246  * @param _t The type.
0247  */
0248 #define rtems_rtl_sptr_type_get(_h, _t) ((_t*) rtems_rtl_sptr_get (_h))
0249 
0250 #ifdef __cplusplus
0251 }
0252 #endif /* __cplusplus */
0253 
0254 #endif