blob: 81503a3b459fffc31e571750a757ff96ccd86344 (
plain) (
tree)
|
|
/*
* COPYRIGHT (c) 2012 Chris Johns <chrisj@rtems.org>
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.org/license/LICENSE.
*/
/**
* @file
*
* @ingroup rtems_rtl
*
* @brief RTEMS Run-Time Linker Indirect Pointer Management allows memory
* compaction in the allocator.
*/
#if !defined (_RTEMS_RTL_INDIRECT_PTR_H_)
#define _RTEMS_RTL_INDIRECT_PTR_H_
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
#include <rtems/chain.h>
/**
* The RTL Indirect pointer.
*/
struct rtems_rtl_ptr_s {
rtems_chain_node node; /**< Indirect pointers are held on lists. */
void* pointer; /**< The actual pointer. */
};
typedef struct rtems_rtl_ptr_s rtems_rtl_ptr_t;
/**
* The RTL Indirect size and pointer.
*/
struct rtems_rtl_sptr_s {
rtems_rtl_ptr_t ptr; /**< The indirect pointer. */
size_t size; /**< The size of the memory block. */
};
typedef struct rtems_rtl_sptr_s rtems_rtl_sptr_t;
/**
* A chain of indirect pointers for users to chain in applications.
*
* @note The chain the pointer is on is internal to the allocator and cannot be
* used by applications.
*/
struct rtems_rtl_ptr_chain_s {
rtems_chain_node node; /**< Chain of indirect pointers. */
rtems_rtl_ptr_t ptr; /**< The indirect pointer. */
};
typedef struct rtems_rtl_ptr_chain_s rtems_rtl_ptr_chain_t;
/**
* A chain of indirect sized pointers for users to chain in applications.
*
* @note The chain the pointer is on is internal to the allocator and cannot be
* used by applications.
*/
struct rtems_rtl_sptr_chain_s {
rtems_chain_node node; /**< Chain of indirect pointers. */
rtems_rtl_sptr_t ptr; /**< The indirect pointer. */
};
typedef struct rtems_rtl_sptr_chain_s rtems_rtl_sptr_chain_t;
/**
* Get the pointer given an indirect handle.
*
* @param handle The handle the pointer is returned from.
* @return void* The pointer held in the handle.
*/
static inline void* rtems_rtl_ptr_get (rtems_rtl_ptr_t* handle)
{
return handle->pointer;
}
/**
* Set the pointer given an indirect handle and the pointer.
*
* @param handle The handle the pointer is returned from.
* @param pointer The pointer to set in the handle.
*/
static inline void rtems_rtl_ptr_set (rtems_rtl_ptr_t* handle, void* pointer)
{
handle->pointer = pointer;
}
/**
* Initialise the indirect handle.
*
* @param handle The handle to initialise.
*/
static inline void rtems_rtl_ptr_init (rtems_rtl_ptr_t* handle)
{
rtems_chain_set_off_chain (&handle->node);
handle->pointer = NULL;
}
/**
* Is the indirect handle NULL ?
*
* @param handle The handle to test.
* @return bool True if the pointer is NULL.
*/
static inline bool rtems_rtl_ptr_null (rtems_rtl_ptr_t* handle)
{
return handle->pointer == NULL;
}
/**
* Move the allocated pointer from one handle to another. The source handle is
* cleared and removed from the list of handles.
*
* @param src The source handle to move the pointer from.
* @param dst The destination handle to receive the pointer.
*/
static inline void rtems_rtl_ptr_move (rtems_rtl_ptr_t* dst, rtems_rtl_ptr_t* src)
{
/*
* We do not know which chain the src handle resides on so insert the dst
* handle after the src handle then extract the src handle.
*/
rtems_chain_insert_unprotected (&src->node, &dst->node);
rtems_chain_extract_unprotected (&src->node);
dst->pointer = src->pointer;
rtems_rtl_ptr_init (src);
}
/**
* Return the pointer as the type provided.
*
* @param _h The handle.
* @param _t The type.
*/
#define rtems_rtl_ptr_type_get(_h, _t) ((_t*) rtems_rtl_ptr_get (_h))
/**
* Get the pointer given an indirect handle.
*
* @param handle The handle the pointer is returned from.
* @return void* The pointer held in the handle.
*/
static inline void* rtems_rtl_sptr_get (rtems_rtl_sptr_t* handle)
{
return rtems_rtl_ptr_get (&handle->ptr);
}
/**
* Set the pointer given an indirect handle and the pointer.
*
* @param handle The handle the pointer is returned from.
* @param pointer The pointer to set in the handle.
*/
static inline void rtems_rtl_sptr_set (rtems_rtl_sptr_t* handle, void* pointer)
{
rtems_rtl_ptr_set (&handle->ptr, pointer);
}
/**
* Initialise the indirect handle.
*
* @param handle The handle to initialise.
*/
static inline void rtems_rtl_sptr_init (rtems_rtl_sptr_t* handle)
{
rtems_rtl_ptr_init (&handle->ptr);
handle->size = 0;
}
/**
* Is the indirect handle NULL ?
*
* @param handle The handle to test.
* @return bool True if the pointer is NULL.
*/
static inline bool rtems_rtl_sptr_null (rtems_rtl_sptr_t* handle)
{
return rtems_rtl_ptr_null (&handle->ptr);
}
/**
* Move the allocated pointer from one handle to another. The source handle is
* cleared and removed from the list of handles.
*
* @param src The source handle to move the pointer from.
* @param dst The destination handle to receive the pointer.
*/
static inline void rtems_rtl_sptr_move (rtems_rtl_sptr_t* dst, rtems_rtl_sptr_t* src)
{
rtems_rtl_ptr_move (&dst->ptr, &src->ptr);
dst->size = src->size;
src->size = 0;
}
/**
* Get the size.
*
* @param handle The handle to get the size from.
* @return size_t The size_t.
*/
static inline size_t rtems_rtl_sptr_get_size (rtems_rtl_sptr_t* handle)
{
return handle->size;
}
/**
* Set the size.
*
* @param handle The handle to set the size.
* @param size The size to set..
*/
static inline void rtems_rtl_sptr_set_size (rtems_rtl_sptr_t* handle, size_t size)
{
handle->size = size;
}
/**
* Return the pointer as the type provided.
*
* @param _h The handle.
* @param _t The type.
*/
#define rtems_rtl_sptr_type_get(_h, _t) ((_t*) rtems_rtl_sptr_get (_h))
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif
|