[Scummvm-cvs-logs] SF.net SVN: scummvm:[46282] scummvm/trunk/common

fingolfin at users.sourceforge.net fingolfin at users.sourceforge.net
Mon Dec 7 19:24:10 CET 2009


Revision: 46282
          http://scummvm.svn.sourceforge.net/scummvm/?rev=46282&view=rev
Author:   fingolfin
Date:     2009-12-07 18:24:10 +0000 (Mon, 07 Dec 2009)

Log Message:
-----------
COMMON: Document class MemoryPool; make MemoryPool::_chunkSize const

Modified Paths:
--------------
    scummvm/trunk/common/memorypool.cpp
    scummvm/trunk/common/memorypool.h

Modified: scummvm/trunk/common/memorypool.cpp
===================================================================
--- scummvm/trunk/common/memorypool.cpp	2009-12-07 18:23:28 UTC (rev 46281)
+++ scummvm/trunk/common/memorypool.cpp	2009-12-07 18:24:10 UTC (rev 46282)
@@ -32,14 +32,20 @@
 	INITIAL_CHUNKS_PER_PAGE = 8
 };
 
-
-MemoryPool::MemoryPool(size_t chunkSize) {
+static size_t adjustChunkSize(size_t chunkSize) {
 	// You must at least fit the pointer in the node (technically unneeded considering the next rounding statement)
-	_chunkSize = MAX(chunkSize, sizeof(void*));
+	chunkSize = MAX(chunkSize, sizeof(void*));
 	// There might be an alignment problem on some platforms when trying to load a void* on a non natural boundary
 	// so we round to the next sizeof(void*)
-	_chunkSize = (_chunkSize + sizeof(void*) - 1) & (~(sizeof(void*) - 1));
+	chunkSize = (chunkSize + sizeof(void*) - 1) & (~(sizeof(void*) - 1));
 
+	return chunkSize;
+}
+
+
+MemoryPool::MemoryPool(size_t chunkSize)
+	: _chunkSize(adjustChunkSize(chunkSize)) {
+
 	_next = NULL;
 
 	_chunksPerPage = INITIAL_CHUNKS_PER_PAGE;

Modified: scummvm/trunk/common/memorypool.h
===================================================================
--- scummvm/trunk/common/memorypool.h	2009-12-07 18:23:28 UTC (rev 46281)
+++ scummvm/trunk/common/memorypool.h	2009-12-07 18:24:10 UTC (rev 46282)
@@ -32,6 +32,16 @@
 
 namespace Common {
 
+/**
+ * This class provides a pool of memory 'chunks' of identical size.
+ * The size of a chunk is determined when creating the memory pool.
+ *
+ * Using a memory pool may yield better performance and memory usage
+ * when allocating and deallocating many memory blocks of equal size.
+ * E.g. the Common::String class uses a memory pool for the refCount
+ * variables (each the size of an int) it allocates for each string
+ * instance.
+ */
 class MemoryPool {
 protected:
 	MemoryPool(const MemoryPool&);
@@ -42,7 +52,7 @@
 		size_t numChunks;
 	};
 
-	size_t			_chunkSize;
+	const size_t	_chunkSize;
 	Array<Page>		_pages;
 	void			*_next;
 	size_t			_chunksPerPage;
@@ -52,17 +62,48 @@
 	bool	isPointerInPage(void *ptr, const Page &page);
 
 public:
+	/**
+	 * Constructor for a memory pool with the given chunk size.
+	 * @param chunkSize		the chunk size of this memory pool
+	 */
 	MemoryPool(size_t chunkSize);
 	~MemoryPool();
 
+	/**
+	 * Allocate a new chunk from the memory pool.
+	 */
 	void	*allocChunk();
+	/**
+	 * Return a chunk to the memory pool. The given pointer must have
+	 * been obtained from calling the allocChunk() method of the very
+	 * same MemoryPool instance. Passing any other pointer (e.g. to
+	 * a chunk from another MemoryPool, or a malloc'ed memory block)
+	 * will lead to undefined behavior and may result in a crash (if
+	 * you are lucky) or in silent data corruption.
+	 */
 	void	freeChunk(void *ptr);
 
+	/**
+	 * Perform garbage collection. The memory pool stores all the
+	 * chunks it manages in memory 'pages' obtained via the classic
+	 * memory allocation APIs (i.e. malloc/free). Ordinarily, once
+	 * a page has been allocated, it won't be released again during
+	 * the life time of the memory pool. The exception is when this
+	 * method is called.
+	 */
 	void	freeUnusedPages();
 
+	/**
+	 * Return the chunk size used by this memory pool.
+	 */
 	size_t	getChunkSize() const { return _chunkSize; }
 };
 
+/**
+ * This is a memory pool which already contains in itself some storage
+ * space for a fixed number of chunks. Thus if the memory pool is only
+ * lightly used, no malloc() calls have to be made at all.
+ */
 template<size_t CHUNK_SIZE, size_t NUM_INTERNAL_CHUNKS = 32>
 class FixedSizeMemoryPool : public MemoryPool {
 private:
@@ -80,16 +121,23 @@
 	}
 };
 
+// Ensure NUM_INTERNAL_CHUNKS == 0 results in a compile error
 template<size_t CHUNK_SIZE>
 class FixedSizeMemoryPool<CHUNK_SIZE,0> : public MemoryPool {
 public:
 	FixedSizeMemoryPool() : MemoryPool(CHUNK_SIZE) {}
 };
 
-
+/**
+ * A memory pool for C++ objects.
+ */
 template<class T, size_t NUM_INTERNAL_CHUNKS = 32>
 class ObjectPool : public FixedSizeMemoryPool<sizeof(T), NUM_INTERNAL_CHUNKS> {
 public:
+	/**
+	 * Return the memory chunk used as storage for the given object back
+	 * to the pool, after calling its destructor.
+	 */
 	void deleteChunk(T *ptr) {
 		ptr->~T();
 		this->freeChunk(ptr);
@@ -98,14 +146,14 @@
 
 }	// 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>
-
+/**
+ * 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();


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