aboutsummaryrefslogtreecommitdiff
path: root/Carpet/CarpetLib/src/mem.cc
diff options
context:
space:
mode:
authorErik Schnetter <schnetter@aei.mpg.de>2005-03-05 17:46:00 +0000
committerErik Schnetter <schnetter@aei.mpg.de>2005-03-05 17:46:00 +0000
commit251b33dc90966225a9e5e799615a5152d9d14456 (patch)
tree18de4a4fcda7ee816ad2cf169a9adb37b7ee2714 /Carpet/CarpetLib/src/mem.cc
parent5cbb9a9180e724206411d38827c6ea02f9bc9fa8 (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.cc98
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