summaryrefslogtreecommitdiff
path: root/ecos/packages/services/memalloc/common/current/include
diff options
context:
space:
mode:
authorschodet2007-02-23 12:33:47 +0000
committerschodet2007-02-23 12:33:47 +0000
commit22e4b1be3fe83053543994c325cb0d44e4587723 (patch)
tree6a4ef5b3c8ed45de299c185e5dd3391c934c6e1b /ecos/packages/services/memalloc/common/current/include
parent16697c575dfa90feb62c8db019d62682dfe026ca (diff)
Added ecos and build system.
git-svn-id: svn+ssh://pessac/svn/cesar/trunk@4 017c9cb6-072f-447c-8318-d5b54f68fe89
Diffstat (limited to 'ecos/packages/services/memalloc/common/current/include')
-rw-r--r--ecos/packages/services/memalloc/common/current/include/common.hxx152
-rw-r--r--ecos/packages/services/memalloc/common/current/include/dlmalloc.hxx172
-rw-r--r--ecos/packages/services/memalloc/common/current/include/dlmallocimpl.hxx184
-rw-r--r--ecos/packages/services/memalloc/common/current/include/kapi.h204
-rw-r--r--ecos/packages/services/memalloc/common/current/include/kapidata.h100
-rw-r--r--ecos/packages/services/memalloc/common/current/include/memfixed.hxx146
-rw-r--r--ecos/packages/services/memalloc/common/current/include/memjoin.hxx131
-rw-r--r--ecos/packages/services/memalloc/common/current/include/memjoin.inl347
-rw-r--r--ecos/packages/services/memalloc/common/current/include/mempolt2.hxx139
-rw-r--r--ecos/packages/services/memalloc/common/current/include/mempolt2.inl411
-rw-r--r--ecos/packages/services/memalloc/common/current/include/mempoolt.hxx123
-rw-r--r--ecos/packages/services/memalloc/common/current/include/mempoolt.inl401
-rw-r--r--ecos/packages/services/memalloc/common/current/include/memvar.hxx164
-rw-r--r--ecos/packages/services/memalloc/common/current/include/mfiximpl.hxx127
-rw-r--r--ecos/packages/services/memalloc/common/current/include/mfiximpl.inl243
-rw-r--r--ecos/packages/services/memalloc/common/current/include/mvarimpl.hxx154
-rw-r--r--ecos/packages/services/memalloc/common/current/include/mvarimpl.inl454
-rw-r--r--ecos/packages/services/memalloc/common/current/include/sepmeta.hxx174
-rw-r--r--ecos/packages/services/memalloc/common/current/include/sepmetaimpl.hxx194
-rw-r--r--ecos/packages/services/memalloc/common/current/include/sepmetaimpl.inl678
20 files changed, 4698 insertions, 0 deletions
diff --git a/ecos/packages/services/memalloc/common/current/include/common.hxx b/ecos/packages/services/memalloc/common/current/include/common.hxx
new file mode 100644
index 0000000000..6928d644b7
--- /dev/null
+++ b/ecos/packages/services/memalloc/common/current/include/common.hxx
@@ -0,0 +1,152 @@
+#ifndef CYGONCE_MEMALLOC_COMMON_HXX
+#define CYGONCE_MEMALLOC_COMMON_HXX
+
+/*==========================================================================
+//
+// common.hxx
+//
+// Shared definitions used by memory allocators
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not invalidate any other reasons why a work based on
+// this file might be covered by the GNU General Public License.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): jlarmour
+// Contributors:
+// Date: 2000-06-12
+// Purpose: Shared definitions used by memory allocators
+// Description:
+// Usage: #include <cyg/memalloc/common.hxx>
+//
+//
+//####DESCRIPTIONEND####
+//
+//========================================================================*/
+
+/* CONFIGURATION */
+
+#include <pkgconf/memalloc.h>
+
+/* TYPE DEFINITIONS */
+
+// struct Cyg_Mempool_Status is returned by the get_status() method of
+// standard eCos memory allocators. After return from get_status(), any
+// field of type T may be set to ((T)-1) to indicate that the information
+// is not available or not applicable to this allocator.
+
+
+class Cyg_Mempool_Status {
+public:
+ const cyg_uint8 *arenabase; // base address of entire pool
+ cyg_int32 arenasize; // total size of entire pool
+ cyg_int32 freeblocks; // number of chunks free for use
+ cyg_int32 totalallocated; // total allocated space in bytes
+ cyg_int32 totalfree; // total space in bytes not in use
+ cyg_int32 blocksize; // block size if fixed block
+ cyg_int32 maxfree; // size of largest unused block
+ cyg_int8 waiting; // are there any threads waiting for memory?
+ const cyg_uint8 *origbase; // address of original region used when pool
+ // created
+ cyg_int32 origsize; // size of original region used when pool
+ // created
+
+ // maxoverhead is the *maximum* per-allocation overhead imposed by
+ // the allocator implementation. Note: this is rarely the typical
+ // overhead which often depends on the size of the allocation requested.
+ // It includes overhead due to alignment constraints. For example, if
+ // maxfree and maxoverhead are available for this allocator, then an
+ // allocation request of (maxfree-maxoverhead) bytes must always succeed
+ // Unless maxoverhead is set to -1 of course, in which case the allocator
+ // does not support reporting this information.
+
+ cyg_int8 maxoverhead;
+
+ void
+ init() {
+ arenabase = (const cyg_uint8 *)-1;
+ arenasize = -1;
+ freeblocks = -1;
+ totalallocated = -1;
+ totalfree = -1;
+ blocksize = -1;
+ maxfree = -1;
+ waiting = -1;
+ origbase = (const cyg_uint8 *)-1;
+ origsize = -1;
+ maxoverhead = -1;
+ }
+
+ // constructor
+ Cyg_Mempool_Status() { init(); }
+};
+
+// Flags to pass to get_status() methods to tell it which stat(s) is/are
+// being requested
+
+#define CYG_MEMPOOL_STAT_ARENABASE (1<<0)
+#define CYG_MEMPOOL_STAT_ARENASIZE (1<<1)
+#define CYG_MEMPOOL_STAT_FREEBLOCKS (1<<2)
+#define CYG_MEMPOOL_STAT_TOTALALLOCATED (1<<3)
+#define CYG_MEMPOOL_STAT_TOTALFREE (1<<4)
+#define CYG_MEMPOOL_STAT_BLOCKSIZE (1<<5)
+#define CYG_MEMPOOL_STAT_MAXFREE (1<<6)
+#define CYG_MEMPOOL_STAT_WAITING (1<<7)
+#define CYG_MEMPOOL_STAT_ORIGBASE (1<<9)
+#define CYG_MEMPOOL_STAT_ORIGSIZE (1<<10)
+#define CYG_MEMPOOL_STAT_MAXOVERHEAD (1<<11)
+
+// And an opaque type for any arguments with these flags
+typedef cyg_uint16 cyg_mempool_status_flag_t;
+
+// breakpoint site for out of memory conditions
+#ifdef CYGSEM_MEMALLOC_INVOKE_OUT_OF_MEMORY
+#include <cyg/memalloc/kapi.h> // protoype for cyg_memalloc_alloc_fail
+#define CYG_MEMALLOC_FAIL_TEST( test, size ) \
+ CYG_MACRO_START \
+ if ( test) { \
+ cyg_memalloc_alloc_fail(__FILE__, __LINE__, size ); \
+ } \
+ CYG_MACRO_END
+#define CYG_MEMALLOC_FAIL( size) \
+ CYG_MACRO_START \
+ cyg_memalloc_alloc_fail(__FILE__, __LINE__, size ); \
+ CYG_MACRO_END
+#else
+#define CYG_MEMALLOC_FAIL_TEST( test, size ) CYG_EMPTY_STATEMENT
+#define CYG_MEMALLOC_FAIL( size ) CYG_EMPTY_STATEMENT
+#endif
+
+#endif /* ifndef CYGONCE_MEMALLOC_COMMON_HXX */
+/* EOF common.hxx */
diff --git a/ecos/packages/services/memalloc/common/current/include/dlmalloc.hxx b/ecos/packages/services/memalloc/common/current/include/dlmalloc.hxx
new file mode 100644
index 0000000000..1ad955a26b
--- /dev/null
+++ b/ecos/packages/services/memalloc/common/current/include/dlmalloc.hxx
@@ -0,0 +1,172 @@
+#ifndef CYGONCE_MEMALLOC_DLMALLOC_HXX
+#define CYGONCE_MEMALLOC_DLMALLOC_HXX
+
+//==========================================================================
+//
+// dlmalloc.hxx
+//
+// Interface to the port of Doug Lea's malloc implementation
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not invalidate any other reasons why a work based on
+// this file might be covered by the GNU General Public License.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): jlarmour
+// Contributors:
+// Date: 2000-06-18
+// Purpose: Define standard interface to Doug Lea's malloc implementation
+// Description: Doug Lea's malloc has been ported to eCos. This file provides
+// the interface between the implementation and the standard
+// memory allocator interface required by eCos
+// Usage: #include <cyg/memalloc/dlmalloc.hxx>
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+// CONFIGURATION
+
+#include <pkgconf/memalloc.h>
+
+#ifdef CYGIMP_MEMALLOC_ALLOCATOR_DLMALLOC_THREADAWARE
+# include <pkgconf/system.h>
+# ifdef CYGPKG_KERNEL
+# include <pkgconf/kernel.h>
+# endif
+#endif
+
+// when used as an implementation for malloc, we need the following
+// to let the system know the name of the class
+#define CYGCLS_MEMALLOC_MALLOC_IMPL Cyg_Mempool_dlmalloc
+
+// if the implementation is all that's required, don't output anything else
+#ifndef __MALLOC_IMPL_WANTED
+
+// INCLUDES
+
+#include <stddef.h> // size_t, ptrdiff_t
+#include <cyg/infra/cyg_type.h> // types
+#ifdef CYGIMP_MEMALLOC_ALLOCATOR_DLMALLOC_THREADAWARE
+# include <cyg/memalloc/mempolt2.hxx> // kernel safe mempool template
+#endif
+#include <cyg/memalloc/dlmallocimpl.hxx> // dlmalloc implementation
+#include <cyg/memalloc/common.hxx> // Common memory allocator infra
+#ifdef CYGFUN_KERNEL_THREADS_TIMER
+# include <cyg/kernel/ktypes.h> // cyg_tick_count
+#endif
+
+
+// TYPE DEFINITIONS
+
+
+class Cyg_Mempool_dlmalloc
+{
+protected:
+#ifdef CYGIMP_MEMALLOC_ALLOCATOR_DLMALLOC_THREADAWARE
+ Cyg_Mempolt2<Cyg_Mempool_dlmalloc_Implementation> mypool;
+#else
+ Cyg_Mempool_dlmalloc_Implementation mypool;
+#endif
+
+
+public:
+ // Constructor: gives the base and size of the arena in which memory is
+ // to be carved out, note that management structures are taken from the
+ // same arena.
+ Cyg_Mempool_dlmalloc( cyg_uint8 *base, cyg_int32 size,
+ CYG_ADDRWORD argthru=0 )
+ : mypool( base, size, argthru ) {}
+
+ // Destructor
+ ~Cyg_Mempool_dlmalloc() {}
+
+ // get some memory; wait if none available
+ // if we aren't configured to be thread-aware this is irrelevant
+#ifdef CYGIMP_MEMALLOC_ALLOCATOR_DLMALLOC_THREADAWARE
+ cyg_uint8 *
+ alloc( cyg_int32 size ) { return mypool.alloc( size ); }
+
+# ifdef CYGFUN_KERNEL_THREADS_TIMER
+ // get some memory with a timeout
+ cyg_uint8 *
+ alloc( cyg_int32 size, cyg_tick_count delay_timeout ) {
+ return mypool.alloc( size, delay_timeout );
+ }
+# endif
+#endif
+
+ // get some memory, return NULL if none available
+ cyg_uint8 *
+ try_alloc( cyg_int32 size ) { return mypool.try_alloc( size ); }
+
+
+ // resize existing allocation, if oldsize is non-NULL, previous
+ // allocation size is placed into it. If previous size not available,
+ // it is set to 0. NB previous allocation size may have been rounded up.
+ // Occasionally the allocation can be adjusted *backwards* as well as,
+ // or instead of forwards, therefore the address of the resized
+ // allocation is returned, or NULL if no resizing was possible.
+ // Note that this differs from ::realloc() in that no attempt is
+ // made to call malloc() if resizing is not possible - that is left
+ // to higher layers. The data is copied from old to new though.
+ // The effects of alloc_ptr==NULL or newsize==0 are undefined
+ cyg_uint8 *
+ resize_alloc( cyg_uint8 *alloc_ptr, cyg_int32 newsize,
+ cyg_int32 *oldsize ) {
+ return mypool.resize_alloc( alloc_ptr, newsize, oldsize);
+ }
+
+ // free the memory back to the pool
+ // returns true on success
+ cyg_bool
+ free( cyg_uint8 *ptr, cyg_int32 size=0 ) { return mypool.free(ptr, size); }
+
+ // Get memory pool status
+ // flags is a bitmask of requested fields to fill in. The flags are
+ // defined in common.hxx
+ void
+ get_status( cyg_mempool_status_flag_t flags, Cyg_Mempool_Status &status ) {
+ // set to 0 - if there's anything really waiting, it will be set to
+ // 1 later
+ status.waiting = 0;
+ mypool.get_status( flags, status );
+ }
+};
+
+#endif // ifndef __MALLOC_IMPL_WANTED
+
+#endif // ifndef CYGONCE_MEMALLOC_DLMALLOC_HXX
+// EOF dlmalloc.hxx
diff --git a/ecos/packages/services/memalloc/common/current/include/dlmallocimpl.hxx b/ecos/packages/services/memalloc/common/current/include/dlmallocimpl.hxx
new file mode 100644
index 0000000000..bbb267b42d
--- /dev/null
+++ b/ecos/packages/services/memalloc/common/current/include/dlmallocimpl.hxx
@@ -0,0 +1,184 @@
+#ifndef CYGONCE_MEMALLOC_DLMALLOCIMPL_HXX
+#define CYGONCE_MEMALLOC_DLMALLOCIMPL_HXX
+
+//==========================================================================
+//
+// dlmallocimpl.hxx
+//
+// Interface to the port of Doug Lea's malloc implementation
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not invalidate any other reasons why a work based on
+// this file might be covered by the GNU General Public License.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): jlarmour
+// Contributors:
+// Date: 2000-06-18
+// Purpose: Define standard interface to Doug Lea's malloc implementation
+// Description: Doug Lea's malloc has been ported to eCos. This file provides
+// the interface between the implementation and the standard
+// memory allocator interface required by eCos
+// Usage: #include <cyg/memalloc/dlmalloc.hxx>
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+// CONFIGURATION
+
+#include <pkgconf/memalloc.h>
+
+// INCLUDES
+
+#include <stddef.h> // size_t, ptrdiff_t
+#include <cyg/infra/cyg_type.h> // types
+
+#include <cyg/memalloc/common.hxx> // Common memory allocator infra
+
+// As a special case, override CYGIMP_MEMALLOC_ALLOCATOR_DLMALLOC_SAFE_MULTIPLE
+// if the malloc config says so
+#ifdef CYGIMP_MEMALLOC_MALLOC_DLMALLOC
+// forward declaration to prevent header dependency problems
+class Cyg_Mempool_dlmalloc;
+# include <pkgconf/heaps.hxx>
+# if (CYGMEM_HEAP_COUNT > 1) && \
+ !defined(CYGIMP_MEMALLOC_ALLOCATOR_DLMALLOC_SAFE_MULTIPLE)
+# define CYGIMP_MEMALLOC_ALLOCATOR_DLMALLOC_SAFE_MULTIPLE 1
+# endif
+#endif
+
+// CONSTANTS
+
+// number of bins - but changing this alone will not change the number of
+// bins!
+#define CYGPRI_MEMALLOC_ALLOCATOR_DLMALLOC_NAV 128
+
+// TYPE DEFINITIONS
+
+
+class Cyg_Mempool_dlmalloc_Implementation
+{
+public:
+ /* cyg_dlmalloc_size_t is the word-size used for internal bookkeeping
+ of chunk sizes. On a 64-bit machine, you can reduce malloc
+ overhead, especially for very small chunks, by defining
+ cyg_dlmalloc_size_t to be a 32-bit type at the expense of not
+ being able to handle requests greater than 2^31. This limitation is
+ hardly ever a concern; you are encouraged to set this. However, the
+ default version is the same as size_t. */
+
+ typedef size_t Cyg_dlmalloc_size_t;
+
+ typedef struct malloc_chunk
+ {
+ Cyg_dlmalloc_size_t prev_size; /* Size of previous chunk (if free). */
+ Cyg_dlmalloc_size_t size; /* Size in bytes, including overhead. */
+ struct malloc_chunk* fd; /* double links -- used only if free. */
+ struct malloc_chunk* bk;
+ };
+
+protected:
+ /* The first value returned from sbrk */
+ cyg_uint8 *arenabase;
+
+ /* The total memory in the pool */
+ cyg_int32 arenasize;
+
+#ifdef CYGIMP_MEMALLOC_ALLOCATOR_DLMALLOC_SAFE_MULTIPLE
+ struct Cyg_Mempool_dlmalloc_Implementation::malloc_chunk *
+ av_[ CYGPRI_MEMALLOC_ALLOCATOR_DLMALLOC_NAV * 2 + 2 ];
+#endif
+
+#ifdef CYGDBG_MEMALLOC_ALLOCATOR_DLMALLOC_DEBUG
+
+ void
+ do_check_chunk( struct malloc_chunk * );
+
+ void
+ do_check_free_chunk( struct malloc_chunk * );
+
+ void
+ do_check_inuse_chunk( struct malloc_chunk * );
+
+ void
+ do_check_malloced_chunk( struct malloc_chunk *, Cyg_dlmalloc_size_t );
+#endif
+
+public:
+ // Constructor: gives the base and size of the arena in which memory is
+ // to be carved out, note that management structures are taken from the
+ // same arena.
+ Cyg_Mempool_dlmalloc_Implementation( cyg_uint8 * /* base */,
+ cyg_int32 /* size */,
+ CYG_ADDRWORD /* argthru */ );
+
+ // Destructor
+ ~Cyg_Mempool_dlmalloc_Implementation() {}
+
+ // get some memory, return NULL if none available
+ cyg_uint8 *
+ try_alloc( cyg_int32 /* size */ );
+
+ // resize existing allocation, if oldsize is non-NULL, previous
+ // allocation size is placed into it. If previous size not available,
+ // it is set to 0. NB previous allocation size may have been rounded up.
+ // Occasionally the allocation can be adjusted *backwards* as well as,
+ // or instead of forwards, therefore the address of the resized
+ // allocation is returned, or NULL if no resizing was possible.
+ // Note that this differs from ::realloc() in that no attempt is
+ // made to call malloc() if resizing is not possible - that is left
+ // to higher layers. The data is copied from old to new though.
+ // The effects of alloc_ptr==NULL or newsize==0 are undefined
+ cyg_uint8 *
+ resize_alloc( cyg_uint8 * /* alloc_ptr */, cyg_int32 /* newsize */,
+ cyg_int32 * /* oldsize */ );
+
+ // free the memory back to the pool
+ // returns true on success
+ cyg_bool
+ free( cyg_uint8 * /* ptr */, cyg_int32 /* size */ =0 );
+
+ // Get memory pool status
+ // flags is a bitmask of requested fields to fill in. The flags are
+ // defined in common.hxx
+ void
+ get_status( cyg_mempool_status_flag_t /* flags */,
+ Cyg_Mempool_Status & /* status */ );
+
+};
+
+#endif // ifndef CYGONCE_MEMALLOC_DLMALLOCIMPL_HXX
+// EOF dlmallocimpl.hxx
diff --git a/ecos/packages/services/memalloc/common/current/include/kapi.h b/ecos/packages/services/memalloc/common/current/include/kapi.h
new file mode 100644
index 0000000000..6df51290c6
--- /dev/null
+++ b/ecos/packages/services/memalloc/common/current/include/kapi.h
@@ -0,0 +1,204 @@
+#ifndef CYGONCE_MEMALLOC_KAPI_H
+#define CYGONCE_MEMALLOC_KAPI_H
+
+/*==========================================================================
+//
+// kapi.h
+//
+// Memory allocator portion of kernel C API
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not invalidate any other reasons why a work based on
+// this file might be covered by the GNU General Public License.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): jlarmour
+// Contributors:
+// Date: 2000-06-12
+// Purpose: Memory allocator portion of kernel C API
+// Description: This is intentionally only to be included from
+// <cyg/kernel/kapi.h>
+// Usage: This file should not be used directly - instead it should
+// be used via <cyg/kernel/kapi.h>
+//
+//
+//####DESCRIPTIONEND####
+//
+//========================================================================*/
+
+/* CONFIGURATION */
+#include <pkgconf/system.h>
+#include <pkgconf/memalloc.h>
+
+/* TYPE DEFINITIONS */
+#ifdef CYGPKG_KERNEL
+#include <cyg/kernel/kapi.h>
+#else
+typedef cyg_uint32 cyg_handle_t;
+#endif
+
+/*---------------------------------------------------------------------------*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*---------------------------------------------------------------------------*/
+struct cyg_mempool_var;
+typedef struct cyg_mempool_var cyg_mempool_var;
+
+struct cyg_mempool_fix;
+typedef struct cyg_mempool_fix cyg_mempool_fix;
+
+/*-----------------------------------------------------------------------*/
+/* Memory pools */
+
+/* There are two sorts of memory pools. A variable size memory pool
+ is for allocating blocks of any size. A fixed size memory pool, has
+ the block size specified when the pool is created, and only provides
+ blocks of that size. */
+
+/* Create a variable size memory pool */
+void cyg_mempool_var_create(
+ void *base, /* base of memory to use for pool */
+ cyg_int32 size, /* size of memory in bytes */
+ cyg_handle_t *handle, /* returned handle of memory pool */
+ cyg_mempool_var *var /* space to put pool structure in */
+ ) __THROW;
+
+/* Delete variable size memory pool */
+void cyg_mempool_var_delete(cyg_handle_t varpool) __THROW;
+
+#ifdef CYGSEM_MEMALLOC_ALLOCATOR_VARIABLE_THREADAWARE
+
+/* Allocates a block of length size. This waits if the memory is not
+ currently available. */
+void *cyg_mempool_var_alloc(cyg_handle_t varpool, cyg_int32 size) __THROW;
+
+# ifdef CYGFUN_KERNEL_THREADS_TIMER
+
+/* Allocates a block of length size. This waits until abstime,
+ if the memory is not already available. NULL is returned if
+ no memory is available. */
+void *cyg_mempool_var_timed_alloc(
+ cyg_handle_t varpool,
+ cyg_int32 size,
+ cyg_tick_count_t abstime) __THROW;
+
+# endif
+#endif
+
+/* Allocates a block of length size. NULL is returned if no memory is
+ available. */
+void *cyg_mempool_var_try_alloc(
+ cyg_handle_t varpool,
+ cyg_int32 size) __THROW;
+
+/* Frees memory back into variable size pool. */
+void cyg_mempool_var_free(cyg_handle_t varpool, void *p) __THROW;
+
+/* Returns true if there are any threads waiting for memory in the
+ given memory pool. */
+cyg_bool_t cyg_mempool_var_waiting(cyg_handle_t varpool) __THROW;
+
+typedef struct {
+ cyg_int32 totalmem;
+ cyg_int32 freemem;
+ void *base;
+ cyg_int32 size;
+ cyg_int32 blocksize;
+ cyg_int32 maxfree; // The largest free block
+} cyg_mempool_info;
+
+/* Puts information about a variable memory pool into the structure
+ provided. */
+void cyg_mempool_var_get_info(cyg_handle_t varpool, cyg_mempool_info *info) __THROW;
+
+/* Create a fixed size memory pool */
+void cyg_mempool_fix_create(
+ void *base, // base of memory to use for pool
+ cyg_int32 size, // size of memory in byte
+ cyg_int32 blocksize, // size of allocation in bytes
+ cyg_handle_t *handle, // handle of memory pool
+ cyg_mempool_fix *fix // space to put pool structure in
+ ) __THROW;
+
+/* Delete fixed size memory pool */
+void cyg_mempool_fix_delete(cyg_handle_t fixpool) __THROW;
+
+#ifdef CYGSEM_MEMALLOC_ALLOCATOR_FIXED_THREADAWARE
+/* Allocates a block. This waits if the memory is not
+ currently available. */
+void *cyg_mempool_fix_alloc(cyg_handle_t fixpool) __THROW;
+
+# ifdef CYGFUN_KERNEL_THREADS_TIMER
+
+/* Allocates a block. This waits until abstime, if the memory
+ is not already available. NULL is returned if no memory is
+ available. */
+void *cyg_mempool_fix_timed_alloc(
+ cyg_handle_t fixpool,
+ cyg_tick_count_t abstime) __THROW;
+
+# endif
+#endif
+
+/* Allocates a block. NULL is returned if no memory is available. */
+void *cyg_mempool_fix_try_alloc(cyg_handle_t fixpool) __THROW;
+
+/* Frees memory back into fixed size pool. */
+void cyg_mempool_fix_free(cyg_handle_t fixpool, void *p) __THROW;
+
+/* Returns true if there are any threads waiting for memory in the
+ given memory pool. */
+cyg_bool_t cyg_mempool_fix_waiting(cyg_handle_t fixpool) __THROW;
+
+/* Puts information about a variable memory pool into the structure
+ provided. */
+void cyg_mempool_fix_get_info(cyg_handle_t fixpool, cyg_mempool_info *info) __THROW;
+
+/* user overrideable function invoked before running out of memory. */
+__externC void cyg_memalloc_alloc_fail(char * file, int line, cyg_int32 size)
+ __THROW;
+
+/*---------------------------------------------------------------------------*/
+#ifdef __cplusplus
+}
+#endif
+
+/*---------------------------------------------------------------------------*/
+
+
+#endif /* ifndef CYGONCE_MEMALLOC_KAPI_H */
+/* EOF kapi.h */
diff --git a/ecos/packages/services/memalloc/common/current/include/kapidata.h b/ecos/packages/services/memalloc/common/current/include/kapidata.h
new file mode 100644
index 0000000000..1558fab12b
--- /dev/null
+++ b/ecos/packages/services/memalloc/common/current/include/kapidata.h
@@ -0,0 +1,100 @@
+#ifndef CYGONCE_MEMALLOC_KAPIDATA_H
+#define CYGONCE_MEMALLOC_KAPIDATA_H
+
+/*==========================================================================
+//
+// kapidata.h
+//
+// Memory allocator portion of kernel C API
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not invalidate any other reasons why a work based on
+// this file might be covered by the GNU General Public License.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): jlarmour
+// Contributors:
+// Date: 2000-06-12
+// Purpose: Memory allocator data for kernel C API
+// Description: This is intentionally only to be included via
+// <cyg/kernel/kapi.h>
+// Usage: This file should not be used directly - instead it should
+// be used via <cyg/kernel/kapi.h>
+//
+//
+//####DESCRIPTIONEND####
+//
+//========================================================================*/
+
+#include <pkgconf/memalloc.h>
+
+/*---------------------------------------------------------------------------*/
+
+/* This corresponds to the extra fields provided by the mempoolt template
+ not the actual size of the template in any given instance. */
+typedef struct cyg_mempoolt {
+ cyg_threadqueue queue;
+} cyg_mempoolt;
+
+
+struct cyg_mempool_var_memdq {
+ struct cyg_mempool_var_memdq *prev, *next;
+ cyg_int32 size;
+};
+
+struct cyg_mempool_var {
+ struct cyg_mempool_var_memdq head;
+ cyg_uint8 *obase;
+ cyg_int32 osize;
+ cyg_uint8 *bottom;
+ cyg_uint8 *top;
+ cyg_int32 alignment;
+ cyg_int32 freemem;
+ cyg_mempoolt mempoolt;
+};
+
+struct cyg_mempool_fix {
+ cyg_uint32 *bitmap;
+ cyg_int32 maptop;
+ cyg_uint8 *mempool;
+ cyg_int32 numblocks;
+ cyg_int32 freeblocks;
+ cyg_int32 blocksize;
+ cyg_int32 firstfree;
+ cyg_uint8 *top;
+ cyg_mempoolt mempoolt;
+};
+
+#endif /* ifndef CYGONCE_MEMALLOC_KAPIDATA_H */
+/* EOF kapidata.h */
diff --git a/ecos/packages/services/memalloc/common/current/include/memfixed.hxx b/ecos/packages/services/memalloc/common/current/include/memfixed.hxx
new file mode 100644
index 0000000000..8062b5d805
--- /dev/null
+++ b/ecos/packages/services/memalloc/common/current/include/memfixed.hxx
@@ -0,0 +1,146 @@
+#ifndef CYGONCE_MEMALLOC_MEMFIXED_HXX
+#define CYGONCE_MEMALLOC_MEMFIXED_HXX
+
+//==========================================================================
+//
+// memfixed.hxx
+//
+// Memory pool with fixed block class declarations
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not invalidate any other reasons why a work based on
+// this file might be covered by the GNU General Public License.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): hmt
+// Contributors: jlarmour
+// Date: 2000-06-12
+// Purpose: Define Memfixed class interface
+// Description: Inline class for constructing a fixed block allocator
+// Usage: #include <cyg/memalloc/memfixed.hxx>
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+// CONFIGURATION
+
+#include <pkgconf/memalloc.h>
+#ifdef CYGSEM_MEMALLOC_ALLOCATOR_FIXED_THREADAWARE
+# include <pkgconf/system.h>
+# ifdef CYGPKG_KERNEL
+# include <pkgconf/kernel.h>
+# endif
+#endif
+
+
+// INCLUDES
+
+#include <cyg/infra/cyg_type.h> // types
+#include <cyg/infra/cyg_ass.h> // assertion macros
+
+#ifdef CYGFUN_KERNEL_THREADS_TIMER
+# include <cyg/kernel/ktypes.h> // cyg_tick_count
+#endif
+
+#ifdef CYGSEM_MEMALLOC_ALLOCATOR_FIXED_THREADAWARE
+# include <cyg/memalloc/mempolt2.hxx> // kernel safe mempool template
+#endif
+
+#include <cyg/memalloc/mfiximpl.hxx> // implementation of a fixed mem pool
+#include <cyg/memalloc/common.hxx> // Common memory allocator infra
+
+
+// TYPE DEFINITIONS
+
+class Cyg_Mempool_Fixed
+{
+protected:
+#ifdef CYGSEM_MEMALLOC_ALLOCATOR_FIXED_THREADAWARE
+ Cyg_Mempolt2<Cyg_Mempool_Fixed_Implementation> mypool;
+#else
+ Cyg_Mempool_Fixed_Implementation mypool;
+#endif
+
+public:
+ // this API makes concrete a class which implements a thread-safe
+ // kernel-savvy memory pool which manages fixed size blocks.
+
+ // Constructor: gives the base and size of the arena in which memory is
+ // to be carved out, note that management structures are taken from the
+ // same arena. Alloc_unit is the blocksize allocated.
+ Cyg_Mempool_Fixed(
+ cyg_uint8 * /* base */,
+ cyg_int32 /* size */,
+ CYG_ADDRWORD /* alloc_unit */ );
+
+ // Destructor
+ ~Cyg_Mempool_Fixed();
+
+#ifdef CYGSEM_MEMALLOC_ALLOCATOR_FIXED_THREADAWARE
+ // get some memory; wait if none available
+ cyg_uint8 *alloc();
+
+# ifdef CYGFUN_KERNEL_THREADS_TIMER
+ // get some memory with a timeout
+ cyg_uint8 *alloc( cyg_tick_count /* delay_timeout */ );
+# endif
+#endif
+
+ // get some memory, return NULL if none available
+ cyg_uint8 *try_alloc();
+
+ // supposedly resize existing allocation. This is defined in the
+ // fixed block allocator purely for API consistency. It will return
+ // an error (false) for all values, except for the blocksize
+ // returns true on success
+ cyg_uint8 *
+ resize_alloc( cyg_uint8 * /* alloc_ptr */, cyg_int32 /* newsize */,
+ cyg_int32 * /* oldsize */ =NULL );
+
+ // free the memory back to the pool
+ cyg_bool free( cyg_uint8 * /* p */ );
+
+ // Get memory pool status
+ // flags is a bitmask of requested fields to fill in. The flags are
+ // defined in common.hxx
+ void get_status( cyg_mempool_status_flag_t /* flags */,
+ Cyg_Mempool_Status & /* status */ );
+
+ CYGDBG_DEFINE_CHECK_THIS
+};
+
+#endif // ifndef CYGONCE_MEMALLOC_MEMFIXED_HXX
+// EOF memfixed.hxx
diff --git a/ecos/packages/services/memalloc/common/current/include/memjoin.hxx b/ecos/packages/services/memalloc/common/current/include/memjoin.hxx
new file mode 100644
index 0000000000..ee97752c7d
--- /dev/null
+++ b/ecos/packages/services/memalloc/common/current/include/memjoin.hxx
@@ -0,0 +1,131 @@
+#ifndef CYGONCE_MEMALLOC_MEMJOIN_HXX
+#define CYGONCE_MEMALLOC_MEMJOIN_HXX
+
+//==========================================================================
+//
+// memjoin.hxx
+//
+// Pseudo memory pool used to join together other memory pools
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not invalidate any other reasons why a work based on
+// this file might be covered by the GNU General Public License.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): jlarmour
+// Contributors:
+// Date: 2000-06-12
+// Purpose: Define joined up memory pool class interface
+// Description: Inline class for constructing a pseudo allocator that contains
+// multiple other allocators. It caters solely to the requirements
+// of the malloc implementation.
+// Usage: #include <cyg/memalloc/memjoin.hxx>
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+// CONFIGURATION
+
+#include <pkgconf/memalloc.h>
+
+// INCLUDES
+
+#include <cyg/infra/cyg_type.h> // types
+//#include <cyg/infra/cyg_ass.h> // assertion macros
+
+#include <cyg/memalloc/common.hxx> // Common memory allocator infra
+
+
+// TYPE DEFINITIONS
+
+template <class T>
+class Cyg_Mempool_Joined
+{
+protected:
+ struct pooldesc {
+ const cyg_uint8 *startaddr;
+ const cyg_uint8 *endaddr;
+ T *pool;
+ };
+ struct pooldesc *pools;
+ cyg_uint8 poolcount;
+
+ T *
+ find_pool_for_ptr( const cyg_uint8 * /* ptr */ );
+
+public:
+ // Constructor
+ Cyg_Mempool_Joined( cyg_uint8 /* num_heaps */, T * /* heaps */[] );
+
+ // Destructor
+ ~Cyg_Mempool_Joined();
+
+ // get some memory, return NULL if none available
+ cyg_uint8 *
+ try_alloc( cyg_int32 /* size */ );
+
+ // resize existing allocation, if oldsize is non-NULL, previous
+ // allocation size is placed into it. If previous size not available,
+ // it is set to 0. NB previous allocation size may have been rounded up.
+ // Occasionally the allocation can be adjusted *backwards* as well as,
+ // or instead of forwards, therefore the address of the resized
+ // allocation is returned, or NULL if no resizing was possible.
+ // Note that this differs from ::realloc() in that no attempt is
+ // made to call malloc() if resizing is not possible - that is left
+ // to higher layers. The data is copied from old to new though.
+ // The effects of alloc_ptr==NULL or newsize==0 are undefined
+ cyg_uint8 *
+ resize_alloc( cyg_uint8 * /* alloc_ptr */, cyg_int32 /* newsize */,
+ cyg_int32 * /* oldsize */ =NULL );
+
+ // free the memory back to the pool
+ // returns true on success
+ cyg_bool
+ free( cyg_uint8 * /* ptr */, cyg_int32 /* size */ =0 );
+
+ // Get memory pool status
+ // flags is a bitmask of requested fields to fill in. The flags are
+ // defined in common.hxx
+ void
+ get_status( cyg_mempool_status_flag_t /* flags */,
+ Cyg_Mempool_Status & /* status */ );
+
+};
+
+#include <cyg/memalloc/memjoin.inl>
+
+#endif // ifndef CYGONCE_MEMALLOC_MEMJOIN_HXX
+// EOF memjoin.hxx
diff --git a/ecos/packages/services/memalloc/common/current/include/memjoin.inl b/ecos/packages/services/memalloc/common/current/include/memjoin.inl
new file mode 100644
index 0000000000..454dc4cfac
--- /dev/null
+++ b/ecos/packages/services/memalloc/common/current/include/memjoin.inl
@@ -0,0 +1,347 @@
+#ifndef CYGONCE_MEMALLOC_MEMJOIN_INL
+#define CYGONCE_MEMALLOC_MEMJOIN_INL
+
+//==========================================================================
+//
+// memjoin.inl
+//
+// Pseudo memory pool used to join together other memory pools
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not invalidate any other reasons why a work based on
+// this file might be covered by the GNU General Public License.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): jlarmour
+// Contributors:
+// Date: 2000-06-12
+// Purpose: Implement joined up memory pool class interface
+// Description: Inline class for constructing a pseudo allocator that contains
+// multiple other allocators. It caters solely to the requirements
+// of the malloc implementation.
+// Usage: #include <cyg/memalloc/memjoin.hxx>
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+// CONFIGURATION
+
+#include <pkgconf/memalloc.h>
+
+// INCLUDES
+
+#include <cyg/infra/cyg_type.h> // types
+#include <cyg/infra/cyg_ass.h> // assertion macros
+#include <cyg/infra/cyg_trac.h> // tracing macros
+#include <cyg/memalloc/memjoin.hxx> // header for this file just in case
+
+
+// FUNCTIONS
+
+
+// -------------------------------------------------------------------------
+// find_pool_for_ptr returns the pool that ptr came from
+
+template <class T>
+inline T *
+Cyg_Mempool_Joined<T>::find_pool_for_ptr( const cyg_uint8 *ptr )
+{
+ cyg_uint8 i;
+
+ for ( i=0; i < poolcount; i++ ) {
+ if ( ptr >= pools[i].startaddr &&
+ ptr < pools[i].endaddr ) {
+ return pools[i].pool;
+ } // if
+ } // for
+ return NULL;
+} // Cyg_Mempool_Joined<T>::find_pool_for_ptr()
+
+
+// -------------------------------------------------------------------------
+// Constructor
+template <class T>
+inline
+Cyg_Mempool_Joined<T>::Cyg_Mempool_Joined( cyg_uint8 num_heaps, T *heaps[] )
+{
+ Cyg_Mempool_Status stat;
+ cyg_uint8 i;
+
+ CYG_REPORT_FUNCTION();
+ CYG_REPORT_FUNCARG2( "num_heaps=%u, heaps=%08x", (int)num_heaps, heaps );
+
+ CYG_CHECK_DATA_PTRC( heaps );
+
+ poolcount = num_heaps;
+
+ // allocate internal structures - this should work because we should be
+ // the first allocation for this pool; and if there isn't enough space
+ // for these teeny bits, what hope is there!
+ for (i=0; i<num_heaps; i++) {
+ pools = (struct pooldesc *)
+ heaps[i]->try_alloc( num_heaps * sizeof(struct pooldesc) );
+ if ( NULL != pools )
+ break;
+ } // for
+
+ CYG_ASSERT( pools != NULL,
+ "Couldn't allocate internal structures from any pools!");
+
+ // now set up internal structures
+ for (i=0; i<num_heaps; i++) {
+ pools[i].pool = heaps[i];
+ heaps[i]->get_status( CYG_MEMPOOL_STAT_ARENABASE|
+ CYG_MEMPOOL_STAT_ARENASIZE,
+ stat );
+
+ CYG_ASSERT( stat.arenabase != (const cyg_uint8 *)-1,
+ "pool returns valid pool base" );
+ CYG_CHECK_DATA_PTR( stat.arenabase, "Bad arena location" );
+ CYG_ASSERT( stat.arenasize > 0, "pool returns valid pool size" );
+
+ pools[i].startaddr = stat.arenabase;
+ pools[i].endaddr = stat.arenabase + stat.arenasize;
+ } // for
+
+ CYG_REPORT_RETURN();
+} // Cyg_Mempool_Joined<T>::Cyg_Mempool_Joined()
+
+
+
+// -------------------------------------------------------------------------
+// Destructor
+template <class T>
+inline
+Cyg_Mempool_Joined<T>::~Cyg_Mempool_Joined()
+{
+ CYG_REPORT_FUNCTION();
+ CYG_REPORT_FUNCARGVOID();
+
+ cyg_bool freestat;
+
+ freestat = free( (cyg_uint8 *)pools, poolcount * sizeof(struct pooldesc) );
+ CYG_ASSERT( freestat, "free failed!");
+ CYG_REPORT_RETURN();
+} // Cyg_Mempool_Joined<T>::~Cyg_Mempool_Joined()
+
+
+
+// -------------------------------------------------------------------------
+// get some memory, return NULL if none available
+template <class T>
+inline cyg_uint8 *
+Cyg_Mempool_Joined<T>::try_alloc( cyg_int32 size )
+{
+ cyg_uint8 i;
+ cyg_uint8 *ptr=NULL;
+
+ CYG_REPORT_FUNCTYPE( "returning memory at addr %08x" );
+ CYG_REPORT_FUNCARG1DV( size );
+
+ for (i=0; i<poolcount; i++) {
+ ptr = pools[i].pool->try_alloc( size );
+ if ( NULL != ptr )
+ break;
+ }
+
+ CYG_REPORT_RETVAL( ptr );
+
+ CYG_MEMALLOC_FAIL_TEST(ptr==NULL, size);
+
+ return ptr;
+} // Cyg_Mempool_Joined<T>::try_alloc()
+
+
+// -------------------------------------------------------------------------
+// resize existing allocation, if oldsize is non-NULL, previous
+// allocation size is placed into it. If previous size not available,
+// it is set to 0. NB previous allocation size may have been rounded up.
+// Occasionally the allocation can be adjusted *backwards* as well as,
+// or instead of forwards, therefore the address of the resized
+// allocation is returned, or NULL if no resizing was possible.
+// Note that this differs from ::realloc() in that no attempt is
+// made to call malloc() if resizing is not possible - that is left
+// to higher layers. The data is copied from old to new though.
+// The effects of alloc_ptr==NULL or newsize==0 are undefined
+template <class T>
+inline cyg_uint8 *
+Cyg_Mempool_Joined<T>::resize_alloc( cyg_uint8 *alloc_ptr, cyg_int32 newsize,
+ cyg_int32 *oldsize )
+{
+ T *pool;
+ cyg_uint8 * ret;
+
+ CYG_REPORT_FUNCTYPE( "success=" );
+ CYG_REPORT_FUNCARG3( "alloc_ptr=%08x, newsize=%d, &oldsize=%08x",
+ alloc_ptr, newsize, oldsize );
+ CYG_CHECK_DATA_PTRC( alloc_ptr );
+ if (NULL != oldsize )
+ CYG_CHECK_DATA_PTRC( oldsize );
+
+ pool = find_pool_for_ptr( alloc_ptr );
+ CYG_ASSERT( NULL != pool, "Couldn't find pool for pointer!" );
+
+ ret = pool->resize_alloc( alloc_ptr, newsize, oldsize );
+
+ CYG_REPORT_RETVAL( ret );
+
+ return ret;
+} // Cyg_Mempool_Joined<T>::resize_alloc()
+
+
+// -------------------------------------------------------------------------
+// free the memory back to the pool
+// returns true on success
+template <class T>
+inline cyg_bool
+Cyg_Mempool_Joined<T>::free( cyg_uint8 *ptr, cyg_int32 size )
+{
+ T *pool;
+ cyg_bool ret;
+
+ CYG_REPORT_FUNCTYPE("success=");
+ CYG_REPORT_FUNCARG2( "ptr=%08x, size=%d", ptr, size );
+ CYG_CHECK_DATA_PTRC( ptr );
+
+ pool = find_pool_for_ptr( ptr );
+ CYG_ASSERT( NULL != pool, "Couldn't find pool for pointer!" );
+
+ ret = pool->free( ptr, size );
+
+ CYG_REPORT_RETVAL( ret );
+ return ret;
+} // Cyg_Mempool_Joined<T>::free()
+
+
+// -------------------------------------------------------------------------
+// Get memory pool status
+// flags is a bitmask of requested fields to fill in. The flags are
+// defined in common.hxx
+template <class T>
+inline void
+Cyg_Mempool_Joined<T>::get_status( cyg_mempool_status_flag_t flags,
+ Cyg_Mempool_Status &status )
+{
+ cyg_uint8 i;
+ Cyg_Mempool_Status tmpstat;
+
+ status.arenasize = status.freeblocks = 0;
+ status.totalallocated = status.totalfree = 0;
+ status.maxfree = status.origsize = 0;
+
+ for ( i=0; i<poolcount; i++ ) {
+ if ( status.arenasize >= 0 ) {
+ if ( 0 != (flags & CYG_MEMPOOL_STAT_ARENASIZE) ) {
+ pools[i].pool->get_status( CYG_MEMPOOL_STAT_ARENASIZE,
+ tmpstat );
+ if ( tmpstat.arenasize > 0)
+ status.arenasize += tmpstat.arenasize;
+ else
+ status.arenasize = -1;
+ } // if
+ } // if
+
+ if ( status.freeblocks >= 0 ) {
+ if ( 0 != (flags & CYG_MEMPOOL_STAT_FREEBLOCKS) ) {
+ pools[i].pool->get_status( CYG_MEMPOOL_STAT_FREEBLOCKS,
+ tmpstat );
+ if ( tmpstat.freeblocks > 0 )
+ status.freeblocks += tmpstat.freeblocks;
+ else
+ status.freeblocks = -1;
+ } // if
+ } // if
+
+ if ( status.totalallocated >= 0 ) {
+ if ( 0 != (flags & CYG_MEMPOOL_STAT_TOTALALLOCATED) ) {
+ pools[i].pool->get_status( CYG_MEMPOOL_STAT_TOTALALLOCATED,
+ tmpstat );
+ if ( tmpstat.totalallocated > 0 )
+ status.totalallocated += tmpstat.totalallocated;
+ else
+ status.totalallocated = -1;
+ } // if
+ } // if
+
+ if ( status.totalfree >= 0 ) {
+ if ( 0 != (flags & CYG_MEMPOOL_STAT_TOTALFREE) ) {
+ pools[i].pool->get_status( CYG_MEMPOOL_STAT_TOTALFREE,
+ tmpstat );
+ if ( tmpstat.totalfree > 0 )
+ status.totalfree += tmpstat.totalfree;
+ else
+ status.totalfree = -1;
+ } // if
+ } // if
+
+ if ( status.maxfree >= 0 ) {
+ if ( 0 != (flags & CYG_MEMPOOL_STAT_MAXFREE) ) {
+ pools[i].pool->get_status( CYG_MEMPOOL_STAT_MAXFREE, tmpstat );
+ if ( tmpstat.maxfree < 0 )
+ status.maxfree = -1;
+ else if ( tmpstat.maxfree > status.maxfree )
+ status.maxfree = tmpstat.maxfree;
+ } // if
+ } // if
+
+ if ( status.origsize >= 0 ) {
+ if ( 0 != (flags & CYG_MEMPOOL_STAT_ORIGSIZE) ) {
+ pools[i].pool->get_status( CYG_MEMPOOL_STAT_ORIGSIZE, tmpstat );
+ if ( tmpstat.origsize > 0 )
+ status.origsize += tmpstat.origsize;
+ else
+ status.origsize = -1;
+ } // if
+ } // if
+
+ if ( status.maxoverhead >= 0 ) {
+ if ( 0 != (flags & CYG_MEMPOOL_STAT_MAXOVERHEAD) ) {
+ pools[i].pool->get_status( CYG_MEMPOOL_STAT_MAXOVERHEAD,
+ tmpstat );
+ if ( tmpstat.maxoverhead < 0 )
+ status.maxoverhead = -1;
+ else if ( tmpstat.maxoverhead > status.maxoverhead )
+ status.maxoverhead = tmpstat.maxoverhead;
+ } // if
+ } // if
+ } // for
+} // Cyg_Mempool_Joined<T>::get_status()
+
+
+// -------------------------------------------------------------------------
+
+#endif // ifndef CYGONCE_MEMALLOC_MEMJOIN_INL
+// EOF memjoin.inl
diff --git a/ecos/packages/services/memalloc/common/current/include/mempolt2.hxx b/ecos/packages/services/memalloc/common/current/include/mempolt2.hxx
new file mode 100644
index 0000000000..88caf0fcd0
--- /dev/null
+++ b/ecos/packages/services/memalloc/common/current/include/mempolt2.hxx
@@ -0,0 +1,139 @@
+#ifndef CYGONCE_MEMALLOC_MEMPOLT2_HXX
+#define CYGONCE_MEMALLOC_MEMPOLT2_HXX
+
+//==========================================================================
+//
+// mempolt2.hxx
+//
+// Mempolt2 (Memory pool template) class declarations
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not invalidate any other reasons why a work based on
+// this file might be covered by the GNU General Public License.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): hmt
+// Contributors: jlarmour
+// Date: 2000-06-12
+// Purpose: Define Mempolt2 class interface
+// Description: The class defined here provides the APIs for thread-safe,
+// kernel-savvy memory managers; make a class with the
+// underlying allocator as the template parameter.
+// Usage: #include <cyg/memalloc/mempolt2.hxx>
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+// It is assumed that implementations using this file have already mandated
+// that the kernel is present. So we just go ahead and use it
+
+#include <pkgconf/memalloc.h>
+#include <cyg/kernel/ktypes.h>
+#include <cyg/infra/cyg_ass.h> // assertion macros
+#include <cyg/kernel/thread.hxx>
+#include <cyg/memalloc/common.hxx> // Common memory allocator infra
+
+template <class T>
+class Cyg_Mempolt2
+{
+private:
+ T pool; // underlying memory manager
+ Cyg_ThreadQueue queue; // queue of waiting threads
+
+ class Mempolt2WaitInfo {
+ private:
+ Mempolt2WaitInfo() {}
+ public:
+ cyg_int32 size;
+ cyg_uint8 *addr;
+ Mempolt2WaitInfo( cyg_int32 allocsize )
+ { size = allocsize; addr = 0; }
+ };
+
+public:
+
+ Cyg_Mempolt2(
+ cyg_uint8 *base,
+ cyg_int32 size,
+ CYG_ADDRWORD arg_thru ); // Constructor
+ ~Cyg_Mempolt2(); // Destructor
+
+ // get some memory; wait if none available; return NULL if failed
+ // due to interrupt
+ cyg_uint8 *alloc( cyg_int32 size );
+
+#ifdef CYGFUN_KERNEL_THREADS_TIMER
+ // get some memory with a timeout; return NULL if failed
+ // due to interrupt or timeout
+ cyg_uint8 *alloc( cyg_int32 size, cyg_tick_count abs_timeout );
+#endif
+
+ // get some memory, return NULL if none available
+ cyg_uint8 *try_alloc( cyg_int32 size );
+
+ // resize existing allocation, if oldsize is non-NULL, previous
+ // allocation size is placed into it. If previous size not available,
+ // it is set to 0. NB previous allocation size may have been rounded up.
+ // Occasionally the allocation can be adjusted *backwards* as well as,
+ // or instead of forwards, therefore the address of the resized
+ // allocation is returned, or NULL if no resizing was possible.
+ // Note that this differs from ::realloc() in that no attempt is
+ // made to call malloc() if resizing is not possible - that is left
+ // to higher layers. The data is copied from old to new though.
+ // The effects of alloc_ptr==NULL or newsize==0 are undefined
+ cyg_uint8 *
+ resize_alloc( cyg_uint8 *alloc_ptr, cyg_int32 newsize,
+ cyg_int32 *oldsize );
+
+ // free the memory back to the pool
+ // returns true on success
+ cyg_bool free( cyg_uint8 *p, cyg_int32 size );
+
+ // Get memory pool status
+ // flags is a bitmask of requested fields to fill in. The flags are
+ // defined in common.hxx
+ void get_status( cyg_mempool_status_flag_t flags,
+ Cyg_Mempool_Status &status );
+
+ CYGDBG_DEFINE_CHECK_THIS
+
+};
+
+#include <cyg/memalloc/mempolt2.inl>
+
+// -------------------------------------------------------------------------
+#endif // ifndef CYGONCE_MEMALLOC_MEMPOLT2_HXX
+// EOF mempolt2.hxx
diff --git a/ecos/packages/services/memalloc/common/current/include/mempolt2.inl b/ecos/packages/services/memalloc/common/current/include/mempolt2.inl
new file mode 100644
index 0000000000..e570cd4351
--- /dev/null
+++ b/ecos/packages/services/memalloc/common/current/include/mempolt2.inl
@@ -0,0 +1,411 @@
+#ifndef CYGONCE_MEMALLOC_MEMPOLT2_INL
+#define CYGONCE_MEMALLOC_MEMPOLT2_INL
+
+//==========================================================================
+//
+// mempolt2.inl
+//
+// Mempolt2 (Memory pool template) class declarations
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not invalidate any other reasons why a work based on
+// this file might be covered by the GNU General Public License.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): hmt
+// Contributors: jlarmour
+// Date: 2000-06-12
+// Purpose: Define Mempolt2 class interface
+// Description: The class defined here provides the APIs for thread-safe,
+// kernel-savvy memory managers; make a class with the
+// underlying allocator as the template parameter.
+// Usage: #include <cyg/memalloc/mempolt2.hxx>
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <cyg/infra/cyg_ass.h> // assertion support
+#include <cyg/infra/cyg_trac.h> // tracing support
+#include <cyg/kernel/thread.inl> // implementation eg. Cyg_Thread::self();
+#include <cyg/kernel/sched.inl> // implementation eg. Cyg_Scheduler::lock();
+
+// -------------------------------------------------------------------------
+// Constructor; we _require_ these arguments and just pass them through to
+// the implementation memory pool in use.
+template <class T>
+Cyg_Mempolt2<T>::Cyg_Mempolt2(
+ cyg_uint8 *base,
+ cyg_int32 size,
+ CYG_ADDRWORD arg_thru) // Constructor
+ : pool( base, size, arg_thru )
+{
+}
+
+
+template <class T>
+Cyg_Mempolt2<T>::~Cyg_Mempolt2() // destructor
+{
+ // Prevent preemption
+ Cyg_Scheduler::lock();
+
+ while ( ! queue.empty() ) {
+ Cyg_Thread *thread = queue.dequeue();
+ thread->set_wake_reason( Cyg_Thread::DESTRUCT );
+ thread->wake();
+ }
+
+ // Unlock the scheduler and maybe switch threads
+ Cyg_Scheduler::unlock();
+}
+
+// -------------------------------------------------------------------------
+// get some memory; wait if none available
+template <class T>
+inline cyg_uint8 *
+Cyg_Mempolt2<T>::alloc( cyg_int32 size )
+{
+ CYG_REPORT_FUNCTION();
+
+ // Prevent preemption
+ Cyg_Scheduler::lock();
+ CYG_ASSERTCLASS( this, "Bad this pointer");
+
+ cyg_uint8 *ret;
+ ret = pool.try_alloc( size );
+ if ( ret ) {
+ Cyg_Scheduler::unlock();
+ CYG_ASSERTCLASS( this, "Bad this pointer");
+ CYG_REPORT_RETVAL( ret );
+ return ret;
+ }
+
+ Cyg_Thread *self = Cyg_Thread::self();
+
+ Mempolt2WaitInfo waitinfo( size );
+
+ CYG_MEMALLOC_FAIL(size);
+
+ self->set_wait_info( (CYG_ADDRWORD)&waitinfo );
+ self->set_sleep_reason( Cyg_Thread::WAIT );
+ self->sleep();
+ queue.enqueue( self );
+
+ CYG_ASSERT( 1 == Cyg_Scheduler::get_sched_lock(),
+ "Called with non-zero scheduler lock");
+
+ // Unlock scheduler and allow other threads to run
+ Cyg_Scheduler::unlock();
+
+ cyg_bool result = true; // just used as a flag here
+ switch( self->get_wake_reason() )
+ {
+ case Cyg_Thread::DESTRUCT:
+ case Cyg_Thread::BREAK:
+ result = false;
+ break;
+
+ case Cyg_Thread::EXIT:
+ self->exit();
+ break;
+
+ default:
+ break;
+ }
+
+ if ( ! result )
+ ret = NULL;
+ else
+ ret = waitinfo.addr;
+
+ CYG_ASSERT( (!result) || (NULL != ret), "Good result but no alloc!" );
+ CYG_ASSERTCLASS( this, "Bad this pointer");
+ CYG_REPORT_RETVAL( ret );
+ return ret;
+}
+
+#ifdef CYGFUN_KERNEL_THREADS_TIMER
+// -------------------------------------------------------------------------
+// get some memory with a timeout
+template <class T>
+inline cyg_uint8 *
+Cyg_Mempolt2<T>::alloc( cyg_int32 size, cyg_tick_count abs_timeout )
+{
+ CYG_REPORT_FUNCTION();
+
+ // Prevent preemption
+ Cyg_Scheduler::lock();
+ CYG_ASSERTCLASS( this, "Bad this pointer");
+
+ cyg_uint8 *ret;
+ ret = pool.try_alloc( size );
+ if ( ret ) {
+ Cyg_Scheduler::unlock();
+ CYG_ASSERTCLASS( this, "Bad this pointer");
+ CYG_REPORT_RETVAL( ret );
+ return ret;
+ }
+
+ Cyg_Thread *self = Cyg_Thread::self();
+
+ Mempolt2WaitInfo waitinfo( size );
+
+ self->set_timer( abs_timeout, Cyg_Thread::TIMEOUT );
+
+ // If the timeout is in the past, the wake reason will have been set to
+ // something other than NONE already. If so, skip the wait and go
+ // straight to unlock.
+
+ if( Cyg_Thread::NONE == self->get_wake_reason() ) {
+
+ CYG_MEMALLOC_FAIL(size);
+
+ self->set_wait_info( (CYG_ADDRWORD)&waitinfo );
+ self->sleep();
+ queue.enqueue( self );
+ }
+
+ CYG_ASSERT( 1 == Cyg_Scheduler::get_sched_lock(),
+ "Called with non-zero scheduler lock");
+
+ // Unlock scheduler and allow other threads to run
+ Cyg_Scheduler::unlock();
+
+ // clear the timer; if it actually fired, no worries.
+ self->clear_timer();
+
+ cyg_bool result = true; // just used as a flag here
+ switch( self->get_wake_reason() )
+ {
+ case Cyg_Thread::TIMEOUT:
+ result = false;
+ break;
+
+ case Cyg_Thread::DESTRUCT:
+ case Cyg_Thread::BREAK:
+ result = false;
+ break;
+
+ case Cyg_Thread::EXIT:
+ self->exit();
+ break;
+
+ default:
+ break;
+ }
+
+ if ( ! result )
+ ret = NULL;
+ else
+ ret = waitinfo.addr;
+
+ CYG_ASSERT( (!result) || (NULL != ret), "Good result but no alloc!" );
+ CYG_ASSERTCLASS( this, "Bad this pointer");
+ CYG_REPORT_RETVAL( ret );
+ return ret;
+}
+#endif
+
+// -------------------------------------------------------------------------
+// get some memory, return NULL if none available
+template <class T>
+inline cyg_uint8 *
+Cyg_Mempolt2<T>::try_alloc( cyg_int32 size )
+{
+ CYG_REPORT_FUNCTION();
+
+ // Prevent preemption
+ Cyg_Scheduler::lock();
+ CYG_ASSERTCLASS( this, "Bad this pointer");
+
+ cyg_uint8 *ret = pool.try_alloc( size );
+
+ CYG_ASSERTCLASS( this, "Bad this pointer");
+
+ // Unlock the scheduler and maybe switch threads
+ Cyg_Scheduler::unlock();
+
+ CYG_MEMALLOC_FAIL_TEST(ret==NULL, size);
+
+ return ret;
+}
+
+
+// -------------------------------------------------------------------------
+// resize existing allocation, if oldsize is non-NULL, previous
+// allocation size is placed into it. If previous size not available,
+// it is set to 0. NB previous allocation size may have been rounded up.
+// Occasionally the allocation can be adjusted *backwards* as well as,
+// or instead of forwards, therefore the address of the resized
+// allocation is returned, or NULL if no resizing was possible.
+// Note that this differs from ::realloc() in that no attempt is
+// made to call malloc() if resizing is not possible - that is left
+// to higher layers. The data is copied from old to new though.
+// The effects of alloc_ptr==NULL or newsize==0 are undefined
+template <class T>
+cyg_uint8 *
+Cyg_Mempolt2<T>::resize_alloc( cyg_uint8 *alloc_ptr, cyg_int32 newsize,
+ cyg_int32 *oldsize )
+{
+ CYG_REPORT_FUNCTION();
+
+ // Prevent preemption
+ Cyg_Scheduler::lock();
+ CYG_ASSERTCLASS( this, "Bad this pointer");
+
+ cyg_uint8 *ret = pool.resize_alloc( alloc_ptr, newsize, oldsize );
+
+ CYG_ASSERTCLASS( this, "Bad this pointer");
+
+ // Unlock the scheduler and maybe switch threads
+ Cyg_Scheduler::unlock();
+
+ CYG_MEMALLOC_FAIL_TEST(ret==NULL, newsize);
+
+ return ret;
+}
+
+
+// -------------------------------------------------------------------------
+// free the memory back to the pool
+template <class T>
+cyg_bool
+Cyg_Mempolt2<T>::free( cyg_uint8 *p, cyg_int32 size )
+{
+ CYG_REPORT_FUNCTION();
+ // Prevent preemption
+ Cyg_Scheduler::lock();
+ CYG_ASSERTCLASS( this, "Bad this pointer");
+
+ cyg_int32 ret = pool.free( p, size );
+
+ // anyone waiting?
+ if ( !(queue.empty()) ) {
+ Mempolt2WaitInfo *p;
+ Cyg_Thread *thread;
+
+#ifdef CYGIMP_MEM_T_ONEFREE_TO_ONEALLOC
+ thread = queue.dequeue();
+ p = (Mempolt2WaitInfo *)(thread->get_wait_info());
+ CYG_ASSERT( NULL == p->addr, "Thread already awoken?" );
+
+ cyg_uint8 *mem;
+ mem = pool.try_alloc( p->size );
+ CYG_ASSERT( NULL != mem, "That should have succeeded" );
+ thread->set_wake_reason( Cyg_Thread::DONE );
+ thread->wake();
+ // return the successful value to it
+ p->addr = mem;
+#else
+ Cyg_ThreadQueue holding;
+ do {
+ thread = queue.dequeue();
+ p = (Mempolt2WaitInfo *)(thread->get_wait_info());
+ CYG_ASSERT( NULL == p->addr, "Thread already awoken?" );
+
+ cyg_uint8 *mem;
+ if ( NULL != (mem = pool.try_alloc( p->size )) ) {
+ // success! awaken the thread
+ thread->set_wake_reason( Cyg_Thread::DONE );
+ thread->wake();
+ // return the successful value to it
+ p->addr = mem;
+ }
+ else {
+ // preserve the entry on the holding queue
+ holding.enqueue( thread );
+ }
+ } while ( !(queue.empty()) );
+
+ // Now re-queue the unaffected threads back into the pool queue
+ // (no pun intended)
+ while ( !(holding.empty()) ) {
+ queue.enqueue( holding.dequeue() );
+ }
+#endif // CYGIMP_MEM_T_ONEFREE_TO_ONEALLOC
+ }
+ // Unlock the scheduler and maybe switch threads
+ Cyg_Scheduler::unlock();
+ CYG_REPORT_RETVAL( ret );
+ return ret;
+}
+
+// -------------------------------------------------------------------------
+// Get memory pool status
+// Needs atomicity protection (maybe)
+template <class T>
+inline void
+Cyg_Mempolt2<T>::get_status( cyg_mempool_status_flag_t flags,
+ Cyg_Mempool_Status &status )
+{
+ // Prevent preemption
+ Cyg_Scheduler::lock();
+ CYG_ASSERTCLASS( this, "Bad this pointer");
+
+ if (0 != (flags & CYG_MEMPOOL_STAT_WAITING)) {
+ status.waiting = (0 == queue.empty());
+ }
+ pool.get_status(flags, status);
+
+ // Unlock the scheduler and maybe switch threads
+ Cyg_Scheduler::unlock();
+}
+
+// -------------------------------------------------------------------------
+// debugging/assert function
+
+#ifdef CYGDBG_USE_ASSERTS
+
+template <class T>
+inline cyg_bool
+Cyg_Mempolt2<T>::check_this(cyg_assert_class_zeal zeal) const
+{
+ CYG_REPORT_FUNCTION();
+
+ if ( Cyg_Thread::DESTRUCT == Cyg_Thread::self()->get_wake_reason() )
+ // then the whole thing is invalid, and we know it.
+ // so return OK, since this check should NOT make an error.
+ return true;
+
+ // check that we have a non-NULL pointer first
+ if( this == NULL ) return false;
+
+ return true;
+}
+#endif
+
+// -------------------------------------------------------------------------
+#endif // ifndef CYGONCE_MEMALLOC_MEMPOLT2_INL
+// EOF mempolt2.inl
diff --git a/ecos/packages/services/memalloc/common/current/include/mempoolt.hxx b/ecos/packages/services/memalloc/common/current/include/mempoolt.hxx
new file mode 100644
index 0000000000..d068c78fcd
--- /dev/null
+++ b/ecos/packages/services/memalloc/common/current/include/mempoolt.hxx
@@ -0,0 +1,123 @@
+#ifndef CYGONCE_KERNEL_MEMPOOLT_HXX
+#define CYGONCE_KERNEL_MEMPOOLT_HXX
+
+//==========================================================================
+//
+// mempoolt.hxx
+//
+// Mempoolt (Memory pool template) class declarations
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not invalidate any other reasons why a work based on
+// this file might be covered by the GNU General Public License.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): hmt
+// Contributors: hmt
+// Date: 1998-02-10
+// Purpose: Define Mempoolt class interface
+
+// Description: The class defined here provides the APIs for thread-safe,
+// kernel-savvy memory managers; make a class with the
+// underlying allocator as the template parameter.
+// Usage: #include <cyg/kernel/mempoolt.hxx>
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <cyg/kernel/ktypes.h>
+#include <cyg/infra/cyg_ass.h> // assertion macros
+#include <cyg/kernel/thread.hxx>
+
+template <class T>
+class Cyg_Mempoolt
+{
+private:
+ T pool; // underlying memory manager
+ Cyg_ThreadQueue queue; // queue of waiting threads
+
+public:
+
+ CYGDBG_DEFINE_CHECK_THIS
+
+ Cyg_Mempoolt(
+ cyg_uint8 *base,
+ cyg_int32 size,
+ CYG_ADDRWORD arg_thru ); // Constructor
+ ~Cyg_Mempoolt(); // Destructor
+
+ // get some memory; wait if none available; return NULL if failed
+ // due to interrupt
+ cyg_uint8 *alloc( cyg_int32 size );
+
+#ifdef CYGFUN_KERNEL_THREADS_TIMER
+ // get some memory with a timeout; return NULL if failed
+ // due to interrupt or timeout
+ cyg_uint8 *alloc( cyg_int32 size, cyg_tick_count abs_timeout );
+#endif
+
+ // get some memory, return NULL if none available
+ cyg_uint8 *try_alloc( cyg_int32 size );
+
+ // free the memory back to the pool
+ cyg_bool free( cyg_uint8 *p, cyg_int32 size );
+
+ // if applicable: return -1 if not fixed size
+ cyg_int32 get_blocksize();
+
+ // is anyone waiting for memory?
+ cyg_bool waiting() { return ! queue.empty(); }
+
+ // these two are obvious and generic
+ cyg_int32 get_totalmem();
+ cyg_int32 get_freemem();
+
+ // get information about the construction parameters for external
+ // freeing after the destruction of the holding object.
+ void get_arena(
+ cyg_uint8 * &base,
+ cyg_int32 &size,
+ CYG_ADDRWORD &arg_thru );
+
+ // Return the size of the memory allocation (previously returned
+ // by alloc() or try_alloc() ) at ptr. Returns -1 if not found
+ cyg_int32
+ get_allocation_size( cyg_uint8 * /* ptr */ );
+};
+
+// -------------------------------------------------------------------------
+#endif // ifndef CYGONCE_KERNEL_MEMPOOLT_HXX
+// EOF mempoolt.hxx
diff --git a/ecos/packages/services/memalloc/common/current/include/mempoolt.inl b/ecos/packages/services/memalloc/common/current/include/mempoolt.inl
new file mode 100644
index 0000000000..e329f27bc9
--- /dev/null
+++ b/ecos/packages/services/memalloc/common/current/include/mempoolt.inl
@@ -0,0 +1,401 @@
+#ifndef CYGONCE_KERNEL_MEMPOOLT_INL
+#define CYGONCE_KERNEL_MEMPOOLT_INL
+
+//==========================================================================
+//
+// mempoolt.inl
+//
+// Mempoolt (Memory pool template) class declarations
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not invalidate any other reasons why a work based on
+// this file might be covered by the GNU General Public License.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): hmt
+// Contributors: hmt
+// Date: 1998-02-10
+// Purpose: Define Mempoolt class interface
+
+// Description: The class defined here provides the APIs for thread-safe,
+// kernel-savvy memory managers; make a class with the
+// underlying allocator as the template parameter.
+// Usage: #include <cyg/kernel/mempoolt.hxx>
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <cyg/kernel/thread.inl> // implementation eg. Cyg_Thread::self();
+#include <cyg/kernel/sched.inl> // implementation eg. Cyg_Scheduler::lock();
+
+// -------------------------------------------------------------------------
+// Constructor; we _require_ these arguments and just pass them through to
+// the implementation memory pool in use.
+template <class T>
+Cyg_Mempoolt<T>::Cyg_Mempoolt(
+ cyg_uint8 *base,
+ cyg_int32 size,
+ CYG_ADDRWORD arg_thru) // Constructor
+ : pool( base, size, arg_thru )
+{
+}
+
+
+template <class T>
+Cyg_Mempoolt<T>::~Cyg_Mempoolt() // destructor
+{
+ // Prevent preemption
+ Cyg_Scheduler::lock();
+
+ while ( ! queue.empty() ) {
+ Cyg_Thread *thread = queue.dequeue();
+ thread->set_wake_reason( Cyg_Thread::DESTRUCT );
+ thread->wake();
+ }
+
+ // Unlock the scheduler and maybe switch threads
+ Cyg_Scheduler::unlock();
+}
+
+// -------------------------------------------------------------------------
+// get some memory; wait if none available
+template <class T>
+inline cyg_uint8 *
+Cyg_Mempoolt<T>::alloc( cyg_int32 size )
+{
+ CYG_REPORT_FUNCTION();
+
+ Cyg_Thread *self = Cyg_Thread::self();
+
+ // Prevent preemption
+ Cyg_Scheduler::lock();
+ CYG_ASSERTCLASS( this, "Bad this pointer");
+
+ // Loop while we got no memory, sleeping each time around the
+ // loop. This copes with the possibility of a higher priority thread
+ // grabbing the freed storage between the wakeup in free() and this
+ // thread actually starting.
+ cyg_uint8 *ret;
+ cyg_bool result = true;
+ while( result && (NULL == (ret = pool.alloc( size ))) ) {
+
+ CYG_MEMALLOC_FAIL(size);
+
+ self->set_sleep_reason( Cyg_Thread::WAIT );
+ self->sleep();
+ queue.enqueue( self );
+
+ CYG_ASSERT( 1 == Cyg_Scheduler::get_sched_lock(),
+ "Called with non-zero scheduler lock");
+
+ // Unlock scheduler and allow other threads to run
+ Cyg_Scheduler::unlock();
+ Cyg_Scheduler::lock();
+
+ CYG_ASSERTCLASS( this, "Bad this pointer");
+
+ switch( self->get_wake_reason() )
+ {
+ case Cyg_Thread::DESTRUCT:
+ case Cyg_Thread::BREAK:
+ result = false;
+ break;
+
+ case Cyg_Thread::EXIT:
+ self->exit();
+ break;
+
+ default:
+ break;
+ }
+ }
+ CYG_ASSERTCLASS( this, "Bad this pointer");
+
+ if ( ! result )
+ ret = NULL;
+
+ // Unlock the scheduler and maybe switch threads
+ Cyg_Scheduler::unlock();
+ CYG_REPORT_RETVAL( ret );
+ return ret;
+}
+
+#ifdef CYGFUN_KERNEL_THREADS_TIMER
+// -------------------------------------------------------------------------
+// get some memory with a timeout
+template <class T>
+inline cyg_uint8 *
+Cyg_Mempoolt<T>::alloc( cyg_int32 size, cyg_tick_count abs_timeout )
+{
+ CYG_REPORT_FUNCTION();
+
+ Cyg_Thread *self = Cyg_Thread::self();
+
+ // Prevent preemption
+ Cyg_Scheduler::lock();
+ CYG_ASSERTCLASS( this, "Bad this pointer");
+
+ // Loop while we got no memory, sleeping each time around the
+ // loop. This copes with the possibility of a higher priority thread
+ // grabbing the freed storage between the wakeup in free() and this
+ // thread actually starting.
+ cyg_uint8 *ret;
+ cyg_bool result = true;
+ // Set the timer _once_ outside the loop.
+ self->set_timer( abs_timeout, Cyg_Thread::TIMEOUT );
+
+ // If the timeout is in the past, the wake reason will have been
+ // set to something other than NONE already. Set the result false
+ // to force an immediate return.
+
+ if( self->get_wake_reason() != Cyg_Thread::NONE )
+ result = false;
+
+ while( result && (NULL == (ret = pool.alloc( size ))) ) {
+ CYG_MEMALLOC_FAIL(size);
+
+ self->set_sleep_reason( Cyg_Thread::TIMEOUT );
+ self->sleep();
+ queue.enqueue( self );
+
+ CYG_ASSERT( 1 == Cyg_Scheduler::get_sched_lock(),
+ "Called with non-zero scheduler lock");
+
+ // Unlock scheduler and allow other threads to run
+ Cyg_Scheduler::unlock();
+ Cyg_Scheduler::lock();
+
+ CYG_ASSERTCLASS( this, "Bad this pointer");
+ switch( self->get_wake_reason() )
+ {
+ case Cyg_Thread::TIMEOUT:
+ result = false;
+ break;
+
+ case Cyg_Thread::DESTRUCT:
+ case Cyg_Thread::BREAK:
+ result = false;
+ break;
+
+ case Cyg_Thread::EXIT:
+ self->exit();
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ CYG_ASSERTCLASS( this, "Bad this pointer");
+
+ if ( ! result )
+ ret = NULL;
+
+ // clear the timer; if it actually fired, no worries.
+ self->clear_timer();
+
+ // Unlock the scheduler and maybe switch threads
+ Cyg_Scheduler::unlock();
+ CYG_REPORT_RETVAL( ret );
+ return ret;
+}
+#endif
+
+// -------------------------------------------------------------------------
+// get some memory, return NULL if none available
+template <class T>
+inline cyg_uint8 *
+Cyg_Mempoolt<T>::try_alloc( cyg_int32 size )
+{
+ CYG_REPORT_FUNCTION();
+
+ // Prevent preemption
+ Cyg_Scheduler::lock();
+ CYG_ASSERTCLASS( this, "Bad this pointer");
+
+ cyg_uint8 *ret = pool.alloc( size );
+
+ CYG_ASSERTCLASS( this, "Bad this pointer");
+
+ // Unlock the scheduler and maybe switch threads
+ Cyg_Scheduler::unlock();
+ CYG_REPORT_RETVAL( ret );
+
+ CYG_MEMALLOC_FAIL_TEST(ret==NULL, size);
+
+ return ret;
+}
+
+
+// -------------------------------------------------------------------------
+// free the memory back to the pool
+template <class T>
+cyg_bool
+Cyg_Mempoolt<T>::free( cyg_uint8 *p, cyg_int32 size )
+{
+ // Prevent preemption
+ Cyg_Scheduler::lock();
+ CYG_ASSERTCLASS( this, "Bad this pointer");
+
+ cyg_int32 ret = pool.free( p, size );
+
+ CYG_ASSERTCLASS( this, "Bad this pointer");
+
+ while ( ret && !queue.empty() ) {
+ // we succeeded and there are people waiting
+ Cyg_Thread *thread = queue.dequeue();
+
+ CYG_ASSERTCLASS( thread, "Bad thread pointer");
+
+ // we wake them all up (ie. broadcast) to cope with variable block
+ // allocators freeing a big block when lots of small allocs wait.
+ thread->set_wake_reason( Cyg_Thread::DONE );
+ thread->wake();
+ // we cannot yield here; if a higher prio thread can't satisfy its
+ // request it would re-queue and we would loop forever
+ }
+ // Unlock the scheduler and maybe switch threads
+ Cyg_Scheduler::unlock();
+ return ret;
+}
+
+// -------------------------------------------------------------------------
+// if applicable: return -1 if not fixed size
+template <class T>
+inline cyg_int32
+Cyg_Mempoolt<T>::get_blocksize()
+{
+ // there should not be any atomicity issues here
+ return pool.get_blocksize();
+}
+
+// -------------------------------------------------------------------------
+// these two are obvious and generic, but need atomicity protection (maybe)
+template <class T>
+inline cyg_int32
+Cyg_Mempoolt<T>::get_totalmem()
+{
+ // Prevent preemption
+ Cyg_Scheduler::lock();
+ CYG_ASSERTCLASS( this, "Bad this pointer");
+
+ cyg_int32 ret = pool.get_totalmem();
+
+ // Unlock the scheduler and maybe switch threads
+ Cyg_Scheduler::unlock();
+ return ret;
+}
+
+template <class T>
+inline cyg_int32
+Cyg_Mempoolt<T>::get_freemem()
+{
+ // Prevent preemption
+ Cyg_Scheduler::lock();
+ CYG_ASSERTCLASS( this, "Bad this pointer");
+
+ cyg_int32 ret = pool.get_freemem();
+
+ // Unlock the scheduler and maybe switch threads
+ Cyg_Scheduler::unlock();
+ return ret;
+}
+
+// -------------------------------------------------------------------------
+// get information about the construction parameters for external
+// freeing after the destruction of the holding object
+template <class T>
+inline void
+Cyg_Mempoolt<T>::get_arena(
+ cyg_uint8 * &base, cyg_int32 &size, CYG_ADDRWORD &arg_thru )
+{
+ // Prevent preemption
+ Cyg_Scheduler::lock();
+ CYG_ASSERTCLASS( this, "Bad this pointer");
+
+ pool.get_arena( base, size, arg_thru );
+
+ // Unlock the scheduler and maybe switch threads
+ Cyg_Scheduler::unlock();
+}
+
+// -------------------------------------------------------------------------
+// Return the size of the memory allocation (previously returned
+// by alloc() or try_alloc() ) at ptr. Returns -1 if not found
+template <class T>
+cyg_int32
+Cyg_Mempoolt<T>::get_allocation_size( cyg_uint8 *ptr )
+{
+ cyg_int32 ret;
+
+ // Prevent preemption
+ Cyg_Scheduler::lock();
+ CYG_ASSERTCLASS( this, "Bad this pointer");
+
+ ret = pool.get_allocation_size( ptr );
+
+ // Unlock the scheduler and maybe switch threads
+ Cyg_Scheduler::unlock();
+
+ return ret;
+}
+
+// -------------------------------------------------------------------------
+// debugging/assert function
+
+#ifdef CYGDBG_USE_ASSERTS
+
+template <class T>
+inline cyg_bool
+Cyg_Mempoolt<T>::check_this(cyg_assert_class_zeal zeal) const
+{
+ CYG_REPORT_FUNCTION();
+
+ if ( Cyg_Thread::DESTRUCT == Cyg_Thread::self()->get_wake_reason() )
+ // then the whole thing is invalid, and we know it.
+ // so return OK, since this check should NOT make an error.
+ return true;
+
+ // check that we have a non-NULL pointer first
+ if( this == NULL ) return false;
+
+ return true;
+}
+#endif
+
+// -------------------------------------------------------------------------
+#endif // ifndef CYGONCE_KERNEL_MEMPOOLT_INL
+// EOF mempoolt.inl
diff --git a/ecos/packages/services/memalloc/common/current/include/memvar.hxx b/ecos/packages/services/memalloc/common/current/include/memvar.hxx
new file mode 100644
index 0000000000..3ce37609f9
--- /dev/null
+++ b/ecos/packages/services/memalloc/common/current/include/memvar.hxx
@@ -0,0 +1,164 @@
+#ifndef CYGONCE_MEMALLOC_MEMVAR_HXX
+#define CYGONCE_MEMALLOC_MEMVAR_HXX
+
+//==========================================================================
+//
+// memvar.hxx
+//
+// Memory pool with variable block class declarations
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not invalidate any other reasons why a work based on
+// this file might be covered by the GNU General Public License.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): dsm, jlarmour
+// Contributors:
+// Date: 2000-06-12
+// Purpose: Define Memvar class interface
+// Description: Inline class for constructing a variable block allocator
+// Usage: #include <cyg/memalloc/memvar.hxx>
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+// CONFIGURATION
+
+#include <pkgconf/memalloc.h>
+#ifdef CYGSEM_MEMALLOC_ALLOCATOR_VARIABLE_THREADAWARE
+# include <pkgconf/system.h>
+# ifdef CYGPKG_KERNEL
+# include <pkgconf/kernel.h>
+# endif
+#endif
+
+// when used as an implementation for malloc, we need the following
+// to let the system know the name of the class
+#define CYGCLS_MEMALLOC_MALLOC_IMPL Cyg_Mempool_Variable
+
+// if the implementation is all that's required, don't output anything else
+#ifndef __MALLOC_IMPL_WANTED
+// INCLUDES
+
+#include <cyg/infra/cyg_type.h> // types
+#include <cyg/infra/cyg_ass.h> // assertion macros
+
+#ifdef CYGFUN_KERNEL_THREADS_TIMER
+# include <cyg/kernel/ktypes.h> // cyg_tick_count
+#endif
+
+#ifdef CYGSEM_MEMALLOC_ALLOCATOR_VARIABLE_THREADAWARE
+# include <cyg/memalloc/mempolt2.hxx> // kernel safe mempool template
+#endif
+
+#include <cyg/memalloc/mvarimpl.hxx> // implementation of a variable mem pool
+#include <cyg/memalloc/common.hxx> // Common memory allocator infra
+
+
+// TYPE DEFINITIONS
+
+class Cyg_Mempool_Variable
+{
+protected:
+#ifdef CYGSEM_MEMALLOC_ALLOCATOR_VARIABLE_THREADAWARE
+ Cyg_Mempolt2<Cyg_Mempool_Variable_Implementation> mypool;
+#else
+ Cyg_Mempool_Variable_Implementation mypool;
+#endif
+
+public:
+ // This API makes concrete a class which implements a thread-safe
+ // kernel-savvy memory pool which manages variable size blocks.
+
+ // Constructor: gives the base and size of the arena in which memory is
+ // to be carved out, note that management structures are taken from the
+ // same arena.
+ Cyg_Mempool_Variable( cyg_uint8 * /* base */, cyg_int32 /* size */,
+ cyg_int32 /* alignment */=8);
+
+ // Destructor
+ ~Cyg_Mempool_Variable();
+
+ // get some memory; wait if none available
+ // if we aren't configured to be thread-aware this is irrelevant
+#ifdef CYGSEM_MEMALLOC_ALLOCATOR_VARIABLE_THREADAWARE
+ cyg_uint8 *
+ alloc( cyg_int32 /* size */ );
+
+# ifdef CYGFUN_KERNEL_THREADS_TIMER
+ // get some memory with a timeout
+ cyg_uint8 *
+ alloc( cyg_int32 /* size */, cyg_tick_count /* delay_timeout */ );
+# endif
+#endif
+
+ // get some memory, return NULL if none available
+ cyg_uint8 *
+ try_alloc( cyg_int32 /* size */ );
+
+ // resize existing allocation, if oldsize is non-NULL, previous
+ // allocation size is placed into it. If previous size not available,
+ // it is set to 0. NB previous allocation size may have been rounded up.
+ // Occasionally the allocation can be adjusted *backwards* as well as,
+ // or instead of forwards, therefore the address of the resized
+ // allocation is returned, or NULL if no resizing was possible.
+ // Note that this differs from ::realloc() in that no attempt is
+ // made to call malloc() if resizing is not possible - that is left
+ // to higher layers. The data is copied from old to new though.
+ // The effects of alloc_ptr==NULL or newsize==0 are undefined
+ cyg_uint8 *
+ resize_alloc( cyg_uint8 * /* alloc_ptr */, cyg_int32 /* newsize */,
+ cyg_int32 * /* oldsize */ =NULL );
+
+ // free the memory back to the pool
+ // returns true on success
+ cyg_bool
+ free( cyg_uint8 * /* ptr */, cyg_int32 /* size */ =0 );
+
+ // Get memory pool status
+ // flags is a bitmask of requested fields to fill in. The flags are
+ // defined in common.hxx
+ void
+ get_status( cyg_mempool_status_flag_t /* flags */,
+ Cyg_Mempool_Status & /* status */ );
+
+ CYGDBG_DEFINE_CHECK_THIS
+};
+
+#endif // ifndef __MALLOC_IMPL_WANTED
+
+#endif // ifndef CYGONCE_MEMALLOC_MEMVAR_HXX
+// EOF memvar.hxx
diff --git a/ecos/packages/services/memalloc/common/current/include/mfiximpl.hxx b/ecos/packages/services/memalloc/common/current/include/mfiximpl.hxx
new file mode 100644
index 0000000000..a976133082
--- /dev/null
+++ b/ecos/packages/services/memalloc/common/current/include/mfiximpl.hxx
@@ -0,0 +1,127 @@
+#ifndef CYGONCE_MEMALLOC_MFIXIMPL_HXX
+#define CYGONCE_MEMALLOC_MFIXIMPL_HXX
+
+//==========================================================================
+//
+// mfiximpl.hxx
+//
+// Memory pool with fixed block class declarations
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not invalidate any other reasons why a work based on
+// this file might be covered by the GNU General Public License.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): hmt
+// Contributors: jlarmour
+// Date: 2000-06-12
+// Purpose: Define Mfiximpl class interface
+// Description: Inline class for constructing a fixed block allocator
+// Usage: #include <cyg/memalloc/mfiximpl.hxx>
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <cyg/infra/cyg_type.h>
+#include <cyg/memalloc/common.hxx> // Common memory allocator infra
+
+class Cyg_Mempool_Fixed_Implementation {
+protected:
+ // these constructors are explicitly disallowed
+ Cyg_Mempool_Fixed_Implementation() {};
+// Cyg_Mempool_Fixed_Implementation( Cyg_Mempool_Fixed_Implementation &ref )
+// {};
+ Cyg_Mempool_Fixed_Implementation &
+ operator=( Cyg_Mempool_Fixed_Implementation &ref )
+ { return ref; };
+
+ cyg_uint32 *bitmap;
+ cyg_int32 maptop;
+ cyg_uint8 *mempool;
+ cyg_int32 numblocks;
+ cyg_int32 freeblocks;
+ cyg_int32 blocksize;
+ cyg_int32 firstfree;
+ cyg_uint8 *top;
+
+public:
+ // THIS is the public API of memory pools generally that can have the
+ // kernel oriented thread-safe package layer atop.
+ //
+ // The kernel package is a template whose type parameter is one of
+ // these. That is the reason there are superfluous parameters here and
+ // more genereralization than might be expected in a fixed block
+ // allocator.
+
+ // Constructor: gives the base and size of the arena in which memory is
+ // to be carved out, note that management structures are taken from the
+ // same arena. The alloc_unit may be any other param in general; it
+ // comes through from the outer constructor unchanged.
+ Cyg_Mempool_Fixed_Implementation(
+ cyg_uint8 *base,
+ cyg_int32 size,
+ CYG_ADDRWORD alloc_unit );
+
+ // Destructor
+ ~Cyg_Mempool_Fixed_Implementation();
+
+ // get some memory; size is ignored in a fixed block allocator
+ cyg_uint8 *try_alloc( cyg_int32 size );
+
+ // supposedly resize existing allocation. This is defined in the
+ // fixed block allocator purely for API consistency. It will return
+ // an error (false) for all values, except for the blocksize
+ // returns true on success
+ cyg_uint8 *
+ resize_alloc( cyg_uint8 *alloc_ptr, cyg_int32 newsize,
+ cyg_int32 *oldsize=NULL );
+
+ // free the memory back to the pool; size ignored here
+ cyg_bool free( cyg_uint8 *p, cyg_int32 size );
+
+ // Get memory pool status
+ // flags is a bitmask of requested fields to fill in. The flags are
+ // defined in common.hxx
+ void get_status( cyg_mempool_status_flag_t /* flags */,
+ Cyg_Mempool_Status & /* status */ );
+
+};
+
+#include <cyg/memalloc/mfiximpl.inl>
+
+// -------------------------------------------------------------------------
+#endif // ifndef CYGONCE_MEMALLOC_MFIXIMPL_HXX
+// EOF mfiximpl.hxx
diff --git a/ecos/packages/services/memalloc/common/current/include/mfiximpl.inl b/ecos/packages/services/memalloc/common/current/include/mfiximpl.inl
new file mode 100644
index 0000000000..b9e0a5fd81
--- /dev/null
+++ b/ecos/packages/services/memalloc/common/current/include/mfiximpl.inl
@@ -0,0 +1,243 @@
+#ifndef CYGONCE_MEMALLOC_MFIXIMPL_INL
+#define CYGONCE_MEMALLOC_MFIXIMPL_INL
+
+//==========================================================================
+//
+// mfiximpl.inl
+//
+// Memory pool with fixed block class declarations
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not invalidate any other reasons why a work based on
+// this file might be covered by the GNU General Public License.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): hmt
+// Contributors: jlarmour
+// Date: 2000-06-12
+// Purpose: Define Mfiximpl class interface
+// Description: Inline class for constructing a fixed block allocator
+// Usage: #include <cyg/kernel/mfiximpl.hxx>
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <pkgconf/memalloc.h>
+#include <cyg/hal/hal_arch.h> // HAL_LSBIT_INDEX magic asm code
+#include <cyg/memalloc/mfiximpl.hxx>
+
+
+// -------------------------------------------------------------------------
+
+inline
+Cyg_Mempool_Fixed_Implementation::Cyg_Mempool_Fixed_Implementation(
+ cyg_uint8 *base,
+ cyg_int32 size,
+ CYG_ADDRWORD alloc_unit )
+{
+ cyg_int32 i;
+ bitmap = (cyg_uint32 *)base;
+ blocksize = alloc_unit;
+
+ CYG_ASSERT( blocksize > 0, "Bad blocksize" );
+ CYG_ASSERT( size > 2, "Bad blocksize" );
+ CYG_ASSERT( blocksize < size, "blocksize, size bad" );
+
+ numblocks = size / blocksize;
+ top = base + size;
+
+ CYG_ASSERT( numblocks >= 2, "numblocks bad" );
+
+ i = (numblocks + 31)/32; // number of words to map blocks
+ while ( (i * 4 + numblocks * blocksize) > size ) {
+ numblocks --; // steal one block for admin
+ i = (numblocks + 31)/32; // number of words to map blocks
+ }
+
+ CYG_ASSERT( 0 < i, "Bad word count for bitmap after fitment" );
+ CYG_ASSERT( 0 < numblocks, "Bad block count after fitment" );
+
+ maptop = i;
+ // this should leave space for the bitmap and maintain alignment
+ mempool = top - (numblocks * blocksize);
+ CYG_ASSERT( base < mempool && mempool < top, "mempool escaped" );
+ CYG_ASSERT( (cyg_uint8 *)(&bitmap[ maptop ]) <= mempool,
+ "mempool overwrites bitmap" );
+ CYG_ASSERT( &mempool[ numblocks * blocksize ] <= top,
+ "mempool overflows top" );
+ freeblocks = numblocks;
+ firstfree = 0;
+
+ // clear out the bitmap; no blocks allocated yet
+ for ( i = 0; i < maptop; i++ )
+ bitmap[ i ] = 0;
+ // apart from the non-existent ones at the top
+ for ( i = ((numblocks-1)&31) + 1; i < 32; i++ )
+ bitmap[ maptop - 1 ] |= ( 1 << i );
+}
+
+// -------------------------------------------------------------------------
+
+inline
+Cyg_Mempool_Fixed_Implementation::~Cyg_Mempool_Fixed_Implementation()
+{
+}
+
+// -------------------------------------------------------------------------
+
+inline cyg_uint8 *
+Cyg_Mempool_Fixed_Implementation::try_alloc( cyg_int32 size )
+{
+ // size parameter is not used
+ CYG_UNUSED_PARAM( cyg_int32, size );
+ if ( 0 >= freeblocks ) {
+ CYG_MEMALLOC_FAIL(size);
+ return NULL;
+ }
+ cyg_int32 i = firstfree;
+ cyg_uint8 *p = NULL;
+ do {
+ if ( 0xffffffff != bitmap[ i ] ) {
+ // then there is a free block in this bucket
+ register cyg_uint32 j, k;
+ k = ~bitmap[ i ]; // look for a 1 in complement
+ HAL_LSBIT_INDEX( j, k );
+ CYG_ASSERT( 0 <= j && j <= 31, "Bad bit index" );
+ CYG_ASSERT( 0 == (bitmap[ i ] & (1 << j)), "Found bit not clear" );
+ bitmap[ i ] |= (1 << j); // set it allocated
+ firstfree = i;
+ freeblocks--;
+ CYG_ASSERT( freeblocks >= 0, "allocated too many" );
+ p = &mempool[ ((32 * i) + j) * blocksize ];
+ break;
+ }
+ if ( ++i >= maptop )
+ i = 0; // wrap if at top
+ } while ( i != firstfree ); // prevent hang if internal error
+ CYG_ASSERT( NULL != p, "Should have a block here" );
+ CYG_ASSERT( mempool <= p && p <= top, "alloc mem escaped" );
+ return p;
+}
+
+// -------------------------------------------------------------------------
+// supposedly resize existing allocation. This is defined in the
+// fixed block allocator purely for API consistency. It will return
+// an error (false) for all values, except for the blocksize
+// returns true on success
+
+inline cyg_uint8 *
+Cyg_Mempool_Fixed_Implementation::resize_alloc( cyg_uint8 *alloc_ptr,
+ cyg_int32 newsize,
+ cyg_int32 *oldsize )
+{
+ CYG_CHECK_DATA_PTRC( alloc_ptr );
+ if ( NULL != oldsize )
+ CYG_CHECK_DATA_PTRC( oldsize );
+
+ CYG_ASSERT( alloc_ptr >= mempool && alloc_ptr < top,
+ "alloc_ptr outside pool" );
+
+ if ( NULL != oldsize )
+ *oldsize = blocksize;
+
+ if (newsize == blocksize)
+ return alloc_ptr;
+ else {
+ CYG_MEMALLOC_FAIL(newsize);
+ return NULL;
+ }
+} // resize_alloc()
+
+
+// -------------------------------------------------------------------------
+
+inline cyg_bool
+Cyg_Mempool_Fixed_Implementation::free( cyg_uint8 *p, cyg_int32 size )
+{
+ // size parameter is not used
+ CYG_UNUSED_PARAM( cyg_int32, size );
+ if ( p < mempool || p >= top )
+ return false; // address way out of bounds
+ cyg_int32 i = p - mempool;
+ i = i / blocksize;
+ if ( &mempool[ i * blocksize ] != p )
+ return false; // address not aligned
+ cyg_int32 j = i / 32;
+ CYG_ASSERT( 0 <= j && j < maptop, "map index escaped" );
+ i = i - 32 * j;
+ CYG_ASSERT( 0 <= i && i < 32, "map bit index escaped" );
+ if ( ! ((1 << i) & bitmap[ j ] ) )
+ return false; // block was not allocated
+ bitmap[ j ] &=~(1 << i); // clear the bit
+ freeblocks++; // count the block
+ CYG_ASSERT( freeblocks <= numblocks, "freeblocks overflow" );
+ return true;
+}
+
+// -------------------------------------------------------------------------
+
+inline void
+Cyg_Mempool_Fixed_Implementation::get_status(
+ cyg_mempool_status_flag_t flags,
+ Cyg_Mempool_Status &status )
+{
+// as quick or quicker to just set it, rather than test flag first
+ status.arenabase = (const cyg_uint8 *)bitmap;
+ if ( 0 != (flags & CYG_MEMPOOL_STAT_ARENASIZE) )
+ status.arenasize = top - (cyg_uint8 *)bitmap;
+ if ( 0 != (flags & CYG_MEMPOOL_STAT_FREEBLOCKS) )
+ status.freeblocks = freeblocks;
+ if ( 0 != (flags & CYG_MEMPOOL_STAT_TOTALALLOCATED) )
+ status.totalallocated = blocksize * numblocks;
+ if ( 0 != (flags & CYG_MEMPOOL_STAT_TOTALFREE) )
+ status.totalfree = blocksize * freeblocks;
+ if ( 0 != (flags & CYG_MEMPOOL_STAT_BLOCKSIZE) )
+ status.blocksize = blocksize;
+ if ( 0 != (flags & CYG_MEMPOOL_STAT_MAXFREE) ) {
+ status.maxfree = freeblocks > 0 ? blocksize : 0;
+ }
+// as quick or quicker to just set it, rather than test flag first
+ status.origbase = (const cyg_uint8 *)bitmap;
+ if ( 0 != (flags & CYG_MEMPOOL_STAT_ORIGSIZE) )
+ status.origsize = top - (cyg_uint8 *)bitmap;
+// quicker to just set it, rather than test flag first
+ status.maxoverhead = 0;
+
+} // get_status()
+
+// -------------------------------------------------------------------------
+#endif // ifndef CYGONCE_MEMALLOC_MFIXIMPL_INL
+// EOF mfiximpl.inl
diff --git a/ecos/packages/services/memalloc/common/current/include/mvarimpl.hxx b/ecos/packages/services/memalloc/common/current/include/mvarimpl.hxx
new file mode 100644
index 0000000000..1fd172e0b0
--- /dev/null
+++ b/ecos/packages/services/memalloc/common/current/include/mvarimpl.hxx
@@ -0,0 +1,154 @@
+#ifndef CYGONCE_MEMALLOC_MVARIMPL_HXX
+#define CYGONCE_MEMALLOC_MVARIMPL_HXX
+
+//==========================================================================
+//
+// mvarimpl.hxx
+//
+// Memory pool with variable block class declarations
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not invalidate any other reasons why a work based on
+// this file might be covered by the GNU General Public License.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): dsm, jlarmour
+// Contributors:
+// Date: 2000-06-12
+// Purpose: Define Mvarimpl class interface
+// Description: Inline class for constructing a variable block allocator
+// Usage: #include <cyg/memalloc/mvarimpl.hxx>
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+#include <cyg/infra/cyg_type.h>
+#include <pkgconf/memalloc.h>
+#include <cyg/memalloc/common.hxx> // Common memory allocator infra
+
+class Cyg_Mempool_Variable_Implementation {
+protected:
+ // these constructors are explicitly disallowed
+ Cyg_Mempool_Variable_Implementation() {};
+// Cyg_Mempool_Variable_Implementation( Cyg_Mempool_Variable_Implementation &ref )
+// {};
+ Cyg_Mempool_Variable_Implementation &
+ operator=( Cyg_Mempool_Variable_Implementation &ref )
+ { return ref; };
+
+ struct memdq {
+ struct memdq *prev, *next;
+ cyg_int32 size;
+ };
+
+ struct memdq head;
+ cyg_uint8 *obase;
+ cyg_int32 osize;
+ cyg_uint8 *bottom;
+ cyg_uint8 *top;
+ cyg_int32 alignment;
+ cyg_int32 freemem;
+
+ // round up size passed to alloc/free to a size that will be used
+ // for allocation
+ cyg_int32
+ roundup(cyg_int32 size);
+
+ struct memdq *
+ addr2memdq( cyg_uint8 *addr );
+
+ struct memdq *
+ alloc2memdq( cyg_uint8 *addr );
+
+ cyg_uint8 *
+ memdq2alloc( struct memdq *dq );
+
+ void
+ insert_free_block( struct memdq *freedq );
+
+public:
+ // THIS is the public API of memory pools generally that can have the
+ // kernel oriented thread-safe package layer atop.
+
+ // Constructor: gives the base and size of the arena in which memory is
+ // to be carved out.
+ Cyg_Mempool_Variable_Implementation(
+ cyg_uint8 * /* base */,
+ cyg_int32 /* size */,
+ CYG_ADDRWORD /* alignment */ = 8 );
+
+ // Destructor
+ ~Cyg_Mempool_Variable_Implementation();
+
+ // get size bytes of memory
+ cyg_uint8 *
+ try_alloc( cyg_int32 /* size */ );
+
+ // resize existing allocation, if oldsize is non-NULL, previous
+ // allocation size is placed into it. If previous size not available,
+ // it is set to 0. NB previous allocation size may have been rounded up.
+ // Occasionally the allocation can be adjusted *backwards* as well as,
+ // or instead of forwards, therefore the address of the resized
+ // allocation is returned, or NULL if no resizing was possible.
+ // Note that this differs from ::realloc() in that no attempt is
+ // made to call malloc() if resizing is not possible - that is left
+ // to higher layers. The data is copied from old to new though.
+ // The effects of alloc_ptr==NULL or newsize==0 are undefined
+ cyg_uint8 *
+ resize_alloc( cyg_uint8 *alloc_ptr, cyg_int32 newsize,
+ cyg_int32 *oldsize );
+
+ // free size bytes of memory back to the pool
+ // returns true on success
+ cyg_bool
+ free( cyg_uint8 * /* ptr */,
+ cyg_int32 /* size */ );
+
+ // Get memory pool status
+ // flags is a bitmask of requested fields to fill in. The flags are
+ // defined in common.hxx
+ void
+ get_status( cyg_mempool_status_flag_t /* flags */,
+ Cyg_Mempool_Status & /* status */ );
+
+};
+
+#include <cyg/memalloc/mvarimpl.inl>
+
+// -------------------------------------------------------------------------
+#endif // ifndef CYGONCE_MEMALLOC_MVARIMPL_HXX
+// EOF mvarimpl.hxx
diff --git a/ecos/packages/services/memalloc/common/current/include/mvarimpl.inl b/ecos/packages/services/memalloc/common/current/include/mvarimpl.inl
new file mode 100644
index 0000000000..df38635a42
--- /dev/null
+++ b/ecos/packages/services/memalloc/common/current/include/mvarimpl.inl
@@ -0,0 +1,454 @@
+#ifndef CYGONCE_MEMALLOC_MVARIMPL_INL
+#define CYGONCE_MEMALLOC_MVARIMPL_INL
+
+//==========================================================================
+//
+// mvarimpl.inl
+//
+// Memory pool with variable block class declarations
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not invalidate any other reasons why a work based on
+// this file might be covered by the GNU General Public License.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): hmt
+// Contributors: jlarmour
+// Date: 2000-06-12
+// Purpose: Define Mvarimpl class interface
+// Description: Inline class for constructing a variable block allocator
+// Usage: #include <cyg/memalloc/mvarimpl.hxx>
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <pkgconf/memalloc.h>
+#include <cyg/memalloc/mvarimpl.hxx>
+
+#include <cyg/infra/cyg_ass.h> // assertion support
+#include <cyg/infra/cyg_trac.h> // tracing support
+
+// Simple allocator
+
+// The free list is stored on a doubly linked list, each member of
+// which is stored in the body of the free memory. The head of the
+// list has the same structure but its size field is zero. This
+// resides in the memory pool structure. Always having at least one
+// item on the list simplifies the alloc and free code.
+
+//
+inline cyg_int32
+Cyg_Mempool_Variable_Implementation::roundup( cyg_int32 size )
+{
+
+ size += sizeof(struct memdq);
+ size = (size + alignment - 1) & -alignment;
+ return size;
+}
+
+inline struct Cyg_Mempool_Variable_Implementation::memdq *
+Cyg_Mempool_Variable_Implementation::addr2memdq( cyg_uint8 *addr )
+{
+ struct memdq *dq;
+ dq = (struct memdq *)(roundup((cyg_int32)addr) - sizeof(struct memdq));
+ return dq;
+}
+
+inline struct Cyg_Mempool_Variable_Implementation::memdq *
+Cyg_Mempool_Variable_Implementation::alloc2memdq( cyg_uint8 *addr )
+{
+ return (struct memdq *)(addr - sizeof(struct memdq));
+}
+
+inline cyg_uint8 *
+Cyg_Mempool_Variable_Implementation::memdq2alloc( struct memdq *dq )
+{
+ return ((cyg_uint8 *)dq + sizeof(struct memdq));
+}
+
+// -------------------------------------------------------------------------
+
+inline void
+Cyg_Mempool_Variable_Implementation::insert_free_block( struct memdq *dq )
+{
+ struct memdq *hdq=&head;
+
+ freemem += dq->size;
+#ifdef CYGSEM_MEMALLOC_ALLOCATOR_VARIABLE_COALESCE
+// For simple coalescing have the free list be sorted by memory base address
+ struct memdq *idq;
+
+ for (idq = hdq->next; idq != hdq; idq = idq->next) {
+ if (idq > dq)
+ break;
+ }
+ // we want to insert immediately before idq
+ dq->next = idq;
+ dq->prev = idq->prev;
+ idq->prev = dq;
+ dq->prev->next = dq;
+
+ // Now do coalescing, but leave the head of the list alone.
+ if (dq->next != hdq && (char *)dq + dq->size == (char *)dq->next) {
+ dq->size += dq->next->size;
+ dq->next = dq->next->next;
+ dq->next->prev = dq;
+ }
+ if (dq->prev != hdq && (char *)dq->prev + dq->prev->size == (char *)dq) {
+ dq->prev->size += dq->size;
+ dq->prev->next = dq->next;
+ dq->next->prev = dq->prev;
+ dq = dq->prev;
+ }
+#else
+ dq->prev = hdq;
+ dq->next = hdq->next;
+ hdq->next = dq;
+ dq->next->prev=dq;
+#endif
+}
+
+// -------------------------------------------------------------------------
+
+inline
+Cyg_Mempool_Variable_Implementation::Cyg_Mempool_Variable_Implementation(
+ cyg_uint8 *base,
+ cyg_int32 size,
+ CYG_ADDRWORD align )
+{
+ CYG_REPORT_FUNCTION();
+
+ CYG_ASSERT( align > 0, "Bad alignment" );
+ CYG_ASSERT(0!=align ,"align is zero");
+ CYG_ASSERT(0==(align & align-1),"align not a power of 2");
+
+ if ((unsigned)size < sizeof(struct memdq)) {
+ bottom = NULL;
+ return;
+ }
+
+ obase=base;
+ osize=size;
+
+ alignment = align;
+ while (alignment < (cyg_int32)sizeof(struct memdq))
+ alignment += alignment;
+ CYG_ASSERT(0==(alignment & alignment-1),"alignment not a power of 2");
+
+ // the memdq for each allocation is always positioned immediately before
+ // an aligned address, so that the allocation (i.e. what eventually gets
+ // returned from alloc()) is at the correctly aligned address
+ // Therefore bottom is set to the lowest available address given the size of
+ // struct memdq and the alignment.
+ bottom = (cyg_uint8 *)addr2memdq(base);
+
+ // because we split free blocks by allocating memory from the end, not
+ // the beginning, then to preserve alignment, the *top* must also be
+ // aligned such that (top-bottom) is a multiple of the alignment
+ top = (cyg_uint8 *)((cyg_int32)(base+size+sizeof(struct memdq)) & -alignment) -
+ sizeof(struct memdq);
+
+ CYG_ASSERT( top > bottom , "heap too small" );
+ CYG_ASSERT( top <= (base+size), "top too large" );
+ CYG_ASSERT( ((cyg_int32)(top+sizeof(struct memdq)) & alignment-1)==0,
+ "top badly aligned" );
+
+ struct memdq *hdq = &head, *dq = (struct memdq *)bottom;
+
+ CYG_ASSERT( ((cyg_int32)memdq2alloc(dq) & alignment-1)==0,
+ "bottom badly aligned" );
+
+ hdq->prev = hdq->next = dq;
+ hdq->size = 0;
+ dq->prev = dq->next = hdq;
+
+ freemem = dq->size = top - bottom;
+}
+
+// -------------------------------------------------------------------------
+
+inline
+Cyg_Mempool_Variable_Implementation::~Cyg_Mempool_Variable_Implementation()
+{
+}
+
+// -------------------------------------------------------------------------
+// allocation is simple
+// First we look down the free list for a large enough block
+// If we find a block the right size, we unlink the block from
+// the free list and return a pointer to it.
+// If we find a larger block, we chop a piece off the end
+// and return that
+// Otherwise we will eventually get back to the head of the list
+// and return NULL
+inline cyg_uint8 *
+Cyg_Mempool_Variable_Implementation::try_alloc( cyg_int32 size )
+{
+ struct memdq *dq = &head;
+ cyg_uint8 *alloced;
+
+ CYG_REPORT_FUNCTION();
+
+ // Allow uninitialised (zero sized) heaps because they could exist as a
+ // quirk of the MLT setup where a dynamically sized heap is at the top of
+ // memory.
+ if (NULL == bottom)
+ return NULL;
+
+ size = roundup(size);
+
+ do {
+ CYG_ASSERT( dq->next->prev==dq, "Bad link in dq");
+ dq = dq->next;
+ if(0 == dq->size) {
+ CYG_ASSERT(dq == &head, "bad free block");
+ return NULL;
+ }
+ } while(dq->size < size);
+
+ if( size == dq->size ) {
+ // exact fit -- unlink from free list
+ dq->prev->next = dq->next;
+ dq->next->prev = dq->prev;
+ alloced = (cyg_uint8 *)dq;
+ } else {
+
+ CYG_ASSERT( dq->size > size, "block found is too small");
+
+ // allocate portion of memory from end of block
+
+ dq->size -=size;
+
+ // The portion left over has to be large enough to store a
+ // struct memdq. This is guaranteed because the alignment is
+ // larger than the size of this structure.
+
+ CYG_ASSERT( (cyg_int32)sizeof(struct memdq)<=dq->size ,
+ "not enough space for list item" );
+
+ alloced = (cyg_uint8 *)dq + dq->size;
+ }
+
+ CYG_ASSERT( bottom<=alloced && alloced<=top, "alloced outside pool" );
+
+ // Set size on allocated block
+
+ dq = (struct memdq *)alloced;
+ dq->size = size;
+ dq->next = dq->prev = (struct memdq *)0xd530d53; // magic number
+
+ freemem -=size;
+
+ cyg_uint8 *ptr = memdq2alloc( dq );
+ CYG_ASSERT( ((CYG_ADDRESS)ptr & (alignment-1)) == 0,
+ "returned memory not aligned" );
+ CYG_MEMALLOC_FAIL_TEST(ptr==NULL, size);
+
+ return ptr;
+}
+
+// -------------------------------------------------------------------------
+// resize existing allocation, if oldsize is non-NULL, previous
+// allocation size is placed into it. If previous size not available,
+// it is set to 0. NB previous allocation size may have been rounded up.
+// Occasionally the allocation can be adjusted *backwards* as well as,
+// or instead of forwards, therefore the address of the resized
+// allocation is returned, or NULL if no resizing was possible.
+// Note that this differs from ::realloc() in that no attempt is
+// made to call malloc() if resizing is not possible - that is left
+// to higher layers. The data is copied from old to new though.
+// The effects of alloc_ptr==NULL or newsize==0 are undefined
+
+inline cyg_uint8 *
+Cyg_Mempool_Variable_Implementation::resize_alloc( cyg_uint8 *alloc_ptr,
+ cyg_int32 newsize,
+ cyg_int32 *oldsize )
+{
+ cyg_uint8 *ret = NULL;
+
+ CYG_REPORT_FUNCTION();
+
+ CYG_CHECK_DATA_PTRC( alloc_ptr );
+ if ( NULL != oldsize )
+ CYG_CHECK_DATA_PTRC( oldsize );
+
+ CYG_ASSERT( (bottom <= alloc_ptr) && (alloc_ptr <= top),
+ "alloc_ptr outside pool" );
+
+ struct memdq *dq=alloc2memdq( alloc_ptr );
+
+ // check magic number in block for validity
+ CYG_ASSERT( (dq->next == dq->prev) &&
+ (dq->next == (struct memdq *)0xd530d53), "bad alloc_ptr" );
+
+ newsize = roundup(newsize);
+
+ if ( NULL != oldsize )
+ *oldsize = dq->size;
+
+ if ( newsize > dq->size ) {
+ // see if we can increase the allocation size
+ if ( (cyg_uint8 *)dq + newsize <= top ) { // obviously can't exceed pool
+ struct memdq *nextdq = (struct memdq *)((cyg_uint8 *)dq + dq->size);
+
+ if ( (nextdq->next != nextdq->prev) &&
+ (nextdq->size >= (newsize - dq->size)) ) {
+ // it's free and it's big enough
+ // we therefore temporarily join this block and *all* of
+ // the next block, so that the code below can then split it
+ nextdq->next->prev = nextdq->prev;
+ nextdq->prev->next = nextdq->next;
+ dq->size += nextdq->size;
+ freemem -= nextdq->size;
+ }
+ } // if
+ } // if
+
+ // this is also used if the allocation size was increased and we need
+ // to split it
+ if ( newsize < dq->size ) {
+ // We can shrink the allocation by splitting into smaller allocation and
+ // new free block
+ struct memdq *newdq = (struct memdq *)((cyg_uint8 *)dq + newsize);
+
+ newdq->size = dq->size - newsize;
+ dq->size = newsize;
+
+ CYG_ASSERT( (cyg_int32)sizeof(struct memdq)<=newdq->size ,
+ "not enough space for list item" );
+
+ // now return the new space back to the freelist
+ insert_free_block( newdq );
+
+ ret = alloc_ptr;
+
+ } // if
+ else if ( newsize == dq->size ) {
+ ret = alloc_ptr;
+ }
+
+ CYG_MEMALLOC_FAIL_TEST(ret==NULL, newsize);
+
+ return ret;
+
+} // resize_alloc()
+
+
+// -------------------------------------------------------------------------
+// When no coalescing is done, free is simply a matter of using the
+// freed memory as an element of the free list linking it in at the
+// start. When coalescing, the free list is sorted
+
+inline cyg_bool
+Cyg_Mempool_Variable_Implementation::free( cyg_uint8 *p, cyg_int32 size )
+{
+ CYG_REPORT_FUNCTION();
+
+ CYG_CHECK_DATA_PTRC( p );
+
+ if (!((bottom <= p) && (p <= top)))
+ return false;
+
+ struct memdq *dq=alloc2memdq( p );
+
+ // check magic number in block for validity
+ if ( (dq->next != dq->prev) ||
+ (dq->next != (struct memdq *)0xd530d53) )
+ return false;
+
+ if ( 0==size ) {
+ size = dq->size;
+ } else {
+ size = roundup(size);
+ }
+
+ if( dq->size != size )
+ return false;
+
+ CYG_ASSERT( (cyg_int32)sizeof(struct memdq)<=size ,
+ "not enough space for list item" );
+
+ insert_free_block( dq );
+
+ return true;
+}
+
+// -------------------------------------------------------------------------
+
+inline void
+Cyg_Mempool_Variable_Implementation::get_status(
+ cyg_mempool_status_flag_t flags,
+ Cyg_Mempool_Status &status )
+{
+ CYG_REPORT_FUNCTION();
+
+// as quick or quicker to just set it, rather than test flag first
+ status.arenabase = obase;
+ if ( 0 != (flags & CYG_MEMPOOL_STAT_ARENASIZE) )
+ status.arenasize = top - bottom;
+ if ( 0 != (flags & CYG_MEMPOOL_STAT_TOTALALLOCATED) )
+ status.totalallocated = (top-bottom) - freemem;
+// as quick or quicker to just set it, rather than test flag first
+ status.totalfree = freemem;
+ if ( 0 != (flags & CYG_MEMPOOL_STAT_MAXFREE) ) {
+ struct memdq *dq = &head;
+ cyg_int32 mf = 0;
+
+ do {
+ CYG_ASSERT( dq->next->prev==dq, "Bad link in dq");
+ dq = dq->next;
+ if(0 == dq->size) {
+ CYG_ASSERT(dq == &head, "bad free block");
+ break;
+ }
+ if(dq->size > mf)
+ mf = dq->size;
+ } while(1);
+ status.maxfree = mf - sizeof(struct memdq);
+ }
+// as quick or quicker to just set it, rather than test flag first
+ status.origbase = obase;
+// as quick or quicker to just set it, rather than test flag first
+ status.origsize = osize;
+
+ CYG_REPORT_RETURN();
+
+} // get_status()
+
+
+// -------------------------------------------------------------------------
+#endif // ifndef CYGONCE_MEMALLOC_MVARIMPL_INL
+// EOF mvarimpl.inl
diff --git a/ecos/packages/services/memalloc/common/current/include/sepmeta.hxx b/ecos/packages/services/memalloc/common/current/include/sepmeta.hxx
new file mode 100644
index 0000000000..b0b5243f2c
--- /dev/null
+++ b/ecos/packages/services/memalloc/common/current/include/sepmeta.hxx
@@ -0,0 +1,174 @@
+#ifndef CYGONCE_MEMALLOC_SEPMETA_HXX
+#define CYGONCE_MEMALLOC_SEPMETA_HXX
+
+//==========================================================================
+//
+// sepmeta.hxx
+//
+// Variable block memory pool with separate metadata
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not invalidate any other reasons why a work based on
+// this file might be covered by the GNU General Public License.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): jlarmour
+// Contributors:
+// Date: 2001-06-28
+// Purpose: Define Sepmeta class interface
+// Description: Inline class for constructing a variable block allocator
+// with separate metadata
+// Usage: #include <cyg/memalloc/sepmeta.hxx>
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+// CONFIGURATION
+
+#include <pkgconf/memalloc.h>
+#ifdef CYGSEM_MEMALLOC_ALLOCATOR_SEPMETA_THREADAWARE
+# include <pkgconf/system.h>
+# ifdef CYGPKG_KERNEL
+# include <pkgconf/kernel.h>
+# endif
+#endif
+
+#if 0
+// when used as an implementation for malloc, we need the following
+// to let the system know the name of the class
+#define CYGCLS_MEMALLOC_MALLOC_IMPL Cyg_Mempool_Sepmeta
+#endif
+
+// if the implementation is all that's required, don't output anything else
+#ifndef __MALLOC_IMPL_WANTED
+// INCLUDES
+
+#include <cyg/infra/cyg_type.h> // types
+#include <cyg/infra/cyg_ass.h> // assertion macros
+
+#ifdef CYGFUN_KERNEL_THREADS_TIMER
+# include <cyg/kernel/ktypes.h> // cyg_tick_count
+#endif
+
+#ifdef CYGSEM_MEMALLOC_ALLOCATOR_SEPMETA_THREADAWARE
+# include <cyg/memalloc/mempolt2.hxx> // kernel safe mempool template
+#endif
+
+#include <cyg/memalloc/sepmetaimpl.hxx>// implementation of this mem pool
+#include <cyg/memalloc/common.hxx> // Common memory allocator infra
+
+
+// TYPE DEFINITIONS
+
+class Cyg_Mempool_Sepmeta
+{
+protected:
+ // This is a horrible workaround for the fact that C++ doesn't let
+ // you construct mypool explicitly if you have to initialize a struct
+ // to pass as an argument first.
+ struct Cyg_Mempool_Sepmeta_Implementation::constructorargs args;
+
+#ifdef CYGSEM_MEMALLOC_ALLOCATOR_SEPMETA_THREADAWARE
+ Cyg_Mempolt2<Cyg_Mempool_Sepmeta_Implementation> mypool;
+#else
+ Cyg_Mempool_Sepmeta_Implementation mypool;
+#endif
+public:
+ // This API makes concrete a class which implements a thread-safe
+ // kernel-savvy memory pool which manages variable size blocks with
+ // separate metadata.
+
+ // Constructor: gives the base and size of the arena in which memory is
+ // to be carved out, note that management structures are taken from the
+ // same arena.
+ Cyg_Mempool_Sepmeta( cyg_uint8 * /* base */, cyg_int32 /* size */,
+ cyg_int32 /* alignment */,
+ cyg_uint8 * /* metabase */,
+ cyg_uint32 /* metasize */);
+
+ // Destructor
+ ~Cyg_Mempool_Sepmeta();
+
+ // get some memory; wait if none available
+ // if we aren't configured to be thread-aware this is irrelevant
+#ifdef CYGSEM_MEMALLOC_ALLOCATOR_SEPMETA_THREADAWARE
+ cyg_uint8 *
+ alloc( cyg_int32 /* size */ );
+
+# ifdef CYGFUN_KERNEL_THREADS_TIMER
+ // get some memory with a timeout
+ cyg_uint8 *
+ alloc( cyg_int32 /* size */, cyg_tick_count /* delay_timeout */ );
+# endif
+#endif
+
+ // get some memory, return NULL if none available
+ cyg_uint8 *
+ try_alloc( cyg_int32 /* size */ );
+
+ // resize existing allocation, if oldsize is non-NULL, previous
+ // allocation size is placed into it. If previous size not available,
+ // it is set to 0. NB previous allocation size may have been rounded up.
+ // Occasionally the allocation can be adjusted *backwards* as well as,
+ // or instead of forwards, therefore the address of the resized
+ // allocation is returned, or NULL if no resizing was possible.
+ // Note that this differs from ::realloc() in that no attempt is
+ // made to call malloc() if resizing is not possible - that is left
+ // to higher layers. The data is copied from old to new though.
+ // The effects of alloc_ptr==NULL or newsize==0 are undefined
+ cyg_uint8 *
+ resize_alloc( cyg_uint8 * /* alloc_ptr */, cyg_int32 /* newsize */,
+ cyg_int32 * /* oldsize */ =NULL );
+
+ // free the memory back to the pool
+ // returns true on success
+ cyg_bool
+ free( cyg_uint8 * /* ptr */, cyg_int32 /* size */ =0 );
+
+ // Get memory pool status
+ // flags is a bitmask of requested fields to fill in. The flags are
+ // defined in common.hxx
+ void
+ get_status( cyg_mempool_status_flag_t /* flags */,
+ Cyg_Mempool_Status & /* status */ );
+
+ CYGDBG_DEFINE_CHECK_THIS
+};
+
+#endif // ifndef __MALLOC_IMPL_WANTED
+
+#endif // ifndef CYGONCE_MEMALLOC_SEPMETA_HXX
+// EOF sepmeta.hxx
diff --git a/ecos/packages/services/memalloc/common/current/include/sepmetaimpl.hxx b/ecos/packages/services/memalloc/common/current/include/sepmetaimpl.hxx
new file mode 100644
index 0000000000..f475f9c28d
--- /dev/null
+++ b/ecos/packages/services/memalloc/common/current/include/sepmetaimpl.hxx
@@ -0,0 +1,194 @@
+#ifndef CYGONCE_MEMALLOC_SEPMETAIMPL_HXX
+#define CYGONCE_MEMALLOC_SEPMETAIMPL_HXX
+
+//==========================================================================
+//
+// sepmetaimpl.hxx
+//
+// Variable block memory pool with separate metadata class declarations
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not invalidate any other reasons why a work based on
+// this file might be covered by the GNU General Public License.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): jlarmour
+// Contributors:
+// Date: 2001-06-28
+// Purpose: Define Sepmetaimpl class interface
+// Description: Inline class for constructing a variable block allocator
+// with separate metadata.
+// Usage: #include <cyg/memalloc/sepmetaimpl.hxx>
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+
+#include <cyg/infra/cyg_type.h>
+#include <pkgconf/memalloc.h>
+#include <cyg/memalloc/common.hxx> // Common memory allocator infra
+
+class Cyg_Mempool_Sepmeta_Implementation {
+protected:
+ // these constructors are explicitly disallowed
+ Cyg_Mempool_Sepmeta_Implementation() {};
+// Cyg_Mempool_Sepmeta_Implementation( Cyg_Mempool_Sepmeta_Implementation &ref )
+// {};
+ Cyg_Mempool_Sepmeta_Implementation &
+ operator=( Cyg_Mempool_Sepmeta_Implementation &ref )
+ { return ref; };
+
+ struct memdq {
+ struct memdq *prev, *next; // prev/next alloced/free block
+ struct memdq *memprev, *memnext; // prev/next block in memory
+ cyg_uint8 *mem; // memory address associated with this block
+ };
+
+ struct memdq allocedhead; // list of alloced memory
+ struct memdq freehead; // list of free memory
+ struct memdq memhead; // initial block on free list
+ struct memdq memend; // dummy memdq indicating the end
+ // of memory, as if it were alloced
+ struct memdq *freemetahead; // unused memdq's
+ cyg_uint8 *obase;
+ cyg_int32 osize;
+ cyg_uint8 *metabase;
+ cyg_int32 metasize;
+ cyg_uint8 *bottom;
+ cyg_uint8 *top;
+ cyg_int32 alignment;
+ cyg_int32 freemem;
+
+ // round up addresses according to required alignment of pool
+ cyg_uint8 *
+ alignup( cyg_uint8 *addr );
+
+ cyg_uint8 *
+ aligndown( cyg_uint8 *addr );
+
+ // round up addresses according to required alignment of metadata
+ cyg_uint8 *
+ alignmetaup( cyg_uint8 *addr );
+
+ cyg_uint8 *
+ alignmetadown( cyg_uint8 *addr );
+
+ // return the alloced dq at mem
+ struct memdq *
+ find_alloced_dq( cyg_uint8 *mem );
+
+ // returns a free dq of at least size, or NULL if none
+ struct memdq *
+ find_free_dq( cyg_int32 size );
+
+ // returns the free dq following mem
+ struct memdq *
+ find_free_dq_slot( cyg_uint8 *mem );
+
+ void
+ insert_free_block( struct memdq *freedq );
+
+ static void
+ copy_data( cyg_uint8 *dst, cyg_uint8 *src, cyg_int32 nbytes );
+
+ void
+ check_free_memdq( struct memdq *dq );
+
+ void
+ check_alloced_memdq( struct memdq *dq );
+
+public:
+ // THIS is the public API of memory pools generally that can have the
+ // kernel oriented thread-safe package layer atop.
+
+ struct constructorargs {
+ cyg_int32 alignment;
+ cyg_uint8 *metabase;
+ cyg_uint32 metasize;
+ constructorargs(cyg_int32 align, cyg_uint8 *mbase, cyg_uint32 msize)
+ {
+ alignment = align; metabase = mbase; metasize = msize;
+ }
+ };
+
+ // Constructor: gives the base and size of the arena in which memory is
+ // to be carved out.
+ Cyg_Mempool_Sepmeta_Implementation(
+ cyg_uint8 * /* base */,
+ cyg_int32 /* size */,
+ CYG_ADDRWORD /* constructorargs */ );
+
+ // Destructor
+ ~Cyg_Mempool_Sepmeta_Implementation();
+
+ // get size bytes of memory
+ cyg_uint8 *
+ try_alloc( cyg_int32 /* size */ );
+
+ // resize existing allocation, if oldsize is non-NULL, previous
+ // allocation size is placed into it. If previous size not available,
+ // it is set to 0. NB previous allocation size may have been rounded up.
+ // Occasionally the allocation can be adjusted *backwards* as well as,
+ // or instead of forwards, therefore the address of the resized
+ // allocation is returned, or NULL if no resizing was possible.
+ // Note that this differs from ::realloc() in that no attempt is
+ // made to call malloc() if resizing is not possible - that is left
+ // to higher layers. The data is copied from old to new though.
+ // The effects of alloc_ptr==NULL or newsize==0 are undefined
+ cyg_uint8 *
+ resize_alloc( cyg_uint8 * /* alloc_ptr */, cyg_int32 /* newsize */,
+ cyg_int32 * /* oldsize */ );
+
+ // free size bytes of memory back to the pool
+ // returns true on success
+ cyg_bool
+ free( cyg_uint8 * /* ptr */,
+ cyg_int32 /* size */ );
+
+ // Get memory pool status
+ // flags is a bitmask of requested fields to fill in. The flags are
+ // defined in common.hxx
+ void
+ get_status( cyg_mempool_status_flag_t /* flags */,
+ Cyg_Mempool_Status & /* status */ );
+
+};
+
+#include <cyg/memalloc/sepmetaimpl.inl>
+
+// -------------------------------------------------------------------------
+#endif // ifndef CYGONCE_MEMALLOC_SEPMETAIMPL_HXX
+// EOF sepmetaimpl.hxx
diff --git a/ecos/packages/services/memalloc/common/current/include/sepmetaimpl.inl b/ecos/packages/services/memalloc/common/current/include/sepmetaimpl.inl
new file mode 100644
index 0000000000..7a3e27308c
--- /dev/null
+++ b/ecos/packages/services/memalloc/common/current/include/sepmetaimpl.inl
@@ -0,0 +1,678 @@
+#ifndef CYGONCE_MEMALLOC_SEPMETAIMPL_INL
+#define CYGONCE_MEMALLOC_SEPMETAIMPL_INL
+
+//==========================================================================
+//
+// sepmetaimpl.inl
+//
+// Variable block memory pool with separate metadata class declarations
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not invalidate any other reasons why a work based on
+// this file might be covered by the GNU General Public License.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): jlarmour
+// Contributors: hmt
+// Date: 2001-06-28
+// Purpose: Define Sepmetaimpl class interface
+// Description: Inline class for constructing a variable block allocator
+// with separate metadata.
+// Usage: #include <cyg/memalloc/sepmetaimpl.hxx>
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <pkgconf/system.h>
+#ifdef CYGPKG_ISOINFRA
+# include <pkgconf/isoinfra.h>
+#endif
+#include <pkgconf/memalloc.h>
+#include <cyg/memalloc/sepmetaimpl.hxx>
+
+#include <cyg/infra/cyg_ass.h> // assertion support
+#include <cyg/infra/cyg_trac.h> // tracing support
+
+// Simple allocator
+
+// The memory block lists are doubly linked lists. One for all alloced
+// blocks, one for all free blocks. There's also a list of unused
+// metadata from the metadata pool. The head of the
+// list has the same structure but its memnext/memprev fields are zero.
+// Always having at least one item on the list simplifies the alloc and
+// free code.
+#ifdef CYGINT_ISO_STRING_MEMFUNCS
+# include <string.h>
+#endif
+
+inline void
+Cyg_Mempool_Sepmeta_Implementation::copy_data( cyg_uint8 *dst,
+ cyg_uint8 *src,
+ cyg_int32 nbytes )
+{
+#ifdef CYGINT_ISO_STRING_MEMFUNCS
+ memmove( dst, src, nbytes );
+#else
+ if ((src < dst) && (dst < (src + nbytes))) {
+ // Have to copy backwards
+ src += nbytes;
+ dst += nbytes;
+ while (nbytes--) {
+ *--dst = *--src;
+ }
+ } else {
+ while (nbytes--) {
+ *dst++ = *src++;
+ }
+ }
+#endif
+}
+
+inline cyg_uint8 *
+Cyg_Mempool_Sepmeta_Implementation::alignup( cyg_uint8 *addr )
+{
+ return (cyg_uint8 *)((cyg_int32)(addr + alignment-1) & -alignment);
+}
+
+inline cyg_uint8 *
+Cyg_Mempool_Sepmeta_Implementation::aligndown( cyg_uint8 *addr )
+{
+ return (cyg_uint8 *)((cyg_int32)addr & -alignment);
+}
+
+inline cyg_uint8 *
+Cyg_Mempool_Sepmeta_Implementation::alignmetaup( cyg_uint8 *addr )
+{
+ const size_t memdqalign = __alignof__ (struct memdq);
+ return (cyg_uint8 *)((cyg_int32)(addr + memdqalign-1) & -memdqalign);
+}
+
+inline cyg_uint8 *
+Cyg_Mempool_Sepmeta_Implementation::alignmetadown( cyg_uint8 *addr )
+{
+ const size_t memdqalign = __alignof__ (struct memdq);
+ return (cyg_uint8 *)((cyg_int32)addr & -memdqalign);
+}
+
+// return the alloced dq at mem
+inline struct Cyg_Mempool_Sepmeta_Implementation::memdq *
+Cyg_Mempool_Sepmeta_Implementation::find_alloced_dq( cyg_uint8 *mem )
+{
+ struct memdq *dq=allocedhead.next;
+
+ while (dq->mem != mem ) {
+ CYG_ASSERT( dq->next->prev==dq, "Bad link in dq");
+ CYG_ASSERT( dq->memnext->memprev==dq, "Bad link in mem dq");
+ if (dq->next == &memend) // address not found!
+ return NULL;
+ dq = dq->next;
+ }
+ return dq;
+}
+
+// returns a free dq of at least size, or NULL if none
+inline struct Cyg_Mempool_Sepmeta_Implementation::memdq *
+Cyg_Mempool_Sepmeta_Implementation::find_free_dq( cyg_int32 size )
+{
+ struct memdq *dq = freehead.next;
+
+ while ( (dq->memnext->mem - dq->mem) < size ) {
+ CYG_ASSERT( dq->next->prev==dq, "Bad link in dq");
+ CYG_ASSERT( dq->memnext->memprev==dq, "Bad link in mem dq");
+ if (dq->next == &freehead) { // reached end of list
+ return NULL;
+ }
+ dq = dq->next; // next on free list
+ }
+ return dq;
+}
+
+// returns the free dq following mem
+inline struct Cyg_Mempool_Sepmeta_Implementation::memdq *
+Cyg_Mempool_Sepmeta_Implementation::find_free_dq_slot( cyg_uint8 *mem )
+{
+ struct memdq *dq;
+ for (dq = freehead.next; dq->mem < mem; dq = dq->next) {
+ if ( dq == &freehead ) // wrapped round
+ break;
+ }
+ return dq;
+}
+
+inline void
+Cyg_Mempool_Sepmeta_Implementation::check_free_memdq( struct memdq *dq )
+{
+ if (dq == &freehead)
+ return;
+ CYG_ASSERT(dq->memnext->memprev == dq, "corrupted free dq #1");
+ CYG_ASSERT(dq->next->prev == dq, "corrupted free dq #2");
+ CYG_ASSERT(dq->memprev->memnext == dq, "corrupted free dq #3");
+ CYG_ASSERT(dq->prev->next == dq, "corrupted free dq #4");
+ CYG_ASSERT(dq->memnext->mem > dq->mem, "free dq mem not sorted #1");
+ if (dq->memprev != &memend)
+ CYG_ASSERT(dq->memprev->mem < dq->mem, "free dq mem not sorted #2");
+}
+
+inline void
+Cyg_Mempool_Sepmeta_Implementation::check_alloced_memdq( struct memdq *dq )
+{
+ CYG_ASSERT(dq->memnext->memprev == dq, "corrupted alloced dq #1");
+ CYG_ASSERT(dq->next->prev == dq, "corrupted alloced dq #2");
+ CYG_ASSERT(dq->memprev->memnext == dq, "corrupted alloced dq #3");
+ CYG_ASSERT(dq->prev->next == dq, "corrupted alloced dq #4");
+ if (dq != &memend)
+ CYG_ASSERT(dq->memnext->mem > dq->mem, "alloced dq mem not sorted #1");
+ if (dq->memprev != &memhead)
+ CYG_ASSERT(dq->memprev->mem < dq->mem, "alloced dq mem not sorted #2");
+}
+
+// -------------------------------------------------------------------------
+
+inline void
+Cyg_Mempool_Sepmeta_Implementation::insert_free_block( struct memdq *dq )
+{
+ // scan for correct slot in the sorted free list
+ struct memdq *fdq = find_free_dq_slot( dq->mem );
+
+ CYG_ASSERT(fdq != &freehead ? fdq->mem > dq->mem : 1,
+ "Block address is already in freelist");
+
+ check_free_memdq(fdq);
+
+ if (dq->memnext == fdq) {
+ // we can coalesce these two together
+ // adjust fdq's mem address backwards to include dq
+ fdq->mem = dq->mem;
+ // and remove dq
+ fdq->memprev = dq->memprev;
+ fdq->memprev->memnext = fdq;
+ // Don't need to adjust fdq's next/prev links as it stays in the
+ // same place in the free list
+
+ // dq is now redundant so return to metadata free list
+ dq->next = freemetahead;
+ freemetahead = dq;
+
+ // reset dq
+ dq = fdq;
+ } else {
+ // insert behind fdq
+ dq->next = fdq;
+ dq->prev = fdq->prev;
+ fdq->prev = dq;
+ dq->prev->next = dq;
+ }
+
+ check_free_memdq(dq);
+
+ // maybe also coalesce backwards
+ if (dq->memprev == dq->prev) {
+ // adjust dq's mem address backwards to include dq->prev
+ dq->mem = dq->prev->mem;
+
+ // return dq->prev to metadata free list
+ dq->prev->next = freemetahead;
+ freemetahead = dq->prev;
+
+ // and remove dq->prev from mem list
+ dq->memprev = dq->prev->memprev;
+ dq->memprev->memnext = dq;
+ // and free list
+ dq->prev = dq->prev->prev;
+ dq->prev->next = dq;
+
+ check_free_memdq(dq);
+ }
+}
+
+// -------------------------------------------------------------------------
+#include <cyg/infra/diag.h>
+inline
+Cyg_Mempool_Sepmeta_Implementation::Cyg_Mempool_Sepmeta_Implementation(
+ cyg_uint8 *base,
+ cyg_int32 size,
+ CYG_ADDRWORD consargs)
+{
+ CYG_REPORT_FUNCTION();
+ struct constructorargs *args = (struct constructorargs *)consargs;
+ CYG_CHECK_DATA_PTRC( args );
+
+ alignment = args->alignment;
+
+ CYG_ASSERT( alignment > 0, "Bad alignment" );
+ CYG_ASSERT( 0!=alignment, "alignment is zero" );
+ CYG_ASSERT( 0==(alignment & alignment-1), "alignment not a power of 2" );
+
+ obase=base;
+ osize=size;
+ metabase = args->metabase;
+ metasize = args->metasize;
+
+ // bottom is set to the lowest available address given the alignment.
+ bottom = alignup( base );
+ cyg_uint8 *metabottom = alignmetaup( metabase );
+
+ // because we split free blocks by allocating memory from the end, not
+ // the beginning, then to preserve alignment, the *top* must also be
+ // aligned
+ top = aligndown( base+size );
+ cyg_uint8 *metatop = metabottom +
+ sizeof(struct memdq)*(metasize/sizeof(struct memdq));
+
+ CYG_ASSERT( top > bottom , "heap too small" );
+ CYG_ASSERT( top <= (base+size), "top too large" );
+ CYG_ASSERT( (((cyg_int32)(top)) & alignment-1)==0,
+ "top badly aligned" );
+ CYG_ASSERT( (((cyg_int32)(bottom)) & alignment-1)==0,
+ "bottom badly aligned" );
+
+ CYG_ASSERT( metatop > metabottom , "meta space too small" );
+ CYG_ASSERT( metatop <= (metabase+metasize), "metatop too large" );
+
+ // Initialize list of unused metadata blocks. Only need to do next
+ // pointers - can ignore prev and size
+ struct memdq *fq = freemetahead = (struct memdq *)metabottom;
+
+ while ((cyg_uint8 *)fq < metatop) {
+ fq->next = fq+1;
+ fq++;
+ }
+
+ CYG_ASSERT((cyg_uint8 *)fq == metatop, "traversed metadata not aligned");
+
+ // set final pointer to NULL;
+ --fq; fq->next = NULL;
+
+ // initialize the free list. memhead is the initial free block occupying
+ // all of free memory.
+ memhead.next = memhead.prev = &freehead;
+ // The mem list is circular for consistency.
+ memhead.memprev = memhead.memnext = &memend;
+ memhead.mem = bottom;
+
+ // initialize block that indicates end of memory. This pretends to
+ // be an allocated block
+ memend.next = memend.prev = &allocedhead;
+ memend.memnext = memend.memprev = &memhead;
+ memend.mem = top;
+
+ // initialize alloced list memdq. memend pretends to be allocated memory
+ // at the end
+ allocedhead.next = allocedhead.prev = &memend;
+ freehead.next = freehead.prev = &memhead;
+ // Since allocedhead and freehead are placeholders, not real blocks,
+ // assign addresses which can't match list searches
+ allocedhead.memnext = allocedhead.memprev = NULL;
+ freehead.memnext = freehead.memprev = NULL;
+ freehead.mem = allocedhead.mem = NULL;
+
+ freemem = top - bottom;
+}
+
+// -------------------------------------------------------------------------
+
+inline
+Cyg_Mempool_Sepmeta_Implementation::~Cyg_Mempool_Sepmeta_Implementation()
+{
+}
+
+// -------------------------------------------------------------------------
+// allocation is mostly simple
+// First we look down the free list for a large enough block
+// If we find a block the right size, we unlink the block from
+// the free list and return a pointer to it.
+// If we find a larger block, we chop a piece off the end
+// and return that
+// Otherwise we reach the end of the list and return NULL
+
+inline cyg_uint8 *
+Cyg_Mempool_Sepmeta_Implementation::try_alloc( cyg_int32 size )
+{
+ struct memdq *alloced;
+
+ CYG_REPORT_FUNCTION();
+
+ // Allow uninitialised (zero sized) heaps because they could exist as a
+ // quirk of the MLT setup where a dynamically sized heap is at the top of
+ // memory.
+ if (NULL == bottom || NULL==metabase)
+ return NULL;
+
+ size = (size + alignment - 1) & -alignment;
+
+ struct memdq *dq = find_free_dq( size );
+
+
+ if (NULL == dq) {
+ CYG_MEMALLOC_FAIL(size);
+ return NULL;
+ }
+
+ cyg_int32 dqsize = dq->memnext->mem - dq->mem;
+
+ if( size == dqsize ) {
+ // exact fit -- unlink from free list
+ dq->prev->next = dq->next;
+ dq->next->prev = dq->prev;
+
+ // set up this block for insertion into alloced list
+ dq->next = dq->memnext; // since dq was free, dq->memnext must
+ // be allocated otherwise it would have
+ // been coalesced
+ dq->prev = dq->next->prev;
+
+ alloced = dq;
+ } else {
+
+ CYG_ASSERT( dqsize > size, "block found is too small");
+
+ // Split into two memdq's, returning the second one
+
+ // first get a memdq
+
+ if ( NULL == freemetahead ) {
+ // out of metadata.
+ CYG_MEMALLOC_FAIL(size);
+ return NULL;
+ }
+
+ // FIXME: since we don't search all the way for an exact fit
+ // first we may be able to find an exact fit later and therefore
+ // not need more metadata. We don't do this yet though.
+
+ alloced = freemetahead;
+ freemetahead = alloced->next;
+
+ // now set its values
+ alloced->memnext = dq->memnext;
+ alloced->next = dq->memnext; // since dq was free, dq->memnext must
+ // be allocated otherwise it would have
+ // been coalesced
+ alloced->memprev = dq;
+ alloced->prev = alloced->next->prev;
+
+ alloced->mem = alloced->next->mem - size;
+
+ // now set up dq (the portion that remains a free block)
+ // dq->next and dq->prev are unchanged as we still end up pointing
+ // at the same adjacent free blocks
+ // dq->memprev obviously doesn't change
+
+ dq->memnext = alloced;
+
+ // finish inserting into memory block list
+ alloced->memnext->memprev = alloced;
+ alloced->next->prev = alloced->prev->next = alloced;
+
+ check_free_memdq(dq);
+ }
+
+ CYG_ASSERT( bottom <= alloced->mem && alloced->mem <= top,
+ "alloced outside pool" );
+
+ // Insert block into alloced list.
+ alloced->next->prev = alloced->prev->next = alloced;
+
+ check_alloced_memdq(alloced);
+
+ freemem -=size;
+
+ CYG_ASSERT( ((CYG_ADDRESS)alloced->mem & (alignment-1)) == 0,
+ "returned memory not aligned" );
+ return alloced->mem;
+}
+
+// -------------------------------------------------------------------------
+// resize existing allocation, if oldsize is non-NULL, previous
+// allocation size is placed into it. If previous size not available,
+// it is set to 0. NB previous allocation size may have been rounded up.
+// Occasionally the allocation can be adjusted *backwards* as well as,
+// or instead of forwards, therefore the address of the resized
+// allocation is returned, or NULL if no resizing was possible.
+// Note that this differs from ::realloc() in that no attempt is
+// made to call malloc() if resizing is not possible - that is left
+// to higher layers. The data is copied from old to new though.
+// The effects of alloc_ptr==NULL or newsize==0 are undefined
+
+inline cyg_uint8 *
+Cyg_Mempool_Sepmeta_Implementation::resize_alloc( cyg_uint8 *alloc_ptr,
+ cyg_int32 newsize,
+ cyg_int32 *oldsize )
+{
+ cyg_int32 currsize, origsize;
+
+ CYG_REPORT_FUNCTION();
+
+ CYG_CHECK_DATA_PTRC( alloc_ptr );
+ if ( NULL != oldsize )
+ CYG_CHECK_DATA_PTRC( oldsize );
+
+ CYG_ASSERT( (bottom <= alloc_ptr) && (alloc_ptr <= top),
+ "alloc_ptr outside pool" );
+
+ struct memdq *dq=find_alloced_dq( alloc_ptr );
+ CYG_ASSERT( dq != NULL, "passed address not previously alloced");
+
+ currsize = origsize = dq->memnext->mem - dq->mem;
+ if ( NULL != oldsize )
+ *oldsize = currsize;
+
+ if ( newsize > currsize ) {
+ cyg_int32 nextmemsize=0, prevmemsize=0;
+
+ // see if we can increase the allocation size. Don't change anything
+ // so we don't have to undo it later if it wouldn't fit
+ if ( dq->next != dq->memnext ) { // if not equal, memnext must
+ // be on free list
+ nextmemsize = dq->memnext->memnext->mem - dq->memnext->mem;
+ }
+ if ( dq->prev != dq->memprev) { // ditto
+ prevmemsize = dq->mem - dq->memprev->mem;
+ }
+ if (nextmemsize + prevmemsize + currsize < newsize)
+ {
+ CYG_MEMALLOC_FAIL_TEST(true, newsize);
+ return NULL; // can't fit it
+ }
+
+ // expand forwards
+ if ( nextmemsize != 0 ) {
+ if (nextmemsize <= (newsize - currsize)) { // taking all of it
+ struct memdq *fblk = dq->memnext;
+
+ // fix up mem list ptrs
+ dq->memnext = fblk->memnext;
+ dq->memnext->memprev=dq;
+ // fix up free list ptrs
+ fblk->next->prev = fblk->prev;
+ fblk->prev->next = fblk->next;
+
+ // return to meta list
+ fblk->next = freemetahead;
+ freemetahead = fblk->next;
+ currsize += nextmemsize;
+ } else { // only needs some
+ dq->memnext->mem += (newsize - currsize);
+ currsize = newsize;
+ }
+ }
+
+ // expand backwards
+ if ( currsize < newsize && prevmemsize != 0 ) {
+ cyg_uint8 *oldmem = dq->mem;
+
+ CYG_ASSERT( prevmemsize >= newsize - currsize,
+ "miscalculated expansion" );
+ if (prevmemsize == (newsize - currsize)) { // taking all of it
+ struct memdq *fblk = dq->memprev;
+
+ // fix up mem list ptrs
+ dq->memprev = fblk->memprev;
+ dq->memprev->memnext=dq;
+ dq->mem = fblk->mem;
+ // fix up free list ptrs
+ fblk->next->prev = fblk->prev;
+ fblk->prev->next = fblk->next;
+
+ // return to meta list
+ fblk->next = freemetahead;
+ freemetahead = fblk->next;
+ } else { // only needs some
+ dq->mem -= (newsize - currsize);
+ }
+
+ // move data into place
+ copy_data( dq->mem, oldmem, origsize );
+ }
+ }
+
+ if (newsize < currsize) {
+ // shrink allocation
+
+ // easy if the next block is already a free block
+ if ( dq->memnext != dq->next ) {
+ dq->memnext->mem -= currsize - newsize;
+ CYG_ASSERT( dq->memnext->mem > dq->mem,
+ "moving next block back corruption" );
+ } else {
+ // if its already allocated we need to create a new free list
+ // entry
+ if (NULL == freemetahead) {
+ CYG_MEMALLOC_FAIL(newsize);
+ return NULL; // can't do it
+ }
+
+ struct memdq *fdq = freemetahead;
+ freemetahead = fdq->next;
+
+ fdq->memprev = dq;
+ fdq->memnext = dq->memnext;
+ fdq->mem = dq->mem + newsize;
+
+ insert_free_block( fdq );
+ }
+ }
+
+ freemem += origsize - newsize;
+
+ return dq->mem;
+} // resize_alloc()
+
+
+// -------------------------------------------------------------------------
+// When no coalescing is done, free is simply a matter of using the
+// freed memory as an element of the free list linking it in at the
+// start. When coalescing, the free list is sorted
+
+inline cyg_bool
+Cyg_Mempool_Sepmeta_Implementation::free( cyg_uint8 *p, cyg_int32 size )
+{
+ CYG_REPORT_FUNCTION();
+
+ CYG_CHECK_DATA_PTRC( p );
+
+ if (!((bottom <= p) && (p <= top)))
+ return false;
+
+ struct memdq *dq = find_alloced_dq( p );
+ if (NULL == dq)
+ return false;
+
+ if (0 == size)
+ size = dq->memnext->mem - dq->mem;
+ else {
+ size = (size + alignment - 1) & -alignment;
+ if( (dq->memnext->mem - dq->mem) != size )
+ return false;
+ }
+
+ check_alloced_memdq( dq );
+
+ // Remove dq from alloced list
+ dq->prev->next = dq->next;
+ dq->next->prev = dq->prev;
+
+ insert_free_block( dq );
+
+ freemem += size;
+
+ return true;
+}
+
+// -------------------------------------------------------------------------
+
+inline void
+Cyg_Mempool_Sepmeta_Implementation::get_status(
+ cyg_mempool_status_flag_t flags,
+ Cyg_Mempool_Status &status )
+{
+ CYG_REPORT_FUNCTION();
+
+// as quick or quicker to just set it, rather than test flag first
+ status.arenabase = obase;
+ if ( 0 != (flags & CYG_MEMPOOL_STAT_ARENASIZE) )
+ status.arenasize = top - bottom;
+ if ( 0 != (flags & CYG_MEMPOOL_STAT_TOTALALLOCATED) )
+ status.totalallocated = (top-bottom) - freemem;
+// as quick or quicker to just set it, rather than test flag first
+ status.totalfree = freemem;
+ if ( 0 != (flags & CYG_MEMPOOL_STAT_MAXFREE) ) {
+ struct memdq *dq = &freehead;
+ cyg_int32 mf = 0;
+
+ do {
+ CYG_ASSERT( dq->next->prev==dq, "Bad link in dq");
+ dq = dq->next;
+ if (dq == &freehead) // wrapped round
+ break;
+ if(dq->memnext->mem - dq->mem > mf)
+ mf = dq->memnext->mem - dq->mem;
+ } while(1);
+ status.maxfree = mf;
+ }
+// as quick or quicker to just set it, rather than test flag first
+ status.origbase = obase;
+// as quick or quicker to just set it, rather than test flag first
+ status.origsize = osize;
+
+ CYG_REPORT_RETURN();
+
+} // get_status()
+
+
+// -------------------------------------------------------------------------
+#endif // ifndef CYGONCE_MEMALLOC_SEPMETAIMPL_INL
+// EOF sepmetaimpl.inl