diff options
author | Erik Schnetter <schnetter@aei.mpg.de> | 2005-03-05 17:46:00 +0000 |
---|---|---|
committer | Erik Schnetter <schnetter@aei.mpg.de> | 2005-03-05 17:46:00 +0000 |
commit | 251b33dc90966225a9e5e799615a5152d9d14456 (patch) | |
tree | 18de4a4fcda7ee816ad2cf169a9adb37b7ee2714 /Carpet/CarpetLib/src/mem.cc | |
parent | 5cbb9a9180e724206411d38827c6ea02f9bc9fa8 (diff) |
CarpetLib: Introduce new class mem<T> for memory management
Introduce a new class mem<T> for memory management. Memory management
has become sufficiently complicated to move into its own class. The
class mem<T> features:
1. Allocating nelem items of type T
2. Managing contiguous regions of memory for several data<T> objects
for vector groups
3. Allowing a pointer to a memory region to be passed in, which is
used instead of allocating memory through new
4. Reference counting, so that the mem<T> object only goes away once
the last using data<T> object does not need it any more.
This makes it unnecessary to delete the first data<T> objects for a
grid function group last.
darcs-hash:20050305174647-891bb-e1f53adca34e5a668af96c662845cca0f259f8e6.gz
Diffstat (limited to 'Carpet/CarpetLib/src/mem.cc')
-rw-r--r-- | Carpet/CarpetLib/src/mem.cc | 98 |
1 files changed, 98 insertions, 0 deletions
diff --git a/Carpet/CarpetLib/src/mem.cc b/Carpet/CarpetLib/src/mem.cc new file mode 100644 index 000000000..ae906d6c5 --- /dev/null +++ b/Carpet/CarpetLib/src/mem.cc @@ -0,0 +1,98 @@ +#include <algorithm> +#include <cassert> + +#include "cctk.h" + +#include "defs.hh" + +#include "mem.hh" + + + +// Total number of currently allocated bytes and objects +static size_t total_allocated_bytes = 0; +static size_t total_allocated_objects = 0; + + + +template<typename T> +mem<T>:: +mem (size_t const vectorlength, size_t const nelems, T * const memptr) + : storage_ (memptr), + nelems_ (nelems), + vectorlength_ (vectorlength), + owns_storage_ (false), + clients_ (vectorlength, false), + num_clients_ (0) +{ + if (memptr == NULL) { + const size_t nbytes = vectorlength * nelems * sizeof (T); + try { + storage_ = new T [vectorlength * nelems]; + owns_storage_ = true; + } catch (...) { + T Tdummy; + CCTK_VWarn (0, __LINE__, __FILE__, CCTK_THORNSTRING, + "Failed to allocate %.0f bytes (%.3f MB) of memory for type %s. %.0f bytes (%.3f MB) are currently allocated in %d objects", + double(nbytes), double(nbytes/1.0e6), + typestring(Tdummy), + double(total_allocated_bytes), + double(total_allocated_bytes/1.0e6), + int(total_allocated_objects)); + } + total_allocated_bytes += nbytes; + } + ++ total_allocated_objects; +} + +template<typename T> +mem<T>:: +~mem () +{ + assert (! has_clients()); + if (owns_storage_) { + delete [] storage_; + total_allocated_bytes -= vectorlength_ * nelems_ * sizeof (T); + } + -- total_allocated_objects; +} + + + +template<typename T> +void mem<T>:: +register_client (size_t const vectorindex) +{ + assert (vectorindex < vectorlength_); + assert (! clients_.at(vectorindex)); + clients_.at(vectorindex) = true; + ++ num_clients_; +} + +template<typename T> +void mem<T>:: +unregister_client (size_t const vectorindex) +{ + assert (vectorindex < vectorlength_); + assert (clients_.at(vectorindex)); + clients_.at(vectorindex) = false; + assert (num_clients_ > 0); + -- num_clients_; +} + +template<typename T> +bool mem<T>:: +has_clients () const +{ + // return find (clients_.begin(), clients_.end(), true) != clients_.end(); + return num_clients_ > 0; +} + + + +#define INSTANTIATE(T) \ + template class mem<T>; + +#include "instantiate" + +#undef INSTANTIATE |