source: rtems/cpukit/libdl/rtl-allocator.c @ 4f1bbbfc

4.115
Last change on this file since 4f1bbbfc was 4f1bbbfc, checked in by Chris Johns <chrisj@…>, on 11/19/14 at 21:43:15

libdl: Add a comment.

See ref #2191.

  • Property mode set to 100644
File size: 5.5 KB
Line 
1/*
2 *  COPYRIGHT (c) 2012 Chris Johns <chrisj@rtems.org>
3 *
4 *  The license and distribution terms for this file may be
5 *  found in the file LICENSE in this distribution or at
6 *  http://www.rtems.org/license/LICENSE.
7 */
8/**
9 * @file
10 *
11 * @ingroup rtems_rtl
12 *
13 * @brief RTEMS Run-Time Linker Allocator
14 */
15
16#include <stdio.h>
17
18#include <rtems/rtl/rtl.h>
19#include "rtl-alloc-heap.h"
20#include "rtl-trace.h"
21
22/**
23 * Tags as symbols for tracing.
24 */
25#if RTEMS_RTL_TRACE
26static const char* tag_labels[6] =
27{
28  "OBJECT",
29  "SYMBOL",
30  "EXTERNAL",
31  "READ",
32  "READ_WRITE",
33  "READ_EXEC",
34};
35#define rtems_rtl_trace_tag_label(_l) tag_labels[_l]
36#else
37#define rtems_rtl_trace_tag_label(_l) ""
38#endif
39
40void
41rtems_rtl_alloc_initialise (rtems_rtl_alloc_data_t* data)
42{
43  int c;
44  data->allocator = rtems_rtl_alloc_heap;
45  for (c = 0; c < RTEMS_RTL_ALLOC_TAGS; ++c)
46    rtems_chain_initialize_empty (&data->indirects[c]);
47}
48
49void*
50rtems_rtl_alloc_new (rtems_rtl_alloc_tag_t tag, size_t size, bool zero)
51{
52  rtems_rtl_data_t* rtl = rtems_rtl_lock ();
53  void*             address = NULL;
54
55  /*
56   * Obtain memory from the allocator.
57   */
58  if (rtl)
59    rtl->allocator.allocator (true, tag, &address, size);
60
61  rtems_rtl_unlock ();
62
63  if (rtems_rtl_trace (RTEMS_RTL_TRACE_ALLOCATOR))
64    printf ("rtl: alloc: new: %s addr=%p size=%zu\n",
65            rtems_rtl_trace_tag_label (tag), address, size);
66
67  /*
68   * Only zero the memory if asked to and the allocation was successful.
69   */
70  if (address && zero)
71    memset (address, 0, size);
72
73  return address;
74}
75
76void
77rtems_rtl_alloc_del (rtems_rtl_alloc_tag_t tag, void* address)
78{
79  rtems_rtl_data_t* rtl = rtems_rtl_lock ();
80
81  if (rtems_rtl_trace (RTEMS_RTL_TRACE_ALLOCATOR))
82    printf ("rtl: alloc: del: %s addr=%p\n",
83            rtems_rtl_trace_tag_label (tag), address);
84
85  if (rtl && address)
86    rtl->allocator.allocator (false, tag, &address, 0);
87
88  rtems_rtl_unlock ();
89}
90
91rtems_rtl_allocator_t
92rtems_rtl_alloc_hook (rtems_rtl_allocator_t handler)
93{
94  rtems_rtl_data_t* rtl = rtems_rtl_lock ();
95  rtems_rtl_allocator_t previous = rtl->allocator.allocator;
96  rtl->allocator.allocator = handler;
97  rtems_rtl_unlock ();
98  return previous;
99}
100
101void
102rtems_rtl_alloc_indirect_new (rtems_rtl_alloc_tag_t tag,
103                              rtems_rtl_ptr_t*      handle,
104                              size_t                size)
105{
106  rtems_rtl_data_t* rtl = rtems_rtl_lock ();
107
108  if (rtems_rtl_trace (RTEMS_RTL_TRACE_ALLOCATOR))
109  {
110    if (!rtems_rtl_ptr_null (handle))
111      printf ("rtl: alloc: inew: %s handle=%p: not null\n",
112              rtems_rtl_trace_tag_label (tag), handle);
113    printf ("rtl: alloc: inew: %s handle=%p size=%zd\n",
114            rtems_rtl_trace_tag_label (tag), handle, size);
115  }
116
117  if (rtl)
118  {
119    rtems_rtl_alloc_data_t* allocator = &rtl->allocator;
120    handle->pointer = rtems_rtl_alloc_new (tag, size, false);
121    if (!rtems_rtl_ptr_null (handle))
122      rtems_chain_append_unprotected (&allocator->indirects[tag],
123                                      &handle->node);
124  }
125
126  rtems_rtl_unlock ();
127}
128
129void
130rtems_rtl_alloc_indirect_del (rtems_rtl_alloc_tag_t tag,
131                              rtems_rtl_ptr_t*      handle)
132{
133  rtems_rtl_data_t* rtl = rtems_rtl_lock ();
134
135  if (rtems_rtl_trace (RTEMS_RTL_TRACE_ALLOCATOR))
136  {
137    if (rtems_rtl_ptr_null (handle))
138      printf ("rtl: alloc: idel: %s handle=%p: is null\n",
139              rtems_rtl_trace_tag_label (tag), handle);
140    printf ("rtl: alloc: idel: %s handle=%p\n",
141            rtems_rtl_trace_tag_label (tag), handle);
142  }
143
144  if (rtl && !rtems_rtl_ptr_null (handle))
145  {
146    rtems_chain_extract_unprotected (&handle->node);
147    rtems_rtl_alloc_del (tag, &handle->pointer);
148  }
149}
150
151bool
152rtems_rtl_alloc_module_new (void** text_base, size_t text_size,
153                            void** const_base, size_t const_size,
154                            void** data_base, size_t data_size,
155                            void** bss_base, size_t bss_size)
156{
157  *text_base = *const_base = *data_base = *bss_base = NULL;
158
159  if (text_size)
160  {
161    *text_base = rtems_rtl_alloc_new (RTEMS_RTL_ALLOC_READ_EXEC,
162                                      text_size, false);
163    if (!*text_base)
164    {
165      return false;
166    }
167  }
168
169  if (const_size)
170  {
171    *const_base = rtems_rtl_alloc_new (RTEMS_RTL_ALLOC_READ,
172                                       const_size, false);
173    if (!*const_base)
174    {
175      rtems_rtl_alloc_module_del (text_base, const_base, data_base, bss_base);
176      return false;
177    }
178  }
179
180  if (data_size)
181  {
182    *data_base = rtems_rtl_alloc_new (RTEMS_RTL_ALLOC_READ_WRITE,
183                                      data_size, false);
184    if (!*data_base)
185    {
186      rtems_rtl_alloc_module_del (text_base, const_base, data_base, bss_base);
187      return false;
188    }
189  }
190
191  if (bss_size)
192  {
193    *bss_base = rtems_rtl_alloc_new (RTEMS_RTL_ALLOC_READ_WRITE,
194                                     bss_size, false);
195    if (!*bss_base)
196    {
197      rtems_rtl_alloc_module_del (text_base, const_base, data_base, bss_base);
198      return false;
199    }
200  }
201
202  return true;
203}
204
205void
206rtems_rtl_alloc_module_del (void** text_base,
207                            void** const_base,
208                            void** data_base,
209                            void** bss_base)
210{
211  rtems_rtl_alloc_del (RTEMS_RTL_ALLOC_READ_WRITE, *bss_base);
212  rtems_rtl_alloc_del (RTEMS_RTL_ALLOC_READ_WRITE, *data_base);
213  rtems_rtl_alloc_del (RTEMS_RTL_ALLOC_READ, *const_base);
214  rtems_rtl_alloc_del (RTEMS_RTL_ALLOC_READ_EXEC, *text_base);
215  *text_base = *const_base = *data_base = *bss_base = NULL;
216}
Note: See TracBrowser for help on using the repository browser.