diff --git a/qse/include/qse/Exception.hpp b/qse/include/qse/Exception.hpp index 56b03eee..a8dc9e2c 100644 --- a/qse/include/qse/Exception.hpp +++ b/qse/include/qse/Exception.hpp @@ -25,8 +25,8 @@ */ -#ifndef _QSE_EXCEPTION_CLASS_ -#define _QSE_EXCEPTION_CLASS_ +#ifndef _QSE_EXCEPTION_HPP_ +#define _QSE_EXCEPTION_HPP_ #include #include diff --git a/qse/include/qse/cmn/HashList.hpp b/qse/include/qse/cmn/HashList.hpp index ba010302..f877330b 100644 --- a/qse/include/qse/cmn/HashList.hpp +++ b/qse/include/qse/cmn/HashList.hpp @@ -52,10 +52,8 @@ struct HashListComparator } }; -// TODO: use MPOLL for nodes??? - template , typename COMPARATOR = HashListComparator > -class HashList +class HashList: public Mmged { public: typedef LinkedList DatumList; @@ -63,9 +61,10 @@ public: typedef HashList SelfType; HashList ( + Mmgr* mmgr = QSE_NULL, qse_size_t node_capacity = 10, qse_size_t load_factor = 75, - qse_size_t mpb_size = 0)/*: datum_list (mpb_size)*/ + qse_size_t mpb_size = 0): Mmged(mmgr) /*: datum_list (mpb_size)*/ { this->nodes = QSE_NULL; this->node_capacity = 0; @@ -73,28 +72,31 @@ public: try { - this->nodes = new Node*[node_capacity << 1]; + qse_size_t total_count = node_capacity << 1; + //this->nodes = new Node*[total_count]; + this->nodes = (Node**)this->getMmgr()->allocMem (QSE_SIZEOF(Node*) * total_count); this->node_capacity = node_capacity; - for (qse_size_t i = 0; i < (node_capacity << 1); i++) + for (qse_size_t i = 0; i < total_count; i++) { this->nodes[i] = QSE_NULL; } - this->datum_list = new DatumList (mpb_size); + this->datum_list = new(this->getMmgr()) DatumList (this->getMmgr(), mpb_size); } catch (...) { if (this->nodes) { - delete[] this->nodes; + //delete[] this->nodes; + this->getMmgr()->freeMem (this->nodes); this->node_capacity = 0; this->nodes = QSE_NULL; } if (this->datum_list) { - delete this->datum_list; + this->delete_datum_list (); this->datum_list = QSE_NULL; } @@ -105,7 +107,7 @@ public: this->threshold = node_capacity * load_factor / 100; } - HashList (const SelfType& list)/*: datum_list (list.datum_list.getMPBlockSize()) */ + HashList (const SelfType& list): Mmged (list)/*: datum_list (list.datum_list.getMPBlockSize()) */ { this->nodes = QSE_NULL; this->node_capacity = 0; @@ -113,26 +115,30 @@ public: try { - this->nodes = new Node*[list.node_capacity << 1]; + qse_size_t total_count = list.node_capacity << 1; + //this->nodes = new Node*[total_count]; + this->nodes = (Node**)this->getMmgr()->allocMem (QSE_SIZEOF(Node*) * total_count); + this->node_capacity = list.node_capacity; - for (qse_size_t i = 0; i < list.node_capacity << 1; i++) + for (qse_size_t i = 0; i < total_count; i++) { this->nodes[i] = QSE_NULL; } - this->datum_list = new DatumList (list.datum_list->getMPBlockSize()); + this->datum_list = new(list.getMmgr()) DatumList (list.getMmgr(), list.datum_list->getMPBlockSize()); } catch (...) { if (this->nodes) { - delete[] this->nodes; + //delete[] this->nodes; + this->getMmgr()->freeMem (this->nodes); this->node_capacity = 0; this->nodes = QSE_NULL; } if (this->datum_list) { - delete this->datum_list; + this->delete_datum_list (); this->datum_list = QSE_NULL; } @@ -163,8 +169,8 @@ public: ~HashList () { this->clear (); - if (this->nodes) delete[] this->nodes; - if (this->datum_list) delete this->datum_list; + if (this->nodes) this->getMmgr()->freeMem (this->nodes); //delete[] this->nodes; + if (this->datum_list) this->delete_datum_list (); } SelfType& operator= (const SelfType& list) @@ -416,7 +422,7 @@ protected: // Move nodes around instead of values to prevent // existing values from being copied over and destroyed. // this incurs less number of memory allocations also. - SelfType temp (this->node_capacity << 1, this->load_factor, this->datum_list->getMPBlockSize()); + SelfType temp (this->getMmgr(), this->node_capacity << 1, this->load_factor, this->datum_list->getMPBlockSize()); Node* p = this->datum_list->getHeadNode(); while (p) { @@ -497,6 +503,12 @@ protected: } } +private: + void delete_datum_list () + { + this->datum_list->~DatumList(); + ::operator delete (this->datum_list, this->getMmgr()); + } }; diff --git a/qse/include/qse/cmn/LinkedList.hpp b/qse/include/qse/cmn/LinkedList.hpp index 2895ffbc..b4360443 100644 --- a/qse/include/qse/cmn/LinkedList.hpp +++ b/qse/include/qse/cmn/LinkedList.hpp @@ -29,8 +29,6 @@ #include #include -#include - ///////////////////////////////// QSE_BEGIN_NAMESPACE(QSE) @@ -39,7 +37,7 @@ QSE_BEGIN_NAMESPACE(QSE) template class LinkedList; template -class LinkedListNode: protected Mpoolable +class LinkedListNode { public: friend class LinkedList; @@ -84,7 +82,7 @@ protected: /// /// The LinkedList class provides a template for a doubly-linked list. /// -template class LinkedList +template class LinkedList: public Mmged { public: typedef LinkedList SelfType; @@ -100,14 +98,14 @@ public: this->clearout (); } - LinkedList (qse_size_t mpb_size = 0): mp (QSE_SIZEOF(Node), mpb_size) + LinkedList (Mmgr* mmgr = QSE_NULL, qse_size_t mpb_size = 0): Mmged(mmgr), mp (mmgr, QSE_SIZEOF(Node), mpb_size) { this->node_count = 0; this->head_node = QSE_NULL; this->tail_node = QSE_NULL; } - LinkedList (const SelfType& ll): mp (ll.mp.getDatumSize(), ll.mp.getBlockSize()) + LinkedList (const SelfType& ll): Mmged(ll.getMmgr()), mp (ll.getMmgr(), ll.mp.getDatumSize(), ll.mp.getBlockSize()) { this->node_count = 0; this->head_node = QSE_NULL; @@ -119,6 +117,7 @@ public: SelfType& operator= (const SelfType& ll) { this->clear (); + // note that the memory pool itself is not copied. for (Node* p = ll.head_node; p != QSE_NULL; p = p->next) this->append (p->value); return *this; @@ -172,7 +171,7 @@ public: // create a new node to hold the value and insert it. Node* insertValue (Node* pos, const T& value) { - Node* node = new(&mp) Node(value); + Node* node = new(&this->mp) Node(value); return this->insertNode (pos, node); } @@ -307,13 +306,8 @@ public: //call the destructor node->~Node (); - - // cal the deallocator - #if defined(_MSC_VER) - node->operator delete (node, &this->mp); - #else - node->dispose (node, &this->mp); - #endif + // free the memory + ::operator delete (node, &this->mp); } void remove (qse_size_t index) @@ -499,16 +493,9 @@ public: { saved = p->next; - if (this->mp.isDisabled()) delete p; - else - { - p->~Node (); - #if defined(_MSC_VER) - p->operator delete (p, &this->mp); - #else - p->dispose (p, &this->mp); - #endif - } + // placement new/delete handling + p->~Node (); // call the destructor + ::operator delete (p, &this->mp); // free the memory this->node_count--; p = saved; @@ -545,7 +532,6 @@ public: } protected: - //Mpool mp; MPOOL mp; Node* head_node; Node* tail_node; diff --git a/qse/include/qse/cmn/Mmged.hpp b/qse/include/qse/cmn/Mmged.hpp index 155c4a83..b7dbd7d7 100644 --- a/qse/include/qse/cmn/Mmged.hpp +++ b/qse/include/qse/cmn/Mmged.hpp @@ -41,7 +41,7 @@ QSE_BEGIN_NAMESPACE(QSE) class QSE_EXPORT Mmged { public: - Mmged (Mmgr* mmgr): mmgr(mmgr) {} + Mmged (Mmgr* mmgr = QSE_NULL); /// /// The getMmgr() function returns the memory manager associated. diff --git a/qse/include/qse/cmn/Mmgr.hpp b/qse/include/qse/cmn/Mmgr.hpp index c2599110..74223428 100644 --- a/qse/include/qse/cmn/Mmgr.hpp +++ b/qse/include/qse/cmn/Mmgr.hpp @@ -64,11 +64,11 @@ public: /// virtual ~Mmgr () {} -protected: +//protected: /// /// The allocMem() function allocates a chunk of memory of the - /// size @a n and return the pointer to the beginning of the chunk. - /// If it fails to allocate memory, it should return QSE_NULL. + /// size \a n and return the pointer to the beginning of the chunk. + /// If it fails to allocate memory, it should return #QSE_NULL. /// virtual void* allocMem ( qse_size_t n ///< size of memory chunk to allocate in bytes @@ -114,4 +114,10 @@ protected: 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); +void operator delete[] (void* ptr, QSE::Mmgr* mmgr); + #endif diff --git a/qse/include/qse/cmn/Mpool.hpp b/qse/include/qse/cmn/Mpool.hpp index 6f6aeefc..7e187321 100644 --- a/qse/include/qse/cmn/Mpool.hpp +++ b/qse/include/qse/cmn/Mpool.hpp @@ -28,7 +28,7 @@ #define _QSE_CMN_MPOOL_HPP_ #include -#include +#include ///////////////////////////////// QSE_BEGIN_NAMESPACE(QSE) @@ -38,7 +38,7 @@ QSE_BEGIN_NAMESPACE(QSE) // allocator for fixed-size data // -class QSE_EXPORT Mpool: public Uncopyable, protected ExcMmgr +class QSE_EXPORT Mpool: public Uncopyable, public Mmged { public: enum @@ -47,6 +47,7 @@ public: }; Mpool ( + Mmgr* mmgr, qse_size_t datum_size, qse_size_t block_size = DEFAULT_BLOCK_SIZE); ~Mpool (); @@ -107,5 +108,9 @@ protected: ///////////////////////////////// QSE_END_NAMESPACE(QSE) //////////////////////////////// + +void* operator new (qse_size_t size, QSE::Mpool* mp); +void operator delete (void* ptr, QSE::Mpool* mp); + #endif diff --git a/qse/lib/cmn/Makefile.am b/qse/lib/cmn/Makefile.am index c8d51c97..7d3d1c3d 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 Mpool.cpp + Mmgr.cpp StdMmgr.cpp ExcMmgr.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 ea58a835..ee7113e3 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 \ - Mpool.cpp + Mmged.cpp Mpool.cpp @ENABLE_CXX_TRUE@am_libqsecmnxx_la_OBJECTS = Mmgr.lo StdMmgr.lo \ -@ENABLE_CXX_TRUE@ ExcMmgr.lo Mpool.lo +@ENABLE_CXX_TRUE@ ExcMmgr.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 Mpool.cpp +@ENABLE_CXX_TRUE@ Mmgr.cpp StdMmgr.cpp ExcMmgr.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)/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@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/StdMmgr.Plo@am__quote@ diff --git a/qse/lib/cmn/Mmged.cpp b/qse/lib/cmn/Mmged.cpp new file mode 100644 index 00000000..29bc484a --- /dev/null +++ b/qse/lib/cmn/Mmged.cpp @@ -0,0 +1,41 @@ +/* + * $Id$ + * + Copyright (c) 2006-2014 Chung, Hyung-Hwan. All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR + IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include + +///////////////////////////////// +QSE_BEGIN_NAMESPACE(QSE) +///////////////////////////////// + +Mmged::Mmged (Mmgr* mmgr) +{ + if (!mmgr) mmgr = ExcMmgr::getDFL(); // TODO: use a different manager???? StdMmgr??? + this->mmgr = mmgr; +} +///////////////////////////////// +QSE_END_NAMESPACE(QSE) +///////////////////////////////// diff --git a/qse/lib/cmn/Mmgr.cpp b/qse/lib/cmn/Mmgr.cpp index eebcd618..b4b6de38 100644 --- a/qse/lib/cmn/Mmgr.cpp +++ b/qse/lib/cmn/Mmgr.cpp @@ -48,3 +48,25 @@ void Mmgr::free_mem (mmgr_t* mmgr, void* ptr) ///////////////////////////////// QSE_END_NAMESPACE(QSE) ///////////////////////////////// + +void* operator new (qse_size_t size, QSE::Mmgr* mmgr) +{ + return mmgr->allocMem (size); +} + +void operator delete (void* ptr, QSE::Mmgr* mmgr) +{ + mmgr->freeMem (ptr); +} + +#if 0 +void* operator new[] (qse_size_t size, QSE::Mmgr* mmgr) +{ + return mmgr->allocMem (size); +} + +void operator delete[] (void* ptr, QSE::Mmgr* mmgr) +{ + mmgr->freeMem (ptr); +} +#endif diff --git a/qse/lib/cmn/Mpool.cpp b/qse/lib/cmn/Mpool.cpp index 92630052..1805e478 100644 --- a/qse/lib/cmn/Mpool.cpp +++ b/qse/lib/cmn/Mpool.cpp @@ -31,7 +31,7 @@ QSE_BEGIN_NAMESPACE(QSE) ///////////////////////////////// -Mpool::Mpool (qse_size_t datum_size, qse_size_t block_size) +Mpool::Mpool (Mmgr* mmgr, qse_size_t datum_size, qse_size_t block_size): Mmged(mmgr) { if (datum_size > 0 && datum_size < QSE_SIZEOF(void*)) datum_size = QSE_SIZEOF(void*); @@ -87,7 +87,7 @@ void Mpool::dispose () Block* next = block->next; //::delete[] (qse_uint8_t*)block; - this->freeMem ((qse_uint8_t*)block); + this->mmgr->freeMem ((qse_uint8_t*)block); block = next; } @@ -107,7 +107,7 @@ Mpool::Block* Mpool::add_block () //Block* block = (Block*)::new qse_uint8_t[ // QSE_SIZEOF(Block) + this->block_size * this->datum_size]; - Block* block = (Block*)this->allocMem (QSE_SIZEOF(Block) + this->block_size * this->datum_size); + Block* block = (Block*)this->mmgr->allocMem (QSE_SIZEOF(Block) + this->block_size * this->datum_size); if (!block) return QSE_NULL; // this line may not be reached if the allocator raises an exception //this->free_list = (Chain*)block->data; @@ -135,3 +135,14 @@ Mpool::Block* Mpool::add_block () ///////////////////////////////// QSE_END_NAMESPACE(QSE) ///////////////////////////////// + +void* operator new (qse_size_t size, QSE::Mpool* mp) +{ + return mp->isEnabled()? mp->allocate (): ::operator new (size, mp->getMmgr()); +} + +void operator delete (void* ptr, QSE::Mpool* mp) +{ + if (mp->isEnabled()) mp->dispose (ptr); + else ::operator delete (ptr, mp->getMmgr()); +} diff --git a/qse/lib/cmn/StdMmgr.cpp b/qse/lib/cmn/StdMmgr.cpp index 2fddf878..5cddb6ca 100644 --- a/qse/lib/cmn/StdMmgr.cpp +++ b/qse/lib/cmn/StdMmgr.cpp @@ -43,7 +43,7 @@ void* StdMmgr::reallocMem (void* ptr, qse_size_t n) } void StdMmgr::freeMem (void* ptr) -{ +{ ::free (ptr); }