From 8fc288e7506ede3f79ab206e9992922ffb44e955 Mon Sep 17 00:00:00 2001 From: hyung-hwan Date: Mon, 2 Feb 2015 10:45:57 +0000 Subject: [PATCH] added the HeapMmgr class --- qse/include/qse/cmn/ExcMmgr.hpp | 7 +++--- qse/include/qse/cmn/HashList.hpp | 41 +++++++++++++++++++++----------- qse/include/qse/cmn/Makefile.am | 4 ++-- qse/include/qse/cmn/Makefile.in | 8 +++---- qse/include/qse/cmn/Mmgr.hpp | 16 +++++++++++-- qse/include/qse/cmn/StdMmgr.hpp | 4 +++- qse/lib/cmn/ExcMmgr.cpp | 13 +++++----- qse/lib/cmn/Makefile.am | 2 +- qse/lib/cmn/Makefile.in | 7 +++--- qse/lib/cmn/Mmged.cpp | 3 +-- qse/lib/cmn/Mmgr.cpp | 14 +++++++++++ qse/lib/cmn/StdMmgr.cpp | 2 +- 12 files changed, 80 insertions(+), 41 deletions(-) diff --git a/qse/include/qse/cmn/ExcMmgr.hpp b/qse/include/qse/cmn/ExcMmgr.hpp index c6c1e1ea..99cf1ec4 100644 --- a/qse/include/qse/cmn/ExcMmgr.hpp +++ b/qse/include/qse/cmn/ExcMmgr.hpp @@ -28,7 +28,6 @@ #define _QSE_CMN_EXCMMGR_HPP_ #include -#include ///////////////////////////////// QSE_BEGIN_NAMESPACE(QSE) @@ -45,9 +44,9 @@ public: void* reallocMem (void* ptr, qse_size_t n); void freeMem (void* ptr); - static ExcMmgr* getDFL(); - - QSE_EXCEPTION (Error); + /// The getInstance() function returns the stock instance of the StdMmgr + /// class. + static ExcMmgr* getInstance(); }; ///////////////////////////////// diff --git a/qse/include/qse/cmn/HashList.hpp b/qse/include/qse/cmn/HashList.hpp index f877330b..0a9ae221 100644 --- a/qse/include/qse/cmn/HashList.hpp +++ b/qse/include/qse/cmn/HashList.hpp @@ -64,7 +64,7 @@ public: Mmgr* mmgr = QSE_NULL, qse_size_t node_capacity = 10, qse_size_t load_factor = 75, - qse_size_t mpb_size = 0): Mmged(mmgr) /*: datum_list (mpb_size)*/ + qse_size_t mpb_size = 0): Mmged(mmgr) { this->nodes = QSE_NULL; this->node_capacity = 0; @@ -73,9 +73,16 @@ public: try { qse_size_t total_count = node_capacity << 1; + + // Node* is a plain type that doesn't have any constructors and destructors. + // it should be safe to call the memory manager bypassing the new operator. //this->nodes = new Node*[total_count]; this->nodes = (Node**)this->getMmgr()->allocMem (QSE_SIZEOF(Node*) * total_count); + // NOTE: something wil go wrong if the memory manager doesn't raise an exception + // upon memory allocation failure. Make sure to use a memory allocation + // that raises an exception. + this->node_capacity = node_capacity; for (qse_size_t i = 0; i < total_count; i++) { @@ -88,15 +95,14 @@ public: { if (this->nodes) { - //delete[] this->nodes; - this->getMmgr()->freeMem (this->nodes); - this->node_capacity = 0; + this->getMmgr()->freeMem (this->nodes); //delete[] this->nodes; this->nodes = QSE_NULL; + this->node_capacity = 0; } if (this->datum_list) { - this->delete_datum_list (); + this->free_datum_list (); this->datum_list = QSE_NULL; } @@ -107,7 +113,7 @@ public: this->threshold = node_capacity * load_factor / 100; } - HashList (const SelfType& list): Mmged (list)/*: datum_list (list.datum_list.getMPBlockSize()) */ + HashList (const SelfType& list): Mmged (list) { this->nodes = QSE_NULL; this->node_capacity = 0; @@ -125,20 +131,21 @@ public: this->nodes[i] = QSE_NULL; } - this->datum_list = new(list.getMmgr()) DatumList (list.getMmgr(), list.datum_list->getMPBlockSize()); + // placement new + this->datum_list = new(list.getMmgr()) + DatumList (list.getMmgr(), list.datum_list->getMPBlockSize()); } catch (...) { if (this->nodes) { - //delete[] this->nodes; - this->getMmgr()->freeMem (this->nodes); - this->node_capacity = 0; + this->getMmgr()->freeMem (this->nodes); //delete[] this->nodes; this->nodes = QSE_NULL; + this->node_capacity = 0; } if (this->datum_list) { - this->delete_datum_list (); + this->free_datum_list (); this->datum_list = QSE_NULL; } @@ -170,13 +177,15 @@ public: { this->clear (); if (this->nodes) this->getMmgr()->freeMem (this->nodes); //delete[] this->nodes; - if (this->datum_list) this->delete_datum_list (); + if (this->datum_list) this->free_datum_list (); } SelfType& operator= (const SelfType& list) { this->clear (); + // note that the memory pool itself is not copied. + for (qse_size_t i = 0; i < list.node_capacity; i++) { qse_size_t head = i << 1; @@ -187,7 +196,7 @@ public: do { - copy_datum (np, this->node_capacity, this->nodes, this->datum_list); + this->copy_datum (np, this->node_capacity, this->nodes, this->datum_list); if (np == list.nodes[tail]) break; np = np->getNextNode (); } @@ -504,9 +513,13 @@ protected: } private: - void delete_datum_list () + void free_datum_list () { + // destruction in response to 'placement new' + + // call the destructor this->datum_list->~DatumList(); + // free the memory ::operator delete (this->datum_list, this->getMmgr()); } }; diff --git a/qse/include/qse/cmn/Makefile.am b/qse/include/qse/cmn/Makefile.am index dd81f6aa..de31711f 100644 --- a/qse/include/qse/cmn/Makefile.am +++ b/qse/include/qse/cmn/Makefile.am @@ -51,7 +51,7 @@ pkginclude_HEADERS = \ if ENABLE_CXX pkginclude_HEADERS += \ - Mmgr.hpp StdMmgr.hpp ExcMmgr.hpp Mmged.hpp Mpool.hpp Mpoolable.hpp \ - LinkedList.hpp HashList.hpp + Mmgr.hpp StdMmgr.hpp ExcMmgr.hpp HeapMmgr.hpp Mmged.hpp \ + Mpool.hpp Mpoolable.hpp LinkedList.hpp HashList.hpp endif diff --git a/qse/include/qse/cmn/Makefile.in b/qse/include/qse/cmn/Makefile.in index 6bb62229..6e6d8d31 100644 --- a/qse/include/qse/cmn/Makefile.in +++ b/qse/include/qse/cmn/Makefile.in @@ -51,8 +51,8 @@ POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ @ENABLE_CXX_TRUE@am__append_1 = \ -@ENABLE_CXX_TRUE@ Mmgr.hpp StdMmgr.hpp ExcMmgr.hpp Mmged.hpp Mpool.hpp Mpoolable.hpp \ -@ENABLE_CXX_TRUE@ LinkedList.hpp HashList.hpp +@ENABLE_CXX_TRUE@ Mmgr.hpp StdMmgr.hpp ExcMmgr.hpp HeapMmgr.hpp Mmged.hpp \ +@ENABLE_CXX_TRUE@ Mpool.hpp Mpoolable.hpp LinkedList.hpp HashList.hpp subdir = include/qse/cmn DIST_COMMON = $(am__pkginclude_HEADERS_DIST) $(srcdir)/Makefile.am \ @@ -90,8 +90,8 @@ am__pkginclude_HEADERS_DIST = alg.h chr.h cp949.h cp950.h dir.h dll.h \ lda.h main.h map.h mb8.h mbwc.h mem.h mux.h nwad.h nwif.h \ nwio.h oht.h opt.h path.h pio.h pma.h rbt.h rex.h sck.h sio.h \ sll.h slmb.h str.h task.h time.h tio.h tmr.h tre.h uni.h uri.h \ - utf8.h xma.h Mmgr.hpp StdMmgr.hpp ExcMmgr.hpp Mmged.hpp \ - Mpool.hpp Mpoolable.hpp LinkedList.hpp HashList.hpp + utf8.h xma.h Mmgr.hpp StdMmgr.hpp ExcMmgr.hpp HeapMmgr.hpp \ + Mmged.hpp Mpool.hpp Mpoolable.hpp LinkedList.hpp HashList.hpp am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ diff --git a/qse/include/qse/cmn/Mmgr.hpp b/qse/include/qse/cmn/Mmgr.hpp index 74223428..1c616bd7 100644 --- a/qse/include/qse/cmn/Mmgr.hpp +++ b/qse/include/qse/cmn/Mmgr.hpp @@ -29,6 +29,7 @@ #include #include +#include ///////////////////////////////// QSE_BEGIN_NAMESPACE(QSE) @@ -47,6 +48,8 @@ public: /// defines an alias type to #qse_mmgr_t typedef qse_mmgr_t mmgr_t; + QSE_EXCEPTION (MemoryError); + /// /// The Mmgr() function builds a memory manager composed of bridge /// functions connecting itself with it. @@ -108,6 +111,13 @@ protected: /// bridge function from the #qse_mmgr_t type the freeMem() function. /// static void free_mem (mmgr_t* mmgr, void* ptr); + +public: + static Mmgr* getDFL (); + static void setDFL (Mmgr* mmgr); + +protected: + static Mmgr* dfl_mmgr; }; ///////////////////////////////// @@ -115,9 +125,11 @@ QSE_END_NAMESPACE(QSE) ///////////////////////////////// void* operator new (qse_size_t size, QSE::Mmgr* mmgr); -void* operator new[] (qse_size_t size, QSE::Mmgr* mmgr); - void operator delete (void* ptr, QSE::Mmgr* mmgr); + +#if 0 +void* operator new[] (qse_size_t size, QSE::Mmgr* mmgr); void operator delete[] (void* ptr, QSE::Mmgr* mmgr); +#endif #endif diff --git a/qse/include/qse/cmn/StdMmgr.hpp b/qse/include/qse/cmn/StdMmgr.hpp index 6ce7e1e3..3a14d203 100644 --- a/qse/include/qse/cmn/StdMmgr.hpp +++ b/qse/include/qse/cmn/StdMmgr.hpp @@ -44,7 +44,9 @@ public: void* reallocMem (void* ptr, qse_size_t n); void freeMem (void* ptr); - static StdMmgr* getDFL(); + /// The getInstance() function returns the stock instance of the StdMmgr + /// class. + static StdMmgr* getInstance (); }; ///////////////////////////////// diff --git a/qse/lib/cmn/ExcMmgr.cpp b/qse/lib/cmn/ExcMmgr.cpp index 81cd58dd..f6a32219 100644 --- a/qse/lib/cmn/ExcMmgr.cpp +++ b/qse/lib/cmn/ExcMmgr.cpp @@ -26,24 +26,23 @@ #include #include -#include + ///////////////////////////////// QSE_BEGIN_NAMESPACE(QSE) ///////////////////////////////// - void* ExcMmgr::allocMem (qse_size_t n) { - void* ptr = ::malloc (n); - if (!ptr) QSE_THROW (Error); - return ptr; + void* xptr = ::malloc (n); + if (!xptr) QSE_THROW (MemoryError); + return xptr; } void* ExcMmgr::reallocMem (void* ptr, qse_size_t n) { void* xptr = ::realloc (ptr, n); - if (!xptr) QSE_THROW (Error); + if (!xptr) QSE_THROW (MemoryError); return xptr; } @@ -52,7 +51,7 @@ void ExcMmgr::freeMem (void* ptr) ::free (ptr); } -ExcMmgr* ExcMmgr::getDFL () +ExcMmgr* ExcMmgr::getInstance () { static ExcMmgr DFL; return &DFL; diff --git a/qse/lib/cmn/Makefile.am b/qse/lib/cmn/Makefile.am index 7d3d1c3d..eacee26b 100644 --- a/qse/lib/cmn/Makefile.am +++ b/qse/lib/cmn/Makefile.am @@ -141,7 +141,7 @@ if ENABLE_CXX lib_LTLIBRARIES += libqsecmnxx.la libqsecmnxx_la_SOURCES = \ - Mmgr.cpp StdMmgr.cpp ExcMmgr.cpp Mmged.cpp Mpool.cpp + Mmgr.cpp StdMmgr.cpp ExcMmgr.cpp HeapMmgr.cpp Mmged.cpp Mpool.cpp libqsecmnxx_la_LDFLAGS = -version-info 1:0:0 -no-undefined libqsecmnxx_la_LIBADD = diff --git a/qse/lib/cmn/Makefile.in b/qse/lib/cmn/Makefile.in index ee7113e3..8f2ee5c5 100644 --- a/qse/lib/cmn/Makefile.in +++ b/qse/lib/cmn/Makefile.in @@ -150,9 +150,9 @@ libqsecmn_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(libqsecmn_la_LDFLAGS) $(LDFLAGS) -o $@ libqsecmnxx_la_DEPENDENCIES = am__libqsecmnxx_la_SOURCES_DIST = Mmgr.cpp StdMmgr.cpp ExcMmgr.cpp \ - Mmged.cpp Mpool.cpp + HeapMmgr.cpp Mmged.cpp Mpool.cpp @ENABLE_CXX_TRUE@am_libqsecmnxx_la_OBJECTS = Mmgr.lo StdMmgr.lo \ -@ENABLE_CXX_TRUE@ ExcMmgr.lo Mmged.lo Mpool.lo +@ENABLE_CXX_TRUE@ ExcMmgr.lo HeapMmgr.lo Mmged.lo Mpool.lo libqsecmnxx_la_OBJECTS = $(am_libqsecmnxx_la_OBJECTS) libqsecmnxx_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \ @@ -435,7 +435,7 @@ libqsecmn_la_SOURCES = alg-base64.c alg-rand.c alg-search.c alg-sort.c \ libqsecmn_la_LDFLAGS = -version-info 1:0:0 -no-undefined libqsecmn_la_LIBADD = $(SOCKET_LIBS) $(QUADMATH_LIBS) @ENABLE_CXX_TRUE@libqsecmnxx_la_SOURCES = \ -@ENABLE_CXX_TRUE@ Mmgr.cpp StdMmgr.cpp ExcMmgr.cpp Mmged.cpp Mpool.cpp +@ENABLE_CXX_TRUE@ Mmgr.cpp StdMmgr.cpp ExcMmgr.cpp HeapMmgr.cpp Mmged.cpp Mpool.cpp @ENABLE_CXX_TRUE@libqsecmnxx_la_LDFLAGS = -version-info 1:0:0 -no-undefined @ENABLE_CXX_TRUE@libqsecmnxx_la_LIBADD = @@ -517,6 +517,7 @@ distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ExcMmgr.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/HeapMmgr.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Mmged.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Mmgr.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Mpool.Plo@am__quote@ diff --git a/qse/lib/cmn/Mmged.cpp b/qse/lib/cmn/Mmged.cpp index 29bc484a..0133d881 100644 --- a/qse/lib/cmn/Mmged.cpp +++ b/qse/lib/cmn/Mmged.cpp @@ -25,7 +25,6 @@ */ #include -#include ///////////////////////////////// QSE_BEGIN_NAMESPACE(QSE) @@ -33,7 +32,7 @@ QSE_BEGIN_NAMESPACE(QSE) Mmged::Mmged (Mmgr* mmgr) { - if (!mmgr) mmgr = ExcMmgr::getDFL(); // TODO: use a different manager???? StdMmgr??? + if (!mmgr) mmgr = Mmgr::getDFL(); this->mmgr = mmgr; } ///////////////////////////////// diff --git a/qse/lib/cmn/Mmgr.cpp b/qse/lib/cmn/Mmgr.cpp index b4b6de38..30ca9d6e 100644 --- a/qse/lib/cmn/Mmgr.cpp +++ b/qse/lib/cmn/Mmgr.cpp @@ -25,6 +25,8 @@ */ #include +#include +#include ///////////////////////////////// QSE_BEGIN_NAMESPACE(QSE) @@ -45,6 +47,18 @@ void Mmgr::free_mem (mmgr_t* mmgr, void* ptr) ((Mmgr*)mmgr->ctx)->freeMem (ptr); } +Mmgr* Mmgr::dfl_mmgr = ExcMmgr::getInstance(); + +Mmgr* Mmgr::getDFL () +{ + return Mmgr::dfl_mmgr; +} + +void Mmgr::setDFL (Mmgr* mmgr) +{ + Mmgr::dfl_mmgr = mmgr; +} + ///////////////////////////////// QSE_END_NAMESPACE(QSE) ///////////////////////////////// diff --git a/qse/lib/cmn/StdMmgr.cpp b/qse/lib/cmn/StdMmgr.cpp index 5cddb6ca..bdd6ae5f 100644 --- a/qse/lib/cmn/StdMmgr.cpp +++ b/qse/lib/cmn/StdMmgr.cpp @@ -47,7 +47,7 @@ void StdMmgr::freeMem (void* ptr) ::free (ptr); } -StdMmgr* StdMmgr::getDFL () +StdMmgr* StdMmgr::getInstance () { static StdMmgr DFL; return &DFL;