1 //========================================================================
5 // Implementation of ISO C memory allocation routines
7 //========================================================================
8 //####ECOSGPLCOPYRIGHTBEGIN####
9 // -------------------------------------------
10 // This file is part of eCos, the Embedded Configurable Operating System.
11 // Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
13 // eCos is free software; you can redistribute it and/or modify it under
14 // the terms of the GNU General Public License as published by the Free
15 // Software Foundation; either version 2 or (at your option) any later version.
17 // eCos is distributed in the hope that it will be useful, but WITHOUT ANY
18 // WARRANTY; without even the implied warranty of MERCHANTABILITY or
19 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22 // You should have received a copy of the GNU General Public License along
23 // with eCos; if not, write to the Free Software Foundation, Inc.,
24 // 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
26 // As a special exception, if other files instantiate templates or use macros
27 // or inline functions from this file, or you compile this file and link it
28 // with other works to produce a work based on this file, this file does not
29 // by itself cause the resulting work to be covered by the GNU General Public
30 // License. However the source code for this file must still be made available
31 // in accordance with section (3) of the GNU General Public License.
33 // This exception does not invalidate any other reasons why a work based on
34 // this file might be covered by the GNU General Public License.
36 // Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
37 // at http://sources.redhat.com/ecos/ecos-license/
38 // -------------------------------------------
39 //####ECOSGPLCOPYRIGHTEND####
40 //========================================================================
41 //#####DESCRIPTIONBEGIN####
43 // Author(s): jlarmour
46 // Purpose: Provides ISO C calloc(), malloc(), realloc() and free()
48 // Description: Implementation of ISO standard allocation routines as per
49 // ISO C section 7.10.3
52 //####DESCRIPTIONEND####
54 //========================================================================
58 #include <pkgconf/memalloc.h> // Configuration header
60 // Do we want these functions?
61 #ifdef CYGPKG_MEMALLOC_MALLOC_ALLOCATORS
65 #include <cyg/infra/cyg_type.h> // Common type definitions and support
66 #include <cyg/infra/cyg_trac.h> // Common tracing support
67 #include <cyg/infra/cyg_ass.h> // Common assertion support
68 #include <string.h> // For memset() and memmove()
69 #include <stdlib.h> // header for this file
70 #ifdef CYGBLD_MEMALLOC_MALLOC_EXTERNAL_HEAP_H
71 # include CYGBLD_MEMALLOC_MALLOC_EXTERNAL_HEAP_H
73 # include <pkgconf/heaps.hxx> // heap pools information
75 #include CYGBLD_MEMALLOC_MALLOC_IMPLEMENTATION_HEADER
79 // First deal with the worst case, that the memory layout didn't define a
81 #if CYGMEM_HEAP_COUNT == 0
83 // the data space for the memory pool
84 cyg_uint8 cyg_memalloc_mallocpool_memory[
85 CYGNUM_MEMALLOC_FALLBACK_MALLOC_POOL_SIZE ] CYGBLD_ATTRIB_WEAK;
87 // the memory pool object itself
88 CYGCLS_MEMALLOC_MALLOC_IMPL cyg_memalloc_mallocpool
89 CYGBLD_ATTRIB_INIT_BEFORE( CYG_INIT_LIBC ) =
90 CYGCLS_MEMALLOC_MALLOC_IMPL( cyg_memalloc_mallocpool_memory,
91 sizeof( cyg_memalloc_mallocpool_memory ) );
93 # define POOL cyg_memalloc_mallocpool
95 #elif CYGMEM_HEAP_COUNT == 1
96 // one heap, so it's straightforward
98 # define POOL (*cygmem_memalloc_heaps[0])
103 # include <cyg/memalloc/memjoin.hxx>
105 Cyg_Mempool_Joined<CYGCLS_MEMALLOC_MALLOC_IMPL> cyg_memalloc_mallocpool
106 CYGBLD_ATTRIB_INIT_BEFORE( CYG_INIT_LIBC ) =
107 Cyg_Mempool_Joined<CYGCLS_MEMALLOC_MALLOC_IMPL>(
108 CYGMEM_HEAP_COUNT, cygmem_memalloc_heaps
111 # define POOL cyg_memalloc_mallocpool
118 malloc( size_t size )
122 CYG_REPORT_FUNCNAMETYPE( "malloc", "returning pointer %08x" );
124 CYG_REPORT_FUNCARG1DV( size );
126 #ifdef CYGSEM_MEMALLOC_MALLOC_ZERO_RETURNS_NULL
127 // first check if size wanted is 0
129 CYG_REPORT_RETVAL( NULL );
134 // ask the pool for the data
135 data_ptr = POOL.try_alloc( size );
137 // if it isn't NULL is the pointer valid?
138 if ( NULL != data_ptr ) {
139 CYG_CHECK_DATA_PTR( data_ptr,
140 "allocator returned invalid pointer!" );
142 // And just check its alignment
143 CYG_ASSERT( !((CYG_ADDRWORD)data_ptr & (sizeof(CYG_ADDRWORD) - 1)),
144 "Allocator has returned badly aligned data!");
147 CYG_REPORT_RETVAL( data_ptr );
158 CYG_REPORT_FUNCNAME( "free");
160 CYG_REPORT_FUNCARG1XV( ptr );
162 // if null pointer, do nothing as per spec
166 CYG_CHECK_DATA_PTR( ptr, "Pointer to free isn't even valid!" );
168 // get pool to free it
169 freeret = POOL.free( (cyg_uint8 *) ptr );
171 CYG_ASSERT( freeret , "Couldn't free!" );
179 calloc( size_t nmemb, size_t size )
182 cyg_ucount32 realsize;
184 CYG_REPORT_FUNCNAMETYPE( "calloc", "returning pointer %08x" );
186 CYG_REPORT_FUNCARG2DV( nmemb, size );
188 realsize = nmemb * size;
190 data_ptr = malloc( realsize );
192 // Fill with 0's if non-NULL
193 if ( data_ptr != NULL )
194 memset( data_ptr, 0, realsize );
196 CYG_REPORT_RETVAL( data_ptr );
202 realloc( void *ptr, size_t size )
206 CYG_REPORT_FUNCNAMETYPE( "realloc", "returning pointer %08x" );
208 CYG_REPORT_FUNCARG2( "ptr=%08x, size=%d", ptr, size );
210 // if pointer is NULL, we must malloc it
212 ptr = malloc( size );
213 CYG_REPORT_RETVAL( ptr );
217 CYG_CHECK_DATA_PTR( ptr, "realloc() passed a bogus pointer!" );
219 // if size is 0, we must free it
222 CYG_REPORT_RETVAL( NULL );
228 // otherwise try to resize allocation
229 newptr = POOL.resize_alloc( (cyg_uint8 *)ptr, size, &oldsize );
231 if ( NULL == newptr ) {
232 // if resize_alloc doesn't return a pointer, it failed, so we
233 // just have to allocate new space instead, and later copy it
235 CYG_ASSERT( oldsize != 0,
236 "resize_alloc() couldn't determine allocation size!" );
238 newptr = malloc( size );
240 if ( NULL != newptr ) {
241 memcpy( newptr, ptr, size < (size_t) oldsize ? size
242 : (size_t) oldsize );
247 CYG_REPORT_RETVAL( newptr );
252 externC struct mallinfo
255 struct mallinfo ret = { 0 }; // initialize to all zeros
256 Cyg_Mempool_Status stat;
258 CYG_REPORT_FUNCTION();
260 POOL.get_status( CYG_MEMPOOL_STAT_ARENASIZE|
261 CYG_MEMPOOL_STAT_FREEBLOCKS|
262 CYG_MEMPOOL_STAT_TOTALALLOCATED|
263 CYG_MEMPOOL_STAT_TOTALFREE|
264 CYG_MEMPOOL_STAT_MAXFREE, stat );
266 if ( stat.arenasize > 0 )
267 ret.arena = stat.arenasize;
269 if ( stat.freeblocks > 0 )
270 ret.ordblks = stat.freeblocks;
272 if ( stat.totalallocated > 0 )
273 ret.uordblks = stat.totalallocated;
275 if ( stat.totalfree > 0 )
276 ret.fordblks = stat.totalfree;
278 if ( stat.maxfree > 0 )
279 ret.maxfree = stat.maxfree;
285 #endif // ifdef CYGPKG_MEMALLOC_MALLOC_ALLOCATORS