diff options
author | Erik Schnetter <schnetter@cct.lsu.edu> | 2007-05-26 19:50:00 +0000 |
---|---|---|
committer | Erik Schnetter <schnetter@cct.lsu.edu> | 2007-05-26 19:50:00 +0000 |
commit | 7e828035d9a2238afeac10838beff2e947d899f9 (patch) | |
tree | 7e238cb23f68a509c02a301592ff71b5fc864d16 /Carpet/CarpetLib/src/mem.cc | |
parent | 4b1bbf6c2a30807847cf782de1091fbf9940d1de (diff) |
CarpetLib: Add class mempool
A mempool (memory pool) is a large chunk of memory. You can allocate
pieces of it. In order to simplify things there is no way to free a
piece again. If the mempool is destroyed, then all its memory is
freed. This is dangerous: you have to make sure that no one continues
to use that memory afterwards. Using a memory pool for short-lived
objects can reduce memory fragmentation.
darcs-hash:20070526195001-dae7b-b419df094d19b85dbf145debdf62da2dc57823af.gz
Diffstat (limited to 'Carpet/CarpetLib/src/mem.cc')
-rw-r--r-- | Carpet/CarpetLib/src/mem.cc | 55 |
1 files changed, 55 insertions, 0 deletions
diff --git a/Carpet/CarpetLib/src/mem.cc b/Carpet/CarpetLib/src/mem.cc index a983fc497..f53a9ccd0 100644 --- a/Carpet/CarpetLib/src/mem.cc +++ b/Carpet/CarpetLib/src/mem.cc @@ -135,6 +135,61 @@ has_clients () const +size_t const mempool::chunksize; +size_t const mempool::align; + +mempool:: +mempool () + : freeptr (0), freesize (0) +{ +} + +mempool:: +~mempool () +{ + while (not chunks.empty()) { + free (chunks.top()); + chunks.pop(); + } +} + +void * +mempool:: +alloc (size_t nbytes) +{ + // Take a shortcut for silly requests + if (nbytes == 0) return 0; + + // Round up request size + nbytes = (nbytes + align - 1) / align * align; + + // If there is not enough memory left, allocate a new chunk. Ignore + // whatever is left in the old chunk. + if (nbytes > freesize) { + // Allocate the usual chunk size, or more if more is requested + freesize = max (chunksize, nbytes); + freeptr = malloc (freesize); + if (not freeptr) { + CCTK_VWarn (CCTK_WARN_ABORT, __LINE__, __FILE__, CCTK_THORNSTRING, + "Failed to allocate %.3f MB of memory", + double(freesize/1.0e6)); + } + // Remember the pointer so that it can be freed + chunks.push (freeptr); + } + + // Allocate a piece from the current chunk + void * const ptr = freeptr; + assert (freesize >= nbytes); + freesize -= nbytes; + assert (freeptr); + freeptr = static_cast <char *> (freeptr) + nbytes; + + return ptr; +} + + + extern "C" void CarpetLib_printmemstats (CCTK_ARGUMENTS); void CarpetLib_printmemstats (CCTK_ARGUMENTS) |