aboutsummaryrefslogtreecommitdiff
path: root/common/memorypool.cpp
diff options
context:
space:
mode:
authorMax Horn2008-10-30 17:45:35 +0000
committerMax Horn2008-10-30 17:45:35 +0000
commit2e20247ce7cf344a29f3efe27c23b15ac13c7512 (patch)
tree8b59c48fc24d4aa431152bbd77bf13ec9fbe632c /common/memorypool.cpp
parent2ec5515e898eca84ea92ac970c63fe244c89982e (diff)
downloadscummvm-rg350-2e20247ce7cf344a29f3efe27c23b15ac13c7512.tar.gz
scummvm-rg350-2e20247ce7cf344a29f3efe27c23b15ac13c7512.tar.bz2
scummvm-rg350-2e20247ce7cf344a29f3efe27c23b15ac13c7512.zip
Reset _chunksPerPage after MemoryPool::freeUnusedPages, to avoid enormous memory consumption in various easy to trigger situations; out of paranoia, prohibit for now memory chunks bigger than 16MB
svn-id: r34868
Diffstat (limited to 'common/memorypool.cpp')
-rw-r--r--common/memorypool.cpp21
1 files changed, 17 insertions, 4 deletions
diff --git a/common/memorypool.cpp b/common/memorypool.cpp
index b117d13931..59772f6a03 100644
--- a/common/memorypool.cpp
+++ b/common/memorypool.cpp
@@ -28,6 +28,11 @@
namespace Common {
+enum {
+ INITIAL_CHUNKS_PER_PAGE = 8
+};
+
+
MemoryPool::MemoryPool(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*));
@@ -37,7 +42,7 @@ MemoryPool::MemoryPool(size_t chunkSize) {
_next = NULL;
- _chunksPerPage = 8;
+ _chunksPerPage = INITIAL_CHUNKS_PER_PAGE;
}
MemoryPool::~MemoryPool() {
@@ -50,9 +55,12 @@ void MemoryPool::allocPage() {
// Allocate a new page
page.numChunks = _chunksPerPage;
+ assert(page.numChunks * _chunkSize < 16*1024*1024); // Refuse to allocate pages bigger than 16 MB
+
page.start = ::malloc(page.numChunks * _chunkSize);
assert(page.start);
_pages.push_back(page);
+
// Next time, we'll alocate a page twice as big as this one.
_chunksPerPage *= 2;
@@ -122,8 +130,6 @@ void MemoryPool::freeUnusedPages() {
}
// Free all pages which are not in use.
- // TODO: Might want to reset _chunksPerPage here (e.g. to the largest
- // _pages[i].numChunks value still in use).
size_t freedPagesCount = 0;
for (size_t i = 0; i < _pages.size(); ++i) {
if (numberOfFreeChunksPerPage[i] == _pages[i].numChunks) {
@@ -141,6 +147,8 @@ void MemoryPool::freeUnusedPages() {
}
}
+// printf("freed %d pages out of %d\n", (int)freedPagesCount, (int)_pages.size());
+
for (size_t i = 0; i < _pages.size(); ) {
if (_pages[i].start == NULL) {
_pages.remove_at(i);
@@ -150,7 +158,12 @@ void MemoryPool::freeUnusedPages() {
}
}
- //printf("%d freed pages\n", freedPagesCount);
+ // Reset _chunksPerPage
+ _chunksPerPage = INITIAL_CHUNKS_PER_PAGE;
+ for (size_t i = 0; i < _pages.size(); ++i) {
+ if (_chunksPerPage < _pages[i].numChunks)
+ _chunksPerPage = _pages[i].numChunks;
+ }
}
} // End of namespace Common