[Scummvm-cvs-logs] SF.net SVN: scummvm:[34785] scummvm/trunk/common
fingolfin at users.sourceforge.net
fingolfin at users.sourceforge.net
Mon Oct 13 00:05:27 CEST 2008
Revision: 34785
http://scummvm.svn.sourceforge.net/scummvm/?rev=34785&view=rev
Author: fingolfin
Date: 2008-10-12 22:05:26 +0000 (Sun, 12 Oct 2008)
Log Message:
-----------
COMMON: Added a new ObjectPool class, with matching operator new/delete overloads
Modified Paths:
--------------
scummvm/trunk/common/hashmap.h
scummvm/trunk/common/memorypool.cpp
scummvm/trunk/common/memorypool.h
scummvm/trunk/common/str.cpp
scummvm/trunk/common/xmlparser.h
Modified: scummvm/trunk/common/hashmap.h
===================================================================
--- scummvm/trunk/common/hashmap.h 2008-10-12 22:04:30 UTC (rev 34784)
+++ scummvm/trunk/common/hashmap.h 2008-10-12 22:05:26 UTC (rev 34785)
@@ -37,16 +37,7 @@
#define USE_HASHMAP_MEMORY_POOL
#ifdef USE_HASHMAP_MEMORY_POOL
#include "common/memorypool.h"
-// FIXME: we sadly can't assume standard C++ to be present
-// on every system we support, so we should get rid of this.
-// The solution should be to write a simple placement new
-// on our own.
-
-// Symbian does not have <new> but the new operator
-#if !defined(__SYMBIAN32__)
-#include <new>
#endif
-#endif
namespace Common {
@@ -100,28 +91,16 @@
};
-#ifdef USE_HASHMAP_MEMORY_POOL
- FixedSizeMemoryPool<sizeof(Node), HASHMAP_MEMORYPOOL_SIZE> _nodePool;
+ ObjectPool<Node, HASHMAP_MEMORYPOOL_SIZE> _nodePool;
Node *allocNode(const Key &key) {
- void* mem = _nodePool.malloc();
- return new (mem) Node(key);
+ return new (_nodePool) Node(key);
}
void freeNode(Node *node) {
- node->~Node();
- _nodePool.free(node);
+ _nodePool.deleteChunk(node);
}
-#else
- Node* allocNode(const Key &key) {
- return new Node(key);
- }
- void freeNode(Node *node) {
- delete node;
- }
-#endif
-
Node **_storage; // hashtable of size arrsize.
uint _mask; /**< Capacity of the HashMap minus one; must be a power of two of minus one */
uint _size;
Modified: scummvm/trunk/common/memorypool.cpp
===================================================================
--- scummvm/trunk/common/memorypool.cpp 2008-10-12 22:04:30 UTC (rev 34784)
+++ scummvm/trunk/common/memorypool.cpp 2008-10-12 22:05:26 UTC (rev 34785)
@@ -79,7 +79,7 @@
_next = page.start;
}
-void *MemoryPool::malloc() {
+void *MemoryPool::allocChunk() {
if (!_next) // No free chunks left? Allocate a new page
allocPage();
@@ -89,7 +89,7 @@
return result;
}
-void MemoryPool::free(void* ptr) {
+void MemoryPool::freeChunk(void *ptr) {
// Add the chunk back to (the start of) the list of free chunks
*(void**)ptr = _next;
_next = ptr;
Modified: scummvm/trunk/common/memorypool.h
===================================================================
--- scummvm/trunk/common/memorypool.h 2008-10-12 22:04:30 UTC (rev 34784)
+++ scummvm/trunk/common/memorypool.h 2008-10-12 22:05:26 UTC (rev 34785)
@@ -29,6 +29,7 @@
#include "common/scummsys.h"
#include "common/array.h"
+
namespace Common {
class MemoryPool {
@@ -54,10 +55,12 @@
MemoryPool(size_t chunkSize);
~MemoryPool();
- void *malloc();
- void free(void *ptr);
+ void *allocChunk();
+ void freeChunk(void *ptr);
void freeUnusedPages();
+
+ size_t getChunkSize() const { return _chunkSize; }
};
template<size_t CHUNK_SIZE, size_t NUM_INTERNAL_CHUNKS = 32>
@@ -83,6 +86,33 @@
FixedSizeMemoryPool() : MemoryPool(CHUNK_SIZE) {}
};
+
+template<class T, size_t NUM_INTERNAL_CHUNKS = 32>
+class ObjectPool : public FixedSizeMemoryPool<sizeof(T), NUM_INTERNAL_CHUNKS> {
+public:
+ void deleteChunk(T *ptr) {
+ ptr->~T();
+ freeChunk(ptr);
+ }
+};
+
} // End of namespace Common
+// Provide a custom placement new operator, using an arbitrary
+// MemoryPool.
+//
+// This *should* work with all C++ implementations, but may not.
+//
+// For details on using placement new for custom allocators, see e.g.
+// <http://www.parashift.com/c++-faq-lite/dtors.html#faq-11.14>
+
+inline void* operator new(size_t nbytes, Common::MemoryPool& pool) {
+ assert(nbytes <= pool.getChunkSize());
+ return pool.allocChunk();
+}
+
+inline void operator delete(void* p, Common::MemoryPool& pool) {
+ pool.freeChunk(p);
+}
+
#endif
Modified: scummvm/trunk/common/str.cpp
===================================================================
--- scummvm/trunk/common/str.cpp 2008-10-12 22:04:30 UTC (rev 34784)
+++ scummvm/trunk/common/str.cpp 2008-10-12 22:05:26 UTC (rev 34785)
@@ -193,7 +193,7 @@
if (g_refCountPool == 0)
g_refCountPool = new MemoryPool(sizeof(int));
- _extern._refCount = (int *)g_refCountPool->malloc();
+ _extern._refCount = (int *)g_refCountPool->allocChunk();
*_extern._refCount = 2;
} else {
++(*_extern._refCount);
@@ -212,7 +212,7 @@
// and the ref count storage.
if (oldRefCount) {
assert(g_refCountPool);
- g_refCountPool->free(oldRefCount);
+ g_refCountPool->freeChunk(oldRefCount);
}
free(_str);
Modified: scummvm/trunk/common/xmlparser.h
===================================================================
--- scummvm/trunk/common/xmlparser.h 2008-10-12 22:04:30 UTC (rev 34784)
+++ scummvm/trunk/common/xmlparser.h 2008-10-12 22:05:26 UTC (rev 34785)
@@ -51,7 +51,7 @@
#define MAX_XML_DEPTH 8
#define XML_KEY(keyName) {\
- lay = new CustomXMLKeyLayout;\
+ lay = new CustomXMLKeyLayout;\
lay->callback = (&kLocalParserName::parserCallback_##keyName);\
layout.top()->children[#keyName] = lay;\
layout.push(lay); \
@@ -169,16 +169,14 @@
XMLKeyLayout *layout;
};
- FixedSizeMemoryPool<sizeof(ParserNode), MAX_XML_DEPTH> _nodePool;
+ ObjectPool<ParserNode, MAX_XML_DEPTH> _nodePool;
ParserNode *allocNode() {
- void* mem = _nodePool.malloc();
- return new (mem) ParserNode;
+ return new (_nodePool) ParserNode;
}
void freeNode(ParserNode *node) {
- node->~ParserNode();
- _nodePool.free(node);
+ _nodePool.deleteChunk(node);
}
/**
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
More information about the Scummvm-git-logs
mailing list