[Scummvm-cvs-logs] SF.net SVN: scummvm: [31320] scummvm/trunk/common
tramboi at users.sourceforge.net
tramboi at users.sourceforge.net
Sun Mar 30 07:42:40 CEST 2008
Revision: 31320
http://scummvm.svn.sourceforge.net/scummvm/?rev=31320&view=rev
Author: tramboi
Date: 2008-03-29 22:42:39 -0700 (Sat, 29 Mar 2008)
Log Message:
-----------
Introduction of a fixed size memory pool with a typical free list implementation
+ : amortized O(1) allocation, O(1) deallocation, less overhead per allocation
- : unused memory is not reclaimed until death or manual invocation of a function
Modified Paths:
--------------
scummvm/trunk/common/module.mk
Added Paths:
-----------
scummvm/trunk/common/memorypool.cpp
scummvm/trunk/common/memorypool.h
Added: scummvm/trunk/common/memorypool.cpp
===================================================================
--- scummvm/trunk/common/memorypool.cpp (rev 0)
+++ scummvm/trunk/common/memorypool.cpp 2008-03-30 05:42:39 UTC (rev 31320)
@@ -0,0 +1,94 @@
+#include "common/memorypool.h"
+#include <algorithm>
+
+namespace Common
+{
+
+static const size_t CHUNK_PAGE_SIZE = 32;
+
+void* MemoryPool::allocPage() {
+ void* result = ::malloc(CHUNK_PAGE_SIZE * _chunkSize);
+ _pages.push_back(result);
+ void* current = result;
+ for(size_t i=1; i<CHUNK_PAGE_SIZE; ++i)
+ {
+ void* next = ((char*)current + _chunkSize);
+ *(void**)current = next;
+
+ current = next;
+ }
+ *(void**)current = NULL;
+ return result;
+}
+
+MemoryPool::MemoryPool(size_t chunkSize) {
+ // You must at least fit the pointer in the node (technically unneeded considering the next rounding statement)
+ _chunkSize = std::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));
+
+ _next = NULL;
+}
+
+MemoryPool::~MemoryPool() {
+ for(size_t i=0; i<_pages.size(); ++i)
+ free(_pages[i]);
+}
+
+void* MemoryPool::malloc() {
+#if 1
+ if(!_next)
+ _next = allocPage();
+
+ void* result = _next;
+ _next = *(void**)result;
+ return result;
+#else
+ return ::malloc(_chunkSize);
+#endif
+}
+
+void MemoryPool::free(void* ptr) {
+#if 1
+ *(void**)ptr = _next;
+ _next = ptr;
+#else
+ ::free(ptr);
+#endif
+}
+
+// Technically not compliant C++ to compare unrelated pointers. In practice...
+bool MemoryPool::isPointerInPage(void* ptr, void* page) {
+ return (ptr >= page) && (ptr < (char*)page + CHUNK_PAGE_SIZE * _chunkSize);
+}
+
+void MemoryPool::freeUnusedPages() {
+ //std::sort(_pages.begin(), _pages.end());
+ Array<int> numberOfFreeChunksPerPage;
+ numberOfFreeChunksPerPage.resize(_pages.size());
+ for(size_t i=0; i<numberOfFreeChunksPerPage.size(); ++i) {
+ numberOfFreeChunksPerPage[i] = 0;
+ }
+
+ void* iterator = _next;
+ while(iterator) {
+ // This should be a binary search
+ for(size_t i=0; i<_pages.size(); ++i) {
+ if(isPointerInPage(iterator, _pages[i])) {
+ ++numberOfFreeChunksPerPage[i];
+ break;
+ }
+ }
+ iterator = *(void**)iterator;
+ }
+
+ for(size_t i=0; i<_pages.size(); ++i) {
+ if(numberOfFreeChunksPerPage[i] == CHUNK_PAGE_SIZE) {
+ free(_pages[i]);
+ _pages[i] = NULL; // TODO : Remove NULL values
+ }
+ }
+}
+
+}
Property changes on: scummvm/trunk/common/memorypool.cpp
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Name: svn:eol-style
+ native
Added: scummvm/trunk/common/memorypool.h
===================================================================
--- scummvm/trunk/common/memorypool.h (rev 0)
+++ scummvm/trunk/common/memorypool.h 2008-03-30 05:42:39 UTC (rev 31320)
@@ -0,0 +1,34 @@
+#ifndef COMMON_MEMORYPOOL_H
+#define COMMON_MEMORYPOOL_H
+
+#include <cstring>
+#include "common/array.h"
+
+namespace Common
+{
+
+class MemoryPool
+{
+ private:
+ MemoryPool(const MemoryPool&);
+ MemoryPool& operator=(const MemoryPool&);
+
+ size_t _chunkSize;
+ Array<void*> _pages;
+ void* _next;
+
+ void* allocPage();
+ bool isPointerInPage(void* ptr, void* page);
+ public:
+ MemoryPool(size_t chunkSize);
+ ~MemoryPool();
+
+ void* malloc();
+ void free(void* ptr);
+
+ void freeUnusedPages();
+};
+
+}
+
+#endif
Property changes on: scummvm/trunk/common/memorypool.h
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Name: svn:eol-style
+ native
Modified: scummvm/trunk/common/module.mk
===================================================================
--- scummvm/trunk/common/module.mk 2008-03-30 03:21:01 UTC (rev 31319)
+++ scummvm/trunk/common/module.mk 2008-03-30 05:42:39 UTC (rev 31320)
@@ -7,6 +7,7 @@
file.o \
fs.o \
hashmap.o \
+ memorypool.o \
md5.o \
mutex.o \
str.o \
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