summaryrefslogtreecommitdiffstats
path: root/cpukit/include/rtems/rtl/rtl-indirect-ptr.h
blob: dbfa70679c2786c7f397627abef99393cde45ced (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
/*
 *  COPYRIGHT (c) 2012, 2018 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 {
  rtems_chain_node node;     /**< Indirect pointers are held on lists. */
  void*            pointer;  /**< The actual pointer. */
};

typedef struct rtems_rtl_ptr rtems_rtl_ptr;

/**
 * The RTL Indirect size and pointer.
 */
struct rtems_rtl_sptr {
  rtems_rtl_ptr  ptr;      /**< The indirect pointer. */
  size_t         size;     /**< The size of the memory block. */
};

typedef struct rtems_rtl_sptr rtems_rtl_sptr;

/**
 * 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 {
  rtems_chain_node node;  /**< Chain of indirect pointers. */
  rtems_rtl_ptr    ptr;   /**< The indirect pointer. */
};

typedef struct rtems_rtl_ptr_chain rtems_rtl_ptr_chain;

/**
 * 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 {
  rtems_chain_node node; /**< Chain of indirect pointers. */
  rtems_rtl_sptr   ptr;  /**< The indirect pointer. */
};

typedef struct rtems_rtl_sptr_chain rtems_rtl_sptr_chain;

/**
 * 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* 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* 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* 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* 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* dst, rtems_rtl_ptr* 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* 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* 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* 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* 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* dst, rtems_rtl_sptr* 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* 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* 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