From 8d88ef3f40c5d6dbb1f88ea1693cbbdf250828d1 Mon Sep 17 00:00:00 2001 From: hyung-hwan Date: Mon, 5 Jan 2015 04:15:32 +0000 Subject: [PATCH] added ExcMmgr simplified LinkedList --- qse/include/qse/awk/Awk.hpp | 3 +- qse/include/qse/cmn/ExcMmgr.hpp | 54 +++++++++++ qse/include/qse/cmn/LinkedList.hpp | 148 +++++++++++++++-------------- qse/include/qse/cmn/Makefile.am | 2 +- qse/include/qse/cmn/Makefile.in | 6 +- qse/include/qse/cmn/Mmged.hpp | 11 ++- qse/include/qse/cmn/Mmgr.hpp | 13 +-- qse/include/qse/cmn/Mpool.hpp | 12 ++- qse/include/qse/cmn/Mpoolable.hpp | 18 ++-- qse/include/qse/cmn/StdMmgr.hpp | 10 +- qse/include/qse/sed/Sed.hpp | 3 +- qse/lib/cmn/ExcMmgr.cpp | 63 ++++++++++++ qse/lib/cmn/Makefile.am | 2 +- qse/lib/cmn/Makefile.in | 8 +- qse/lib/cmn/Mmgr.cpp | 4 +- qse/lib/cmn/Mpool.cpp | 28 ++++-- qse/lib/cmn/StdMmgr.cpp | 6 +- 17 files changed, 274 insertions(+), 117 deletions(-) create mode 100644 qse/include/qse/cmn/ExcMmgr.hpp create mode 100644 qse/lib/cmn/ExcMmgr.cpp diff --git a/qse/include/qse/awk/Awk.hpp b/qse/include/qse/awk/Awk.hpp index 105ce593..f789b921 100644 --- a/qse/include/qse/awk/Awk.hpp +++ b/qse/include/qse/awk/Awk.hpp @@ -30,6 +30,7 @@ #include #include #include +#include #include #include @@ -44,7 +45,7 @@ QSE_BEGIN_NAMESPACE(QSE) /// The Awk class implements an AWK interpreter by wrapping around /// #qse_awk_t and #qse_awk_rtx_t. /// -class QSE_EXPORT Awk: public Mmged +class QSE_EXPORT Awk: public Types, public Mmged { public: typedef qse_htb_t htb_t; diff --git a/qse/include/qse/cmn/ExcMmgr.hpp b/qse/include/qse/cmn/ExcMmgr.hpp new file mode 100644 index 00000000..884a185b --- /dev/null +++ b/qse/include/qse/cmn/ExcMmgr.hpp @@ -0,0 +1,54 @@ +/* + * $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. + */ + +#ifndef _QSE_CMN_STDMMGR_HPP_ +#define _QSE_CMN_STDMMGR_HPP_ + +#include + +///////////////////////////////// +QSE_BEGIN_NAMESPACE(QSE) +///////////////////////////////// + +/// The ExcMmgr class implements the memory manager interface that +/// raises an exception upon failure. You can use the StdMmgr class +/// if #QSE_NULL should be returned upon failure. + +class QSE_EXPORT ExcMmgr: public Mmgr +{ +public: + void* allocMem (qse_size_t n); + void* reallocMem (void* ptr, qse_size_t n); + void freeMem (void* ptr); + + static ExcMmgr* getDFL(); +}; + +///////////////////////////////// +QSE_END_NAMESPACE(QSE) +///////////////////////////////// + +#endif diff --git a/qse/include/qse/cmn/LinkedList.hpp b/qse/include/qse/cmn/LinkedList.hpp index e4984f13..efdb1e86 100644 --- a/qse/include/qse/cmn/LinkedList.hpp +++ b/qse/include/qse/cmn/LinkedList.hpp @@ -28,44 +28,54 @@ #define _QSE_CMN_LINKEDLIST_HPP_ #include -#include -#include +#include +#include ///////////////////////////////// QSE_BEGIN_NAMESPACE(QSE) ///////////////////////////////// -template class LinkedList; +template class LinkedList; -template -class LinkedListNode: protected MemoryPoolable +template +class LinkedListNode: protected Mpoolable { public: - friend class LinkedList; + friend class LinkedList; + typedef LinkedListNode Node; - T value; + T value; // you can use this variable or accessor functions below protected: - LinkedListNode* next; - LinkedListNode* prev; + Node* next; + Node* prev; public: - LinkedListNode* getNext () { return this->next; } - const LinkedListNode* getNext () const { return this->next; } + T& getValue () { return this->value; } + const T& getValue () const { return this->value; } + void setValue (const T& v) { this->value = v; } - LinkedListNode* getPrev () { return this->prev; } - const LinkedListNode* getPrev () const { return this->prev; } + Node* getNext () { return this->next; } + const Node* getNext () const { return this->next; } + Node* getNextNode () { return this->next; } + const Node* getNextNode () const { return this->next; } + + Node* getPrev () { return this->prev; } + const Node* getPrev () const { return this->prev; } + Node* getPrevNode () { return this->prev; } + const Node* getPrevNode () const { return this->prev; } protected: - LinkedListNode () {} - LinkedListNode (const T& v): value(v) {} + LinkedListNode (): prev(QSE_NULL), next(QSE_NULL) {} + LinkedListNode (const T& v): value(v), prev(QSE_NULL), next(QSE_NULL) {} - void setNext (const LinkedListNode* node) + void setNext (const Node* node) { this->next = node; } - void setPrev (const LinkedListNode* node) + + void setPrev (const Node* node) { this->prev = node; } @@ -74,10 +84,10 @@ protected: /// /// The LinkedList class provides a template for a doubly-linked list. /// -template class LinkedList +template class LinkedList { public: - typedef LinkedListNode Node; + typedef LinkedListNode Node; enum { @@ -96,7 +106,7 @@ public: this->tail_node = QSE_NULL; } - LinkedList (const LinkedList& ll): mp (ll.mp.datumSize(), ll.mp.blockSize()) + LinkedList (const LinkedList& ll): mp (ll.mp.getDatumSize(), ll.mp.getBlockSize()) { this->node_count = 0; this->head_node = QSE_NULL; @@ -161,9 +171,8 @@ public: // create a new node to hold the value and insert it. Node* insertValue (Node* pos, const T& value) { - Node* n = this->mp.isEnabled()? - (new(&mp) Node(value)): (new Node(value)); - return this->insertNode (pos, n); + Node* node = new(&mp) Node(value); + return this->insertNode (pos, node); } T& insert (Node* node, const T& value) @@ -186,10 +195,12 @@ public: T& prepend (const T& value) { + // same as prependValue() return this->insert (this->head_node, value); } T& append (const T& value) { + // same as appendValue() return this->insert ((Node*)QSE_NULL, value); } @@ -263,22 +274,45 @@ public: // take extra care when using this method as the node // can be freed through the memory pool when the list is // destructed if the memory pool is enabled. - Node* yield (Node* node, bool clear_links = true); + Node* yield (Node* node, bool clear_links = true) + { + QSE_ASSERT (node != QSE_NULL); + QSE_ASSERT (this->node_count > 0); + if (node->next) + node->next->prev = node->next; + else + this->tail_node = node->prev; + + if (node->prev) + node->prev->next = node->next; + else + this->head_node = node->next; + + this->node_count--; + + if (clear_links) + { + node->next = QSE_NULL; + node->prev = QSE_NULL; + } + + return node; + } // remove a node from the list and free it. void remove (Node* node) { this->yield (node, false); - if (mp.isDisabled()) delete node; - else - { - node->~Node (); - #if defined(_MSC_VER) - node->operator delete (node, &mp); - #else - node->dispose (node, &mp); - #endif - } + + //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 } void remove (qse_size_t index) @@ -298,17 +332,17 @@ public: Node* yieldByValue (const T& value, bool clear_links = true) { Node* p = this->findFirstNode (value); - Node* p = this->findFirstNode (value); - if (p == QSE_NULL) return -1; + if (!p) return QSE_NULL; return this->yield (p, clear_links); } + /// \return the number of items deleted. qse_size_t removeByValue (const T& value) { Node* p = this->findFirstNode (value); if (!p) return 0; this->remove (p); - return 1; + return 1; } /// \return the number of items deleted @@ -463,15 +497,15 @@ public: while (p) { saved = p->next; - + if (this->mp.isDisabled()) delete p; else { p->~Node (); #if defined(_MSC_VER) - p->operator delete (p, &mp); + p->operator delete (p, &this->mp); #else - p->dispose (p, &mp); + p->dispose (p, &this->mp); #endif } @@ -510,14 +544,15 @@ public: } protected: - MemoryPool mp; + //Mpool mp; + MPOOL mp; Node* head_node; Node* tail_node; qse_size_t node_count; }; -template -inline typename LinkedList::Node* LinkedList::insertNode (Node* pos, Node* node) +template +inline typename LinkedList::Node* LinkedList::insertNode (Node* pos, Node* node) { if (pos == QSE_NULL) { @@ -544,33 +579,6 @@ inline typename LinkedList::Node* LinkedList::insertNode (Node* pos, Node* } this->node_count++; - return n; -} - -template -inline typename LinkedList::Node* LinkedList::yield (Node* node, bool clear_links) -{ - QSE_ASSERT (node != QSE_NULL); - QSE_ASSERT (this->node_count > 0); - - if (node->next) - node->next->prev = node->next; - else - this->tail_node = node->prev; - - if (node->prev) - node->prev->next = node->next; - else - this->head_node = node->next; - - this->node_count--; - - if (clear_links) - { - node->next = QSE_NULL; - node->prev = QSE_NULL; - } - return node; } diff --git a/qse/include/qse/cmn/Makefile.am b/qse/include/qse/cmn/Makefile.am index 03f311db..66578dac 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 Mmged.hpp Mpool.hpp Mpoolable.hpp \ + Mmgr.hpp StdMmgr.hpp ExcMmgr.hpp Mmged.hpp Mpool.hpp Mpoolable.hpp \ LinkedList.hpp endif diff --git a/qse/include/qse/cmn/Makefile.in b/qse/include/qse/cmn/Makefile.in index 689e69a1..1050dc8f 100644 --- a/qse/include/qse/cmn/Makefile.in +++ b/qse/include/qse/cmn/Makefile.in @@ -51,7 +51,7 @@ POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ @ENABLE_CXX_TRUE@am__append_1 = \ -@ENABLE_CXX_TRUE@ Mmgr.hpp StdMmgr.hpp Mmged.hpp Mpool.hpp Mpoolable.hpp \ +@ENABLE_CXX_TRUE@ Mmgr.hpp StdMmgr.hpp ExcMmgr.hpp Mmged.hpp Mpool.hpp Mpoolable.hpp \ @ENABLE_CXX_TRUE@ LinkedList.hpp subdir = include/qse/cmn @@ -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 Mmged.hpp Mpool.hpp \ - Mpoolable.hpp LinkedList.hpp + utf8.h xma.h Mmgr.hpp StdMmgr.hpp ExcMmgr.hpp Mmged.hpp \ + Mpool.hpp Mpoolable.hpp LinkedList.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/Mmged.hpp b/qse/include/qse/cmn/Mmged.hpp index e3c8531e..3b049555 100644 --- a/qse/include/qse/cmn/Mmged.hpp +++ b/qse/include/qse/cmn/Mmged.hpp @@ -27,8 +27,8 @@ #ifndef _QSE_CMN_MMGED_HPP_ #define _QSE_CMN_MMGED_HPP_ -#include #include +#include ///////////////////////////////// QSE_BEGIN_NAMESPACE(QSE) @@ -39,15 +39,18 @@ QSE_BEGIN_NAMESPACE(QSE) /// a subclass that uses a memory manager. /// -class QSE_EXPORT Mmged: public Types +class QSE_EXPORT Mmged { public: - Mmged (Mmgr* mmgr): mmgr (mmgr) {} + Mmged (Mmgr* mmgr): mmgr(mmgr) {} /// /// The getMmgr() function returns the memory manager associated. /// - Mmgr* getMmgr () const { return mmgr; } + Mmgr* getMmgr () const { return this->mmgr; } + + + protected: Mmgr* mmgr; diff --git a/qse/include/qse/cmn/Mmgr.hpp b/qse/include/qse/cmn/Mmgr.hpp index f703b9b2..c2599110 100644 --- a/qse/include/qse/cmn/Mmgr.hpp +++ b/qse/include/qse/cmn/Mmgr.hpp @@ -27,7 +27,8 @@ #ifndef _QSE_CMN_MMGR_HPP_ #define _QSE_CMN_MMGR_HPP_ -#include +#include +#include ///////////////////////////////// QSE_BEGIN_NAMESPACE(QSE) @@ -40,7 +41,7 @@ QSE_BEGIN_NAMESPACE(QSE) /// write code in more object-oriented fashion. An inheriting class should /// implement three pure virtual functions. /// -class QSE_EXPORT Mmgr: public Types, public qse_mmgr_t +class QSE_EXPORT Mmgr: public qse_mmgr_t { public: /// defines an alias type to #qse_mmgr_t @@ -70,7 +71,7 @@ protected: /// If it fails to allocate memory, it should return QSE_NULL. /// virtual void* allocMem ( - size_t n ///< size of memory chunk to allocate in bytes + qse_size_t n ///< size of memory chunk to allocate in bytes ) = 0; /// @@ -81,7 +82,7 @@ protected: /// virtual void* reallocMem ( void* ptr, ///< pointer to memory chunk to resize - size_t n ///< new size in bytes + qse_size_t n ///< new size in bytes ) = 0; /// @@ -96,12 +97,12 @@ protected: /// /// bridge function from the #qse_mmgr_t type the allocMem() function. /// - static void* alloc_mem (mmgr_t* mmgr, size_t n); + static void* alloc_mem (mmgr_t* mmgr, qse_size_t n); /// /// bridge function from the #qse_mmgr_t type the reallocMem() function. /// - static void* realloc_mem (mmgr_t* mmgr, void* ptr, size_t n); + static void* realloc_mem (mmgr_t* mmgr, void* ptr, qse_size_t n); /// /// bridge function from the #qse_mmgr_t type the freeMem() function. diff --git a/qse/include/qse/cmn/Mpool.hpp b/qse/include/qse/cmn/Mpool.hpp index b9de66c9..6f6aeefc 100644 --- a/qse/include/qse/cmn/Mpool.hpp +++ b/qse/include/qse/cmn/Mpool.hpp @@ -28,6 +28,7 @@ #define _QSE_CMN_MPOOL_HPP_ #include +#include ///////////////////////////////// QSE_BEGIN_NAMESPACE(QSE) @@ -37,7 +38,7 @@ QSE_BEGIN_NAMESPACE(QSE) // allocator for fixed-size data // -class Mpool: public Uncopyable +class QSE_EXPORT Mpool: public Uncopyable, protected ExcMmgr { public: enum @@ -63,14 +64,16 @@ public: return this->datum_size <= 0 || this->block_size <= 0; } - inline qse_size_t datumSize () const + inline qse_size_t getDatumSize () const { return this->datum_size; } - inline qse_size_t blockSize () const + + inline qse_size_t getBlockSize () const { return this->block_size; } + inline void setBlockSize (qse_size_t blockSize) { this->block_size = blockSize; @@ -87,6 +90,7 @@ protected: Block* next; //qse_uint8_t data[0]; }; + struct Chain { Chain* next; @@ -97,7 +101,7 @@ protected: qse_size_t datum_size; qse_size_t block_size; - void add_block (); + Block* add_block (); }; ///////////////////////////////// diff --git a/qse/include/qse/cmn/Mpoolable.hpp b/qse/include/qse/cmn/Mpoolable.hpp index d3965db7..a221859b 100644 --- a/qse/include/qse/cmn/Mpoolable.hpp +++ b/qse/include/qse/cmn/Mpoolable.hpp @@ -29,15 +29,18 @@ #include +// use size_t as some compilers complain about qse_size_t used in new(). +#include + ///////////////////////////////// QSE_BEGIN_NAMESPACE(QSE) ///////////////////////////////// -class Mpoolable +class QSE_EXPORT Mpoolable { public: - typedef qse_size_t mp_size_t; +/* inline void* operator new (mp_size_t size) { return ::operator new (size); @@ -47,21 +50,24 @@ public: { ::operator delete (ptr); } +*/ - inline void* operator new (mp_size_t /*size*/, Mpool* mp) + inline void* operator new (size_t size, Mpool* mp) { - return mp->allocate (); + return mp->isEnabled()? mp->allocate (): ::operator new (size); } #if defined(_MSC_VER) void operator delete (void* ptr, Mpool* mp) { - mp->dispose (ptr); + if (mp->isEnabled()) mp->dispose (ptr); + else ::operator delete (mp); } #else inline void dispose (void* ptr, Mpool* mp) { - mp->dispose (ptr); + if (mp->isEnabled()) mp->dispose (ptr); + else ::operator delete (mp); } #endif }; diff --git a/qse/include/qse/cmn/StdMmgr.hpp b/qse/include/qse/cmn/StdMmgr.hpp index 2989e047..6ce7e1e3 100644 --- a/qse/include/qse/cmn/StdMmgr.hpp +++ b/qse/include/qse/cmn/StdMmgr.hpp @@ -33,12 +33,16 @@ QSE_BEGIN_NAMESPACE(QSE) ///////////////////////////////// +/// The StdMmgr class implements the memory manager interface. +/// It doesn't raise an exception upon failure. If you want an exception +/// to be raised, use the ExcMmgr class instead. + class QSE_EXPORT StdMmgr: public Mmgr { public: - void* allocMem (size_t n); - void* reallocMem (void* ptr, size_t n); - virtual void freeMem (void* ptr); + void* allocMem (qse_size_t n); + void* reallocMem (void* ptr, qse_size_t n); + void freeMem (void* ptr); static StdMmgr* getDFL(); }; diff --git a/qse/include/qse/sed/Sed.hpp b/qse/include/qse/sed/Sed.hpp index 68c610ff..1779ae32 100644 --- a/qse/include/qse/sed/Sed.hpp +++ b/qse/include/qse/sed/Sed.hpp @@ -27,6 +27,7 @@ #ifndef _QSE_SED_SED_HPP_ #define _QSE_SED_SED_HPP_ +#include #include #include @@ -45,7 +46,7 @@ QSE_BEGIN_NAMESPACE(QSE) /// /// The Sed class implements a stream editor by wrapping around #qse_sed_t. /// -class QSE_EXPORT Sed: public Mmged +class QSE_EXPORT Sed: public Types, public Mmged { public: /// The sed_t type redefines a stream editor type diff --git a/qse/lib/cmn/ExcMmgr.cpp b/qse/lib/cmn/ExcMmgr.cpp new file mode 100644 index 00000000..a3349d41 --- /dev/null +++ b/qse/lib/cmn/ExcMmgr.cpp @@ -0,0 +1,63 @@ +/* + * $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 +#include + +///////////////////////////////// +QSE_BEGIN_NAMESPACE(QSE) +///////////////////////////////// + + +void* ExcMmgr::allocMem (qse_size_t n) +{ + void* ptr = ::malloc (n); + if (!ptr) throw 1; // TODO: change 1 to a proper exception object + return ptr; +} + +void* ExcMmgr::reallocMem (void* ptr, qse_size_t n) +{ + void* xptr = ::realloc (ptr, n); + if (!xptr) throw 1; + return xptr; +} + +void ExcMmgr::freeMem (void* ptr) +{ + ::free (ptr); +} + +ExcMmgr* ExcMmgr::getDFL () +{ + static ExcMmgr DFL; + return &DFL; +} + +///////////////////////////////// +QSE_END_NAMESPACE(QSE) +///////////////////////////////// diff --git a/qse/lib/cmn/Makefile.am b/qse/lib/cmn/Makefile.am index 7ef4c314..c8d51c97 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 Mpool.cpp + Mmgr.cpp StdMmgr.cpp ExcMmgr.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 2ef65003..ea58a835 100644 --- a/qse/lib/cmn/Makefile.in +++ b/qse/lib/cmn/Makefile.in @@ -149,9 +149,10 @@ libqsecmn_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(libqsecmn_la_LDFLAGS) $(LDFLAGS) -o $@ libqsecmnxx_la_DEPENDENCIES = -am__libqsecmnxx_la_SOURCES_DIST = Mmgr.cpp StdMmgr.cpp Mpool.cpp +am__libqsecmnxx_la_SOURCES_DIST = Mmgr.cpp StdMmgr.cpp ExcMmgr.cpp \ + Mpool.cpp @ENABLE_CXX_TRUE@am_libqsecmnxx_la_OBJECTS = Mmgr.lo StdMmgr.lo \ -@ENABLE_CXX_TRUE@ Mpool.lo +@ENABLE_CXX_TRUE@ ExcMmgr.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) \ @@ -434,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 Mpool.cpp +@ENABLE_CXX_TRUE@ Mmgr.cpp StdMmgr.cpp ExcMmgr.cpp Mpool.cpp @ENABLE_CXX_TRUE@libqsecmnxx_la_LDFLAGS = -version-info 1:0:0 -no-undefined @ENABLE_CXX_TRUE@libqsecmnxx_la_LIBADD = @@ -515,6 +516,7 @@ mostlyclean-compile: distclean-compile: -rm -f *.tab.c +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ExcMmgr.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/Mmgr.cpp b/qse/lib/cmn/Mmgr.cpp index c0ca7887..eebcd618 100644 --- a/qse/lib/cmn/Mmgr.cpp +++ b/qse/lib/cmn/Mmgr.cpp @@ -30,12 +30,12 @@ QSE_BEGIN_NAMESPACE(QSE) ///////////////////////////////// -void* Mmgr::alloc_mem (mmgr_t* mmgr, size_t n) +void* Mmgr::alloc_mem (mmgr_t* mmgr, qse_size_t n) { return ((Mmgr*)mmgr->ctx)->allocMem (n); } -void* Mmgr::realloc_mem (mmgr_t* mmgr, void* ptr, size_t n) +void* Mmgr::realloc_mem (mmgr_t* mmgr, void* ptr, qse_size_t n) { return ((Mmgr*)mmgr->ctx)->reallocMem (ptr, n); } diff --git a/qse/lib/cmn/Mpool.cpp b/qse/lib/cmn/Mpool.cpp index a91159cf..92630052 100644 --- a/qse/lib/cmn/Mpool.cpp +++ b/qse/lib/cmn/Mpool.cpp @@ -25,9 +25,7 @@ */ #include - - -// TODO: can i use QSE_MMGR_XXXXX instead of ::new and ::delete??? +#include ///////////////////////////////// QSE_BEGIN_NAMESPACE(QSE) @@ -47,6 +45,7 @@ Mpool::Mpool (qse_size_t datum_size, qse_size_t block_size) this->nalloc = 0; #endif } + Mpool::~Mpool () { this->dispose (); @@ -59,7 +58,9 @@ void* Mpool::allocate () void* ptr = this->free_list; if (!ptr) { - this->add_block (); + // NOTE: 'return QSE_NULL' can't be reached if add_block() + // raises an exception. + if (!this->add_block ()) return QSE_NULL; ptr = this->free_list; } this->free_list = this->free_list->next; @@ -84,24 +85,30 @@ void Mpool::dispose () while (block) { Block* next = block->next; - ::delete[] block; + + //::delete[] (qse_uint8_t*)block; + this->freeMem ((qse_uint8_t*)block); + block = next; } this->free_list = QSE_NULL; this->mp_blocks = QSE_NULL; + #if defined(QSE_DEBUG_MPOOL) this->navail = 0; this->nalloc = 0; #endif } -void Mpool::add_block () +Mpool::Block* Mpool::add_block () { QSE_ASSERT (this->datum_size > 0 && this->block_size > 0); - Block* block = (Block*)::new qse_uint8_t[ - QSE_SIZEOF(Block) + this->block_size * this->datum_size]; + //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); + if (!block) return QSE_NULL; // this line may not be reached if the allocator raises an exception //this->free_list = (Chain*)block->data; this->free_list = (Chain*)(block + 1); @@ -114,12 +121,15 @@ void Mpool::add_block () } ptr->next = QSE_NULL; - block->next = this->mp_blocks; + block->next = this->mp_blocks; this->mp_blocks = block; + #if defined(QSE_DEBUG_MPOOL) this->navail += this->block_size; this->nalloc += this->block_size; #endif + + return block; } ///////////////////////////////// diff --git a/qse/lib/cmn/StdMmgr.cpp b/qse/lib/cmn/StdMmgr.cpp index de53fea7..2fddf878 100644 --- a/qse/lib/cmn/StdMmgr.cpp +++ b/qse/lib/cmn/StdMmgr.cpp @@ -32,12 +32,12 @@ QSE_BEGIN_NAMESPACE(QSE) ///////////////////////////////// -void* StdMmgr::allocMem (size_t n) +void* StdMmgr::allocMem (qse_size_t n) { - return ::malloc (n); + return ::malloc (n); } -void* StdMmgr::reallocMem (void* ptr, size_t n) +void* StdMmgr::reallocMem (void* ptr, qse_size_t n) { return ::realloc (ptr, n); }