added ExcMmgr

simplified LinkedList
This commit is contained in:
hyung-hwan 2015-01-05 04:15:32 +00:00
parent 3b672857aa
commit 8d88ef3f40
17 changed files with 274 additions and 117 deletions

View File

@ -30,6 +30,7 @@
#include <qse/awk/awk.h> #include <qse/awk/awk.h>
#include <qse/cmn/htb.h> #include <qse/cmn/htb.h>
#include <qse/cmn/chr.h> #include <qse/cmn/chr.h>
#include <qse/Types.hpp>
#include <qse/cmn/Mmged.hpp> #include <qse/cmn/Mmged.hpp>
#include <stdarg.h> #include <stdarg.h>
@ -44,7 +45,7 @@ QSE_BEGIN_NAMESPACE(QSE)
/// The Awk class implements an AWK interpreter by wrapping around /// The Awk class implements an AWK interpreter by wrapping around
/// #qse_awk_t and #qse_awk_rtx_t. /// #qse_awk_t and #qse_awk_rtx_t.
/// ///
class QSE_EXPORT Awk: public Mmged class QSE_EXPORT Awk: public Types, public Mmged
{ {
public: public:
typedef qse_htb_t htb_t; typedef qse_htb_t htb_t;

View File

@ -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/cmn/Mmgr.hpp>
/////////////////////////////////
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

View File

@ -28,44 +28,54 @@
#define _QSE_CMN_LINKEDLIST_HPP_ #define _QSE_CMN_LINKEDLIST_HPP_
#include <qse/Types.hpp> #include <qse/Types.hpp>
#include <xp/bas/MemoryPool.hpp> #include <qse/cmn/Mpool.hpp>
#include <xp/bas/MemoryPoolable.hpp> #include <qse/cmn/Mpoolable.hpp>
///////////////////////////////// /////////////////////////////////
QSE_BEGIN_NAMESPACE(QSE) QSE_BEGIN_NAMESPACE(QSE)
///////////////////////////////// /////////////////////////////////
template <typename T> class LinkedList; template <typename T, typename MPOOL> class LinkedList;
template <typename T> template <typename T,typename MPOOL>
class LinkedListNode: protected MemoryPoolable class LinkedListNode: protected Mpoolable
{ {
public: public:
friend class LinkedList<T>; friend class LinkedList<T,MPOOL>;
typedef LinkedListNode<T,MPOOL> Node;
T value; T value; // you can use this variable or accessor functions below
protected: protected:
LinkedListNode<T>* next; Node* next;
LinkedListNode<T>* prev; Node* prev;
public: public:
LinkedListNode<T>* getNext () { return this->next; } T& getValue () { return this->value; }
const LinkedListNode<T>* getNext () const { return this->next; } const T& getValue () const { return this->value; }
void setValue (const T& v) { this->value = v; }
LinkedListNode<T>* getPrev () { return this->prev; } Node* getNext () { return this->next; }
const LinkedListNode<T>* getPrev () const { return this->prev; } 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: protected:
LinkedListNode () {} LinkedListNode (): prev(QSE_NULL), next(QSE_NULL) {}
LinkedListNode (const T& v): value(v) {} LinkedListNode (const T& v): value(v), prev(QSE_NULL), next(QSE_NULL) {}
void setNext (const LinkedListNode<T>* node) void setNext (const Node* node)
{ {
this->next = node; this->next = node;
} }
void setPrev (const LinkedListNode<T>* node)
void setPrev (const Node* node)
{ {
this->prev = node; this->prev = node;
} }
@ -74,10 +84,10 @@ protected:
/// ///
/// The LinkedList<T> class provides a template for a doubly-linked list. /// The LinkedList<T> class provides a template for a doubly-linked list.
/// ///
template <typename T> class LinkedList template <typename T, typename MPOOL = Mpool> class LinkedList
{ {
public: public:
typedef LinkedListNode<T> Node; typedef LinkedListNode<T,MPOOL> Node;
enum enum
{ {
@ -96,7 +106,7 @@ public:
this->tail_node = QSE_NULL; this->tail_node = QSE_NULL;
} }
LinkedList (const LinkedList<T>& ll): mp (ll.mp.datumSize(), ll.mp.blockSize()) LinkedList (const LinkedList<T>& ll): mp (ll.mp.getDatumSize(), ll.mp.getBlockSize())
{ {
this->node_count = 0; this->node_count = 0;
this->head_node = QSE_NULL; this->head_node = QSE_NULL;
@ -161,9 +171,8 @@ public:
// create a new node to hold the value and insert it. // create a new node to hold the value and insert it.
Node* insertValue (Node* pos, const T& value) Node* insertValue (Node* pos, const T& value)
{ {
Node* n = this->mp.isEnabled()? Node* node = new(&mp) Node(value);
(new(&mp) Node(value)): (new Node(value)); return this->insertNode (pos, node);
return this->insertNode (pos, n);
} }
T& insert (Node* node, const T& value) T& insert (Node* node, const T& value)
@ -186,10 +195,12 @@ public:
T& prepend (const T& value) T& prepend (const T& value)
{ {
// same as prependValue()
return this->insert (this->head_node, value); return this->insert (this->head_node, value);
} }
T& append (const T& value) T& append (const T& value)
{ {
// same as appendValue()
return this->insert ((Node*)QSE_NULL, value); return this->insert ((Node*)QSE_NULL, value);
} }
@ -263,22 +274,45 @@ public:
// take extra care when using this method as the node // take extra care when using this method as the node
// can be freed through the memory pool when the list is // can be freed through the memory pool when the list is
// destructed if the memory pool is enabled. // 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. // remove a node from the list and free it.
void remove (Node* node) void remove (Node* node)
{ {
this->yield (node, false); this->yield (node, false);
if (mp.isDisabled()) delete node;
else //call the destructor
{ node->~Node ();
node->~Node ();
#if defined(_MSC_VER) // cal the deallocator
node->operator delete (node, &mp); #if defined(_MSC_VER)
#else node->operator delete (node, &this->mp);
node->dispose (node, &mp); #else
#endif node->dispose (node, &this->mp);
} #endif
} }
void remove (qse_size_t index) void remove (qse_size_t index)
@ -298,17 +332,17 @@ public:
Node* yieldByValue (const T& value, bool clear_links = true) Node* yieldByValue (const T& value, bool clear_links = true)
{ {
Node* p = this->findFirstNode (value); Node* p = this->findFirstNode (value);
Node* p = this->findFirstNode (value); if (!p) return QSE_NULL;
if (p == QSE_NULL) return -1;
return this->yield (p, clear_links); return this->yield (p, clear_links);
} }
/// \return the number of items deleted.
qse_size_t removeByValue (const T& value) qse_size_t removeByValue (const T& value)
{ {
Node* p = this->findFirstNode (value); Node* p = this->findFirstNode (value);
if (!p) return 0; if (!p) return 0;
this->remove (p); this->remove (p);
return 1; return 1;
} }
/// \return the number of items deleted /// \return the number of items deleted
@ -463,15 +497,15 @@ public:
while (p) while (p)
{ {
saved = p->next; saved = p->next;
if (this->mp.isDisabled()) delete p; if (this->mp.isDisabled()) delete p;
else else
{ {
p->~Node (); p->~Node ();
#if defined(_MSC_VER) #if defined(_MSC_VER)
p->operator delete (p, &mp); p->operator delete (p, &this->mp);
#else #else
p->dispose (p, &mp); p->dispose (p, &this->mp);
#endif #endif
} }
@ -510,14 +544,15 @@ public:
} }
protected: protected:
MemoryPool mp; //Mpool mp;
MPOOL mp;
Node* head_node; Node* head_node;
Node* tail_node; Node* tail_node;
qse_size_t node_count; qse_size_t node_count;
}; };
template <typename T> template <typename T,typename MPOOL>
inline typename LinkedList<T>::Node* LinkedList<T>::insertNode (Node* pos, Node* node) inline typename LinkedList<T,MPOOL>::Node* LinkedList<T,MPOOL>::insertNode (Node* pos, Node* node)
{ {
if (pos == QSE_NULL) if (pos == QSE_NULL)
{ {
@ -544,33 +579,6 @@ inline typename LinkedList<T>::Node* LinkedList<T>::insertNode (Node* pos, Node*
} }
this->node_count++; this->node_count++;
return n;
}
template <typename T>
inline typename LinkedList<T>::Node* LinkedList<T>::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; return node;
} }

View File

@ -51,7 +51,7 @@ pkginclude_HEADERS = \
if ENABLE_CXX if ENABLE_CXX
pkginclude_HEADERS += \ 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 LinkedList.hpp
endif endif

View File

@ -51,7 +51,7 @@ POST_UNINSTALL = :
build_triplet = @build@ build_triplet = @build@
host_triplet = @host@ host_triplet = @host@
@ENABLE_CXX_TRUE@am__append_1 = \ @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 @ENABLE_CXX_TRUE@ LinkedList.hpp
subdir = include/qse/cmn 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 \ 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 \ 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 \ 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 \ utf8.h xma.h Mmgr.hpp StdMmgr.hpp ExcMmgr.hpp Mmged.hpp \
Mpoolable.hpp LinkedList.hpp Mpool.hpp Mpoolable.hpp LinkedList.hpp
am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
am__vpath_adj = case $$p in \ am__vpath_adj = case $$p in \
$(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \

View File

@ -27,8 +27,8 @@
#ifndef _QSE_CMN_MMGED_HPP_ #ifndef _QSE_CMN_MMGED_HPP_
#define _QSE_CMN_MMGED_HPP_ #define _QSE_CMN_MMGED_HPP_
#include <qse/Types.hpp>
#include <qse/cmn/Mmgr.hpp> #include <qse/cmn/Mmgr.hpp>
#include <qse/cmn/StdMmgr.hpp>
///////////////////////////////// /////////////////////////////////
QSE_BEGIN_NAMESPACE(QSE) QSE_BEGIN_NAMESPACE(QSE)
@ -39,15 +39,18 @@ QSE_BEGIN_NAMESPACE(QSE)
/// a subclass that uses a memory manager. /// a subclass that uses a memory manager.
/// ///
class QSE_EXPORT Mmged: public Types class QSE_EXPORT Mmged
{ {
public: public:
Mmged (Mmgr* mmgr): mmgr (mmgr) {} Mmged (Mmgr* mmgr): mmgr(mmgr) {}
/// ///
/// The getMmgr() function returns the memory manager associated. /// The getMmgr() function returns the memory manager associated.
/// ///
Mmgr* getMmgr () const { return mmgr; } Mmgr* getMmgr () const { return this->mmgr; }
protected: protected:
Mmgr* mmgr; Mmgr* mmgr;

View File

@ -27,7 +27,8 @@
#ifndef _QSE_CMN_MMGR_HPP_ #ifndef _QSE_CMN_MMGR_HPP_
#define _QSE_CMN_MMGR_HPP_ #define _QSE_CMN_MMGR_HPP_
#include <qse/Types.hpp> #include <qse/types.h>
#include <qse/macros.h>
///////////////////////////////// /////////////////////////////////
QSE_BEGIN_NAMESPACE(QSE) QSE_BEGIN_NAMESPACE(QSE)
@ -40,7 +41,7 @@ QSE_BEGIN_NAMESPACE(QSE)
/// write code in more object-oriented fashion. An inheriting class should /// write code in more object-oriented fashion. An inheriting class should
/// implement three pure virtual functions. /// implement three pure virtual functions.
/// ///
class QSE_EXPORT Mmgr: public Types, public qse_mmgr_t class QSE_EXPORT Mmgr: public qse_mmgr_t
{ {
public: public:
/// defines an alias type to #qse_mmgr_t /// defines an alias type to #qse_mmgr_t
@ -70,7 +71,7 @@ protected:
/// If it fails to allocate memory, it should return QSE_NULL. /// If it fails to allocate memory, it should return QSE_NULL.
/// ///
virtual void* allocMem ( 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; ) = 0;
/// ///
@ -81,7 +82,7 @@ protected:
/// ///
virtual void* reallocMem ( virtual void* reallocMem (
void* ptr, ///< pointer to memory chunk to resize void* ptr, ///< pointer to memory chunk to resize
size_t n ///< new size in bytes qse_size_t n ///< new size in bytes
) = 0; ) = 0;
/// ///
@ -96,12 +97,12 @@ protected:
/// ///
/// bridge function from the #qse_mmgr_t type the allocMem() function. /// 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. /// 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. /// bridge function from the #qse_mmgr_t type the freeMem() function.

View File

@ -28,6 +28,7 @@
#define _QSE_CMN_MPOOL_HPP_ #define _QSE_CMN_MPOOL_HPP_
#include <qse/Uncopyable.hpp> #include <qse/Uncopyable.hpp>
#include <qse/cmn/ExcMmgr.hpp>
///////////////////////////////// /////////////////////////////////
QSE_BEGIN_NAMESPACE(QSE) QSE_BEGIN_NAMESPACE(QSE)
@ -37,7 +38,7 @@ QSE_BEGIN_NAMESPACE(QSE)
// allocator for fixed-size data // allocator for fixed-size data
// //
class Mpool: public Uncopyable class QSE_EXPORT Mpool: public Uncopyable, protected ExcMmgr
{ {
public: public:
enum enum
@ -63,14 +64,16 @@ public:
return this->datum_size <= 0 || this->block_size <= 0; 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; return this->datum_size;
} }
inline qse_size_t blockSize () const
inline qse_size_t getBlockSize () const
{ {
return this->block_size; return this->block_size;
} }
inline void setBlockSize (qse_size_t blockSize) inline void setBlockSize (qse_size_t blockSize)
{ {
this->block_size = blockSize; this->block_size = blockSize;
@ -87,6 +90,7 @@ protected:
Block* next; Block* next;
//qse_uint8_t data[0]; //qse_uint8_t data[0];
}; };
struct Chain struct Chain
{ {
Chain* next; Chain* next;
@ -97,7 +101,7 @@ protected:
qse_size_t datum_size; qse_size_t datum_size;
qse_size_t block_size; qse_size_t block_size;
void add_block (); Block* add_block ();
}; };
///////////////////////////////// /////////////////////////////////

View File

@ -29,15 +29,18 @@
#include <qse/cmn/Mpool.hpp> #include <qse/cmn/Mpool.hpp>
// use size_t as some compilers complain about qse_size_t used in new().
#include <stddef.h>
///////////////////////////////// /////////////////////////////////
QSE_BEGIN_NAMESPACE(QSE) QSE_BEGIN_NAMESPACE(QSE)
///////////////////////////////// /////////////////////////////////
class Mpoolable class QSE_EXPORT Mpoolable
{ {
public: public:
typedef qse_size_t mp_size_t;
/*
inline void* operator new (mp_size_t size) inline void* operator new (mp_size_t size)
{ {
return ::operator new (size); return ::operator new (size);
@ -47,21 +50,24 @@ public:
{ {
::operator delete (ptr); ::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) #if defined(_MSC_VER)
void operator delete (void* ptr, Mpool* mp) void operator delete (void* ptr, Mpool* mp)
{ {
mp->dispose (ptr); if (mp->isEnabled()) mp->dispose (ptr);
else ::operator delete (mp);
} }
#else #else
inline void dispose (void* ptr, Mpool* mp) inline void dispose (void* ptr, Mpool* mp)
{ {
mp->dispose (ptr); if (mp->isEnabled()) mp->dispose (ptr);
else ::operator delete (mp);
} }
#endif #endif
}; };

View File

@ -33,12 +33,16 @@
QSE_BEGIN_NAMESPACE(QSE) 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 class QSE_EXPORT StdMmgr: public Mmgr
{ {
public: public:
void* allocMem (size_t n); void* allocMem (qse_size_t n);
void* reallocMem (void* ptr, size_t n); void* reallocMem (void* ptr, qse_size_t n);
virtual void freeMem (void* ptr); void freeMem (void* ptr);
static StdMmgr* getDFL(); static StdMmgr* getDFL();
}; };

View File

@ -27,6 +27,7 @@
#ifndef _QSE_SED_SED_HPP_ #ifndef _QSE_SED_SED_HPP_
#define _QSE_SED_SED_HPP_ #define _QSE_SED_SED_HPP_
#include <qse/Types.hpp>
#include <qse/cmn/Mmged.hpp> #include <qse/cmn/Mmged.hpp>
#include <qse/sed/sed.h> #include <qse/sed/sed.h>
@ -45,7 +46,7 @@ QSE_BEGIN_NAMESPACE(QSE)
/// ///
/// The Sed class implements a stream editor by wrapping around #qse_sed_t. /// 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: public:
/// The sed_t type redefines a stream editor type /// The sed_t type redefines a stream editor type

63
qse/lib/cmn/ExcMmgr.cpp Normal file
View File

@ -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 <qse/cmn/ExcMmgr.hpp>
#include <stdlib.h>
#include <stdio.h>
/////////////////////////////////
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)
/////////////////////////////////

View File

@ -141,7 +141,7 @@ if ENABLE_CXX
lib_LTLIBRARIES += libqsecmnxx.la lib_LTLIBRARIES += libqsecmnxx.la
libqsecmnxx_la_SOURCES = \ 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_LDFLAGS = -version-info 1:0:0 -no-undefined
libqsecmnxx_la_LIBADD = libqsecmnxx_la_LIBADD =

View File

@ -149,9 +149,10 @@ libqsecmn_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
$(libqsecmn_la_LDFLAGS) $(LDFLAGS) -o $@ $(libqsecmn_la_LDFLAGS) $(LDFLAGS) -o $@
libqsecmnxx_la_DEPENDENCIES = 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@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_OBJECTS = $(am_libqsecmnxx_la_OBJECTS)
libqsecmnxx_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \ libqsecmnxx_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \ $(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_LDFLAGS = -version-info 1:0:0 -no-undefined
libqsecmn_la_LIBADD = $(SOCKET_LIBS) $(QUADMATH_LIBS) libqsecmn_la_LIBADD = $(SOCKET_LIBS) $(QUADMATH_LIBS)
@ENABLE_CXX_TRUE@libqsecmnxx_la_SOURCES = \ @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_LDFLAGS = -version-info 1:0:0 -no-undefined
@ENABLE_CXX_TRUE@libqsecmnxx_la_LIBADD = @ENABLE_CXX_TRUE@libqsecmnxx_la_LIBADD =
@ -515,6 +516,7 @@ mostlyclean-compile:
distclean-compile: distclean-compile:
-rm -f *.tab.c -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)/Mmgr.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Mpool.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@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/StdMmgr.Plo@am__quote@

View File

@ -30,12 +30,12 @@
QSE_BEGIN_NAMESPACE(QSE) 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); 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); return ((Mmgr*)mmgr->ctx)->reallocMem (ptr, n);
} }

View File

@ -25,9 +25,7 @@
*/ */
#include <qse/cmn/Mpool.hpp> #include <qse/cmn/Mpool.hpp>
#include <qse/cmn/mem.h>
// TODO: can i use QSE_MMGR_XXXXX instead of ::new and ::delete???
///////////////////////////////// /////////////////////////////////
QSE_BEGIN_NAMESPACE(QSE) QSE_BEGIN_NAMESPACE(QSE)
@ -47,6 +45,7 @@ Mpool::Mpool (qse_size_t datum_size, qse_size_t block_size)
this->nalloc = 0; this->nalloc = 0;
#endif #endif
} }
Mpool::~Mpool () Mpool::~Mpool ()
{ {
this->dispose (); this->dispose ();
@ -59,7 +58,9 @@ void* Mpool::allocate ()
void* ptr = this->free_list; void* ptr = this->free_list;
if (!ptr) 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; ptr = this->free_list;
} }
this->free_list = this->free_list->next; this->free_list = this->free_list->next;
@ -84,24 +85,30 @@ void Mpool::dispose ()
while (block) while (block)
{ {
Block* next = block->next; Block* next = block->next;
::delete[] block;
//::delete[] (qse_uint8_t*)block;
this->freeMem ((qse_uint8_t*)block);
block = next; block = next;
} }
this->free_list = QSE_NULL; this->free_list = QSE_NULL;
this->mp_blocks = QSE_NULL; this->mp_blocks = QSE_NULL;
#if defined(QSE_DEBUG_MPOOL) #if defined(QSE_DEBUG_MPOOL)
this->navail = 0; this->navail = 0;
this->nalloc = 0; this->nalloc = 0;
#endif #endif
} }
void Mpool::add_block () Mpool::Block* Mpool::add_block ()
{ {
QSE_ASSERT (this->datum_size > 0 && this->block_size > 0); QSE_ASSERT (this->datum_size > 0 && this->block_size > 0);
Block* block = (Block*)::new qse_uint8_t[ //Block* block = (Block*)::new qse_uint8_t[
QSE_SIZEOF(Block) + this->block_size * this->datum_size]; // 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->data;
this->free_list = (Chain*)(block + 1); this->free_list = (Chain*)(block + 1);
@ -114,12 +121,15 @@ void Mpool::add_block ()
} }
ptr->next = QSE_NULL; ptr->next = QSE_NULL;
block->next = this->mp_blocks; block->next = this->mp_blocks;
this->mp_blocks = block; this->mp_blocks = block;
#if defined(QSE_DEBUG_MPOOL) #if defined(QSE_DEBUG_MPOOL)
this->navail += this->block_size; this->navail += this->block_size;
this->nalloc += this->block_size; this->nalloc += this->block_size;
#endif #endif
return block;
} }
///////////////////////////////// /////////////////////////////////

View File

@ -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); return ::realloc (ptr, n);
} }