source: rtems/c/src/exec/libcsupport/src/malloc.c @ e8512eb

4.104.114.84.95
Last change on this file since e8512eb was e8512eb, checked in by Joel Sherrill <joel.sherrill@…>, on Jun 5, 1995 at 10:59:47 PM

incorporate Tony's patches:

+ c/src/lib/libc/support/generic/malloc.c did not initialize the

sbrk amount

+ _Thread_Handler in c/src/exec/rtems/thread.c left a window

during the begin extension which could result in a context switch

fixed places which did not correctly distinguish between an
CPU_isr and a CPU_isr_entry.

  • Property mode set to 100644
File size: 5.5 KB
Line 
1/*
2 *  RTEMS Malloc Family Implementation
3 *
4 *
5 *  COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994.
6 *  On-Line Applications Research Corporation (OAR).
7 *  All rights assigned to U.S. Government, 1994.
8 *
9 *  This material may be reproduced by or for the U.S. Government pursuant
10 *  to the copyright license under the clause at DFARS 252.227-7013.  This
11 *  notice must appear in all copies of this file and its derivatives.
12 *
13 *  $Id$
14 */
15
16#include <rtems.h>
17#ifdef RTEMS_LIBC
18#include <memory.h>
19#endif
20#include "libcsupport.h"
21#ifdef RTEMS_NEWLIB
22#include <sys/reent.h>
23#endif
24
25#include <stdio.h>
26#include <stdlib.h>
27#include <sys/types.h>
28#include <assert.h>
29#include <errno.h>
30#include <string.h>
31
32/*
33 *  XXX: Do we really need to duplicate these? It appears that they
34 *       only cause typing problems.
35 */
36
37#if 0
38void *malloc(size_t);
39void *calloc(size_t, size_t);
40void *realloc(void *, size_t);
41void free(void *);
42void *sbrk(size_t);
43#endif
44
45rtems_id RTEMS_Malloc_Heap;
46size_t RTEMS_Malloc_Sbrk_amount;
47
48void RTEMS_Malloc_Initialize(
49  void   *start,
50  size_t  length,
51  size_t  sbrk_amount
52)
53{
54  rtems_status_code   status;
55  void               *starting_address;
56  rtems_unsigned32    u32_address;
57
58  /*
59   * If the starting address is 0 then we are to attempt to
60   * get length worth of memory using sbrk. Make sure we
61   * align the address that we get back.
62   */
63
64  starting_address = start;
65  RTEMS_Malloc_Sbrk_amount = sbrk_amount;
66
67  if (!starting_address) {
68    u32_address = (unsigned int)sbrk(length);
69
70    if (u32_address == -1) {
71      rtems_fatal_error_occurred( RTEMS_NO_MEMORY );
72      /* DOES NOT RETURN!!! */
73    }
74
75    if (u32_address & (CPU_ALIGNMENT-1)) {
76      u32_address = (u32_address + CPU_ALIGNMENT) & ~(CPU_ALIGNMENT-1);
77      /* XXX: if we do any alignment .. then length should be shortened */
78    }
79
80    starting_address = (void *)u32_address;
81  }
82
83  /*
84   *  Unfortunately we cannot use assert if this fails because if this
85   *  has failed we do not have a heap and if we do not have a heap
86   *  STDIO cannot work because there will be no buffers.
87   */
88
89  status = rtems_region_create(
90    rtems_build_name( 'H', 'E', 'A', 'P' ),
91    starting_address,
92    length,
93    8,                     /* XXX : use CPU dependent RTEMS constant */
94    RTEMS_DEFAULT_ATTRIBUTES,
95    &RTEMS_Malloc_Heap
96  );
97  if ( status != RTEMS_SUCCESSFUL )
98    rtems_fatal_error_occurred( status );
99}
100
101void *malloc(
102  size_t  size
103)
104{
105  void              *return_this;
106  void              *starting_address;
107  rtems_unsigned32   the_size;
108  rtems_unsigned32   sbrk_amount;
109  rtems_status_code  status;
110
111  if ( !size )
112    return (void *) 0;
113
114  /*
115   * Try to give a segment in the current region if there is not
116   * enough space then try to grow the region using rtems_region_extend().
117   * If this fails then return a NULL pointer.
118   */
119
120  status = rtems_region_get_segment(
121    RTEMS_Malloc_Heap,
122    size,
123    RTEMS_NO_WAIT,
124    RTEMS_NO_TIMEOUT,
125    &return_this
126  );
127
128  if ( status != RTEMS_SUCCESSFUL ) {
129    /*
130     *  Round to the "requested sbrk amount" so hopefully we won't have
131     *  to grow again for a while.  This effectively does sbrk() calls
132     *  in "page" amounts.
133     */
134
135    sbrk_amount = RTEMS_Malloc_Sbrk_amount;
136
137    if ( sbrk_amount == 0 )
138      return (void *) 0;
139
140    the_size = ((size + sbrk_amount) / sbrk_amount * sbrk_amount);
141
142    if (((rtems_unsigned32)starting_address = sbrk(the_size)) == -1)
143      return (void *) 0;
144
145    /*
146    fprintf(stderr, "Extended the C heap starting at 0x%x for %d bytes\n",
147        (unsigned32)starting_address, the_size);
148     */
149
150    status = rtems_region_extend(
151      RTEMS_Malloc_Heap,
152      starting_address,
153      the_size
154    );
155    if ( status != RTEMS_SUCCESSFUL ) {
156      sbrk(-the_size);
157      return(FALSE);
158      errno = ENOMEM;
159      return (void *) 0;
160    }
161    status = rtems_region_get_segment(
162      RTEMS_Malloc_Heap,
163       size,
164       RTEMS_NO_WAIT,
165       RTEMS_NO_TIMEOUT,
166       &return_this
167    );
168    if ( status != RTEMS_SUCCESSFUL ) {
169      errno = ENOMEM;
170      return (void *) 0;
171    }
172  }
173
174  return return_this;
175}
176
177void *calloc(
178  size_t nelem,
179  size_t elsize
180)
181{
182  register char *cptr;
183  int length;
184
185  length = nelem * elsize;
186  cptr = malloc( length );
187  if ( cptr )
188    memset( cptr, '\0', length );
189
190  return cptr;
191}
192
193void *realloc(
194  void *ptr,
195  size_t size
196)
197{
198  rtems_unsigned32  old_size;
199  rtems_status_code status;
200  char *new_area;
201
202  if ( !ptr )
203    return malloc( size );
204
205  if ( !size ) {
206    free( ptr );
207    return (void *) 0;
208  }
209
210  status = rtems_region_get_segment_size( RTEMS_Malloc_Heap, ptr, &old_size );
211  if ( status != RTEMS_SUCCESSFUL ) {
212    errno = EINVAL;
213    return (void *) 0;
214  }
215
216  new_area = malloc( size );
217  if ( !new_area ) {
218    free( ptr );
219    return (void *) 0;
220  }
221
222  memcpy( new_area, ptr, (size < old_size) ? size : old_size );
223  free( ptr );
224
225  return new_area;
226
227}
228
229void free(
230  void *ptr
231)
232{
233  rtems_status_code status;
234
235  if ( !ptr )
236    return;
237
238  status = rtems_region_return_segment( RTEMS_Malloc_Heap, ptr );
239  if ( status != RTEMS_SUCCESSFUL ) {
240    errno = EINVAL;
241    assert( 0 );
242  }
243}
244
245/*
246 *  "Reentrant" versions of the above routines implemented above.
247 */
248
249#ifdef RTEMS_NEWLIB
250void *malloc_r(
251  struct _reent *ignored,
252  size_t  size
253)
254{
255  return malloc( size );
256}
257
258void *calloc_r(
259  size_t nelem,
260  size_t elsize
261)
262{
263  return calloc( nelem, elsize );
264}
265
266void *realloc_r(
267  void *ptr,
268  size_t size
269)
270{
271  return realloc_r( ptr, size );
272}
273
274void free_r(
275  void *ptr
276)
277{
278  free( ptr );
279}
280#endif
281
Note: See TracBrowser for help on using the repository browser.