1 //==========================================================================
5 // Implementation of kernel C API functions for memory pools
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): nickg, dsm, jlarmour
46 // Description: Implementation of kernel C API functions for memory pools
50 //####DESCRIPTIONEND####
52 //==========================================================================
56 #include <pkgconf/memalloc.h>
57 #include <pkgconf/system.h>
59 # include <pkgconf/kernel.h>
62 #ifdef CYGFUN_MEMALLOC_KAPI
66 #include <cyg/infra/cyg_type.h> // types
67 #include <cyg/infra/cyg_ass.h> // assertion macros
68 #include <cyg/infra/cyg_trac.h> // tracing macros
69 #include <cyg/kernel/ktypes.h> // base kernel types
71 #include <cyg/memalloc/memvar.hxx>
72 #include <cyg/memalloc/memfixed.hxx>
73 #include <cyg/memalloc/common.hxx> // status flags
75 #include <cyg/kernel/kapi.h> // C API
79 #ifdef CYGDBG_USE_ASSERTS
81 #define CYG_ASSERT_SIZES(cstruct, cxxstruct) \
83 char *msg = "Size of C struct " #cstruct \
84 " != size of C++ struct " #cxxstruct ; \
85 CYG_ASSERT( sizeof(cstruct) == sizeof(cxxstruct) , msg ); \
90 #define CYG_ASSERT_SIZES(cstruct, cxxstruct)
96 // -------------------------------------------------------------------------
99 inline void *operator new(size_t size, void *ptr)
101 CYG_CHECK_DATA_PTR( ptr, "Bad pointer" );
105 /*-----------------------------------------------------------------------*/
108 /* Create a variable size memory pool */
109 externC void cyg_mempool_var_create(
110 void *base, /* base of memory to use for pool */
111 cyg_int32 size, /* size of memory in bytes */
112 cyg_handle_t *handle, /* returned handle of memory pool */
113 cyg_mempool_var *var /* space to put pool structure in */
116 CYG_ASSERT_SIZES( cyg_mempool_var, Cyg_Mempool_Variable );
118 Cyg_Mempool_Variable *t = new((void *)var) Cyg_Mempool_Variable (
124 CYG_CHECK_DATA_PTR( handle, "Bad handle pointer" );
125 *handle = (cyg_handle_t)var;
128 /* Delete variable size memory pool */
129 externC void cyg_mempool_var_delete(cyg_handle_t varpool) __THROW
131 ((Cyg_Mempool_Variable *)varpool)->~Cyg_Mempool_Variable();
134 /* Allocates a block of length size. This waits if the memory is not
135 currently available. */
136 #ifdef CYGSEM_MEMALLOC_ALLOCATOR_VARIABLE_THREADAWARE
137 externC void *cyg_mempool_var_alloc(cyg_handle_t varpool, cyg_int32 size) __THROW
139 return ((Cyg_Mempool_Variable *)varpool)->alloc(size);
142 # ifdef CYGFUN_KERNEL_THREADS_TIMER
144 /* Allocates a block of length size. This waits for up to delay
145 ticks, if the memory is not already available. NULL is returned if
146 no memory is available. */
147 externC void *cyg_mempool_var_timed_alloc(
148 cyg_handle_t varpool,
150 cyg_tick_count_t abstime) __THROW
152 return ((Cyg_Mempool_Variable *)varpool)->alloc(size, abstime);
158 /* Allocates a block of length size. NULL is returned if no memory is
160 externC void *cyg_mempool_var_try_alloc(
161 cyg_handle_t varpool,
162 cyg_int32 size) __THROW
164 return ((Cyg_Mempool_Variable *)varpool)->try_alloc(size);
167 /* Frees memory back into variable size pool. */
168 externC void cyg_mempool_var_free(cyg_handle_t varpool, void *p) __THROW
171 b = ((Cyg_Mempool_Variable *)varpool)->free((cyg_uint8 *)p, 0);
172 CYG_ASSERT( b, "Bad free");
176 /* Returns true if there are any threads waiting for memory in the
177 given memory pool. */
178 externC cyg_bool_t cyg_mempool_var_waiting(cyg_handle_t varpool) __THROW
180 Cyg_Mempool_Variable *v = (Cyg_Mempool_Variable *)varpool;
181 Cyg_Mempool_Status stat;
183 v->get_status( CYG_MEMPOOL_STAT_WAITING, stat );
184 return (stat.waiting != 0);
187 /* Puts information about a variable memory pool into the structure
189 externC void cyg_mempool_var_get_info(
190 cyg_handle_t varpool,
191 cyg_mempool_info *info) __THROW
193 Cyg_Mempool_Variable *v = (Cyg_Mempool_Variable *)varpool;
194 Cyg_Mempool_Status stat;
196 v->get_status( CYG_MEMPOOL_STAT_ARENASIZE|
197 CYG_MEMPOOL_STAT_TOTALFREE|
198 CYG_MEMPOOL_STAT_ARENABASE|
199 CYG_MEMPOOL_STAT_ORIGSIZE|
200 CYG_MEMPOOL_STAT_MAXFREE, stat );
202 info->totalmem = stat.arenasize;
203 info->freemem = stat.totalfree;
204 info->size = stat.origsize;
205 info->base = const_cast<cyg_uint8 *>(stat.arenabase);
206 info->blocksize = -1;
207 info->maxfree = stat.maxfree;
211 /* Create a fixed size memory pool */
212 externC void cyg_mempool_fix_create(
213 void *base, // base of memory to use for pool
214 cyg_int32 size, // size of memory in byte
215 cyg_int32 blocksize, // size of allocation in bytes
216 cyg_handle_t *handle, // handle of memory pool
217 cyg_mempool_fix *fix // space to put pool structure in
220 CYG_ASSERT_SIZES( cyg_mempool_fix, Cyg_Mempool_Fixed );
222 Cyg_Mempool_Fixed *t = new((void *)fix) Cyg_Mempool_Fixed (
229 CYG_CHECK_DATA_PTR( handle, "Bad handle pointer" );
230 *handle = (cyg_handle_t)fix;
233 /* Delete fixed size memory pool */
234 externC void cyg_mempool_fix_delete(cyg_handle_t fixpool) __THROW
236 ((Cyg_Mempool_Fixed *)fixpool)->~Cyg_Mempool_Fixed();
239 #ifdef CYGSEM_MEMALLOC_ALLOCATOR_FIXED_THREADAWARE
240 /* Allocates a block. This waits if the memory is not
241 currently available. */
242 externC void *cyg_mempool_fix_alloc(cyg_handle_t fixpool) __THROW
244 return ((Cyg_Mempool_Fixed *)fixpool)->alloc();
247 # ifdef CYGFUN_KERNEL_THREADS_TIMER
249 /* Allocates a block. This waits for up to delay ticks, if the memory
250 is not already available. NULL is returned if no memory is
252 externC void *cyg_mempool_fix_timed_alloc(
253 cyg_handle_t fixpool,
254 cyg_tick_count_t abstime) __THROW
256 return ((Cyg_Mempool_Fixed *)fixpool)->alloc(abstime);
262 /* Allocates a block. NULL is returned if no memory is available. */
263 externC void *cyg_mempool_fix_try_alloc(cyg_handle_t fixpool) __THROW
265 return ((Cyg_Mempool_Fixed *)fixpool)->try_alloc();
268 /* Frees memory back into fixed size pool. */
269 externC void cyg_mempool_fix_free(cyg_handle_t fixpool, void *p) __THROW
272 b = ((Cyg_Mempool_Fixed *)fixpool)->free((cyg_uint8 *)p);
273 CYG_ASSERT( b, "Bad free");
276 /* Returns true if there are any threads waiting for memory in the
277 given memory pool. */
278 externC cyg_bool_t cyg_mempool_fix_waiting(cyg_handle_t fixpool) __THROW
280 Cyg_Mempool_Fixed *f = (Cyg_Mempool_Fixed *)fixpool;
281 Cyg_Mempool_Status stat;
283 f->get_status( CYG_MEMPOOL_STAT_WAITING, stat );
284 return (stat.waiting != 0);
287 /* Puts information about a fixed block memory pool into the structure
289 externC void cyg_mempool_fix_get_info(
290 cyg_handle_t fixpool,
291 cyg_mempool_info *info) __THROW
293 Cyg_Mempool_Fixed *f = (Cyg_Mempool_Fixed *)fixpool;
294 Cyg_Mempool_Status stat;
296 f->get_status( CYG_MEMPOOL_STAT_ARENASIZE|
297 CYG_MEMPOOL_STAT_TOTALFREE|
298 CYG_MEMPOOL_STAT_ARENABASE|
299 CYG_MEMPOOL_STAT_ORIGSIZE|
300 CYG_MEMPOOL_STAT_BLOCKSIZE|
301 CYG_MEMPOOL_STAT_MAXFREE, stat );
303 info->totalmem = stat.arenasize;
304 info->freemem = stat.totalfree;
305 info->size = stat.origsize;
306 info->base = const_cast<cyg_uint8 *>(stat.arenabase);
307 info->blocksize = stat.blocksize;
308 info->maxfree = stat.maxfree;
311 // -------------------------------------------------------------------------
312 // Check structure sizes.
313 // This class and constructor get run automatically in debug versions
314 // of the kernel and check that the structures configured in the C
315 // code are the same size as the C++ classes they should match.
317 #ifdef CYGPKG_INFRA_DEBUG
319 class Cyg_Check_Mem_Structure_Sizes
323 Cyg_Check_Mem_Structure_Sizes( int x ) __THROW;
327 #define CYG_CHECK_SIZES(cstruct, cxxstruct) \
328 if( sizeof(cstruct) != sizeof(cxxstruct) ) \
330 char *fmt = "Size of C struct " #cstruct \
331 " != size of C++ struct " #cxxstruct ; \
332 CYG_TRACE2(1, fmt, sizeof(cstruct) , sizeof(cxxstruct) ); \
337 Cyg_Check_Mem_Structure_Sizes::Cyg_Check_Mem_Structure_Sizes(int x) __THROW
339 cyg_bool fail = false;
343 CYG_CHECK_SIZES( cyg_mempool_var, Cyg_Mempool_Variable );
344 CYG_CHECK_SIZES( cyg_mempool_fix, Cyg_Mempool_Fixed );
346 CYG_ASSERT( !fail, "Size checks failed");
349 static Cyg_Check_Mem_Structure_Sizes cyg_memalloc_check_structure_sizes(1);
353 // -------------------------------------------------------------------------
356 #endif // ifdef CYGFUN_MEMALLOC_KAPI