aboutsummaryrefslogtreecommitdiff
path: root/engines/tony/mpal
diff options
context:
space:
mode:
authorPaul Gilbert2012-06-08 23:00:48 +1000
committerPaul Gilbert2012-06-08 23:00:48 +1000
commitd4777379d23b70aa07feec3ef2e90fcf376f4117 (patch)
tree1309d5caa0cd9d075ad6ef2ea25d8f9ada125828 /engines/tony/mpal
parent1866cbd0fb0d7df1c1a4059e98b5d0f6d851c2d4 (diff)
downloadscummvm-rg350-d4777379d23b70aa07feec3ef2e90fcf376f4117.tar.gz
scummvm-rg350-d4777379d23b70aa07feec3ef2e90fcf376f4117.tar.bz2
scummvm-rg350-d4777379d23b70aa07feec3ef2e90fcf376f4117.zip
TONY: Refactored the memory manager to increase performance
Diffstat (limited to 'engines/tony/mpal')
-rw-r--r--engines/tony/mpal/expr.cpp4
-rw-r--r--engines/tony/mpal/expr.h2
-rw-r--r--engines/tony/mpal/loadmpc.cpp16
-rw-r--r--engines/tony/mpal/memory.cpp128
-rw-r--r--engines/tony/mpal/memory.h53
-rw-r--r--engines/tony/mpal/mpal.cpp15
-rw-r--r--engines/tony/mpal/mpal.h7
7 files changed, 96 insertions, 129 deletions
diff --git a/engines/tony/mpal/expr.cpp b/engines/tony/mpal/expr.cpp
index 0b51724330..5ba2fff442 100644
--- a/engines/tony/mpal/expr.cpp
+++ b/engines/tony/mpal/expr.cpp
@@ -238,7 +238,7 @@ static int evaluateAndFreeExpression(byte *expr) {
// 3) Risoluzione algebrica
solve(one, num);
val = one->val.num;
- globalFree(expr);
+ globalDestroy(expr);
return val;
}
@@ -263,7 +263,7 @@ const byte *parseExpression(const byte *lpBuf, HGLOBAL *h) {
if (num == 0)
return NULL;
- *h = globalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT, num * sizeof(EXPRESSION) + 1);
+ *h = globalAllocate(GMEM_MOVEABLE | GMEM_ZEROINIT, num * sizeof(EXPRESSION) + 1);
if (*h == NULL)
return NULL;
diff --git a/engines/tony/mpal/expr.h b/engines/tony/mpal/expr.h
index 7d33e5c8ca..9844add822 100644
--- a/engines/tony/mpal/expr.h
+++ b/engines/tony/mpal/expr.h
@@ -29,6 +29,8 @@
#ifndef MPAL_EXPR_H
#define MPAL_EXPR_H
+#include "tony/mpal/memory.h"
+
namespace Tony {
namespace MPAL {
diff --git a/engines/tony/mpal/loadmpc.cpp b/engines/tony/mpal/loadmpc.cpp
index 8f07102aa3..5a338b24b0 100644
--- a/engines/tony/mpal/loadmpc.cpp
+++ b/engines/tony/mpal/loadmpc.cpp
@@ -149,7 +149,7 @@ static const byte *parseDialog(const byte *lpBuf, LPMPALDIALOG lpmdDialog) {
for (i = 0; i < num; i++) {
lpmdDialog->_periodNums[i] = READ_LE_UINT16(lpBuf);
lpBuf += 2;
- lpmdDialog->_periods[i] = globalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT, *lpBuf + 1);
+ lpmdDialog->_periods[i] = globalAllocate(GMEM_MOVEABLE | GMEM_ZEROINIT, *lpBuf + 1);
lpLock = (byte *)globalLock(lpmdDialog->_periods[i]);
Common::copy(lpBuf + 1, lpBuf + 1 + *lpBuf, lpLock);
globalUnlock(lpmdDialog->_periods[i]);
@@ -478,7 +478,7 @@ bool ParseMpc(const byte *lpBuf) {
GLOBALS.nVars = READ_LE_UINT16(lpBuf);
lpBuf += 2;
- GLOBALS.hVars = globalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT, sizeof(MPALVAR) * (uint32)GLOBALS.nVars);
+ GLOBALS.hVars = globalAllocate(GMEM_MOVEABLE | GMEM_ZEROINIT, sizeof(MPALVAR) * (uint32)GLOBALS.nVars);
if (GLOBALS.hVars == NULL)
return false;
@@ -507,7 +507,7 @@ bool ParseMpc(const byte *lpBuf) {
lpBuf += 2;
#ifdef NEED_LOCK_MSGS
- GLOBALS.hMsgs = globalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT, sizeof(MPALMSG) * (uint32)GLOBALS.nMsgs);
+ GLOBALS.hMsgs = globalAllocate(GMEM_MOVEABLE | GMEM_ZEROINIT, sizeof(MPALMSG) * (uint32)GLOBALS.nMsgs);
if (GLOBALS.hMsgs == NULL)
return false;
@@ -525,7 +525,7 @@ bool ParseMpc(const byte *lpBuf) {
for (j = 0; lpBuf[j] != 0;)
j += lpBuf[j] + 1;
- GLOBALS.lpmmMsgs->hText = globalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT, j + 1);
+ GLOBALS.lpmmMsgs->hText = globalAllocate(GMEM_MOVEABLE | GMEM_ZEROINIT, j + 1);
lpTemp2 = lpTemp = (byte *)globalLock(GLOBALS.lpmmMsgs->hText);
for (j = 0; lpBuf[j] != 0;) {
@@ -560,7 +560,7 @@ bool ParseMpc(const byte *lpBuf) {
if (*((const byte *)lpBuf + 2) == 6 && strncmp((const char *)lpBuf + 3, "Dialog", 6) == 0) {
GLOBALS.nDialogs = READ_LE_UINT16(lpBuf); lpBuf += 2;
- GLOBALS.hDialogs = globalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT, (uint32)GLOBALS.nDialogs * sizeof(MPALDIALOG));
+ GLOBALS.hDialogs = globalAllocate(GMEM_MOVEABLE | GMEM_ZEROINIT, (uint32)GLOBALS.nDialogs * sizeof(MPALDIALOG));
if (GLOBALS.hDialogs == NULL)
return false;
@@ -581,7 +581,7 @@ bool ParseMpc(const byte *lpBuf) {
lpBuf += 2;
// Allocate memory and read them in
- GLOBALS.hItems = globalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT, (uint32)GLOBALS.nItems * sizeof(MPALITEM));
+ GLOBALS.hItems = globalAllocate(GMEM_MOVEABLE | GMEM_ZEROINIT, (uint32)GLOBALS.nItems * sizeof(MPALITEM));
if (GLOBALS.hItems == NULL)
return false;
@@ -602,7 +602,7 @@ bool ParseMpc(const byte *lpBuf) {
lpBuf += 2;
// Allocate memory and read them in
- GLOBALS.hLocations = globalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT, (uint32)GLOBALS.nLocations*sizeof(MPALLOCATION));
+ GLOBALS.hLocations = globalAllocate(GMEM_MOVEABLE | GMEM_ZEROINIT, (uint32)GLOBALS.nLocations*sizeof(MPALLOCATION));
if (GLOBALS.hLocations == NULL)
return false;
@@ -623,7 +623,7 @@ bool ParseMpc(const byte *lpBuf) {
lpBuf += 2;
// Allocate memory
- GLOBALS.hScripts = globalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT, (uint32)GLOBALS.nScripts * sizeof(MPALSCRIPT));
+ GLOBALS.hScripts = globalAllocate(GMEM_MOVEABLE | GMEM_ZEROINIT, (uint32)GLOBALS.nScripts * sizeof(MPALSCRIPT));
if (GLOBALS.hScripts == NULL)
return false;
diff --git a/engines/tony/mpal/memory.cpp b/engines/tony/mpal/memory.cpp
index b5bd77f838..b50f9d7c37 100644
--- a/engines/tony/mpal/memory.cpp
+++ b/engines/tony/mpal/memory.cpp
@@ -30,122 +30,100 @@ namespace Tony {
namespace MPAL {
/****************************************************************************\
-* MemoryItem methods
-\****************************************************************************/
-
-/**
- * Constructor
- * @param Data sizee
- */
-MemoryItem::MemoryItem(uint32 size) {
- _size = size;
- _buffer = (size == 0) ? NULL : new byte[size];
-}
-
-/**
- * Destructor
- */
-MemoryItem::~MemoryItem() {
- delete[] _buffer;
-}
-
-/**
- * Returns a pointer to the resource
- */
-MemoryItem::operator void *() {
- return dataPointer();
-}
-
-/****************************************************************************\
* MemoryManager methods
\****************************************************************************/
-MemoryManager::MemoryManager() {
-}
-
-/**
- * Destructor
- */
-MemoryManager::~MemoryManager() {
- Common::List<MemoryItem *>::iterator i;
- for (i = _memoryBlocks.begin(); i != _memoryBlocks.end(); ++i) {
- MemoryItem *item = *i;
- delete item;
- }
-}
+const int BLOCK_ID = 0x12345678;
/**
* Allocates a new memory block
- * @returns Returns a MemoryItem instance for the new block
+ * @return Returns a MemoryItem instance for the new block
*/
-MemoryItem &MemoryManager::allocate(uint32 size, uint flags) {
- MemoryItem *newItem = new MemoryItem(size);
+HANDLE MemoryManager::allocate(uint32 size, uint flags) {
+ MemoryItem *newItem = (MemoryItem *)malloc(sizeof(MemoryItem) + size);
+ newItem->_id = BLOCK_ID;
+ newItem->_size = size;
+ newItem->_lockCount = 0;
+
+ // If requested, clear the allocated data block
if ((flags & GMEM_ZEROINIT) != 0) {
- byte *dataP = (byte *)newItem->dataPointer();
+ byte *dataP = newItem->_data;
Common::fill(dataP, dataP + size, 0);
}
- _memoryBlocks.push_back(newItem);
-
- return *newItem;
+ return (HANDLE)newItem;
}
/**
* Allocates a new memory block and returns its data pointer
- * @returns Data pointer to allocated block
+ * @return Data pointer to allocated block
*/
-HGLOBAL MemoryManager::alloc(uint32 size, uint flags) {
- MemoryItem &newItem = allocate(size, flags);
- return (HGLOBAL)newItem.dataPointer();
+void *MemoryManager::alloc(uint32 size, uint flags) {
+ MemoryItem *item = (MemoryItem *)allocate(size, flags);
+ ++item->_lockCount;
+ return &item->_data[0];
}
+#define OFFSETOF(type, field) ((unsigned long) &(((type *) 0)->field))
+
/**
* Returns a reference to the MemoryItem for a gien byte pointer
* @param block Byte pointer
*/
-MemoryItem &MemoryManager::getItem(HGLOBAL handle) {
- Common::List<MemoryItem *>::iterator i;
- for (i = _memoryBlocks.begin(); i != _memoryBlocks.end(); ++i) {
- MemoryItem *item = *i;
- if (item->dataPointer() == handle)
- return *item;
- }
-
- error("Could not locate a memory block");
+MemoryItem *MemoryManager::getItem(HGLOBAL handle) {
+ MemoryItem *rec = (MemoryItem *)((byte *)handle - OFFSETOF(MemoryItem, _data));
+ assert(rec->_id == BLOCK_ID);
+ return rec;
}
/**
- * Square bracketes operator
- * @param block Byte pointer
+ * Returns a size of a memory block given its pointer
*/
-MemoryItem &MemoryManager::operator[](HGLOBAL handle) {
- return getItem(handle);
+uint32 MemoryManager::getSize(HANDLE handle) {
+ MemoryItem *item = (MemoryItem *)handle;
+ assert(item->_id == BLOCK_ID);
+ return item->_size;
}
/**
- * Returns a size of a memory block given its pointer
+ * Erases a given item
*/
-uint32 MemoryManager::getSize(HGLOBAL handle) {
- MemoryItem &item = getItem(handle);
- return item.size();
+void MemoryManager::freeBlock(HANDLE handle) {
+ MemoryItem *item = (MemoryItem *)handle;
+ assert(item->_id == BLOCK_ID);
+ free(item);
}
/**
* Erases a given item
*/
-void MemoryManager::erase(MemoryItem *item) {
- delete item;
- _memoryBlocks.remove(item);
+void MemoryManager::destroyItem(HANDLE handle) {
+ MemoryItem *item = getItem(handle);
+ assert(item->_id == BLOCK_ID);
+ free(item);
}
/**
- * Erases a given item
+ * Locks an item for access
*/
-void MemoryManager::erase(HGLOBAL handle) {
- MemoryItem &item = getItem(handle);
- erase(&item);
+byte *MemoryManager::lockItem(HANDLE handle) {
+ MemoryItem *item = (MemoryItem *)handle;
+ assert(item->_id == BLOCK_ID);
+ ++item->_lockCount;
+ return &item->_data[0];
}
+/**
+ * Unlocks a locked item
+ */
+void MemoryManager::unlockItem(HANDLE handle) {
+ MemoryItem *item = (MemoryItem *)handle;
+ assert(item->_id == BLOCK_ID);
+ assert(item->_lockCount > 0);
+ --item->_lockCount;
+}
+
+
/****************************************************************************\
* Stand-alone methods
\****************************************************************************/
diff --git a/engines/tony/mpal/memory.h b/engines/tony/mpal/memory.h
index 7f95f8d86f..52d527544a 100644
--- a/engines/tony/mpal/memory.h
+++ b/engines/tony/mpal/memory.h
@@ -34,46 +34,37 @@ namespace MPAL {
typedef void *HANDLE;
typedef HANDLE HGLOBAL;
-class MemoryItem {
-protected:
- byte *_buffer;
+struct MemoryItem {
+ uint32 _id;
uint32 _size;
-public:
- MemoryItem(uint32 size);
- virtual ~MemoryItem();
-
- uint32 size() { return _size; }
- void *dataPointer() { return (void *)_buffer; }
- bool isValid() { return _buffer != NULL; }
-
- // Casting for access to data
- operator void *();
+ int _lockCount;
+ byte _data[1];
+
+ // Casting for access to data
+ operator void *() { return &_data[0]; }
};
class MemoryManager {
private:
- Common::List<MemoryItem *> _memoryBlocks;
+ static MemoryItem *getItem(HGLOBAL handle);
public:
- MemoryManager();
- virtual ~MemoryManager();
-
- MemoryItem &allocate(uint32 size, uint flags);
- HGLOBAL alloc(uint32 size, uint flags);
- MemoryItem &getItem(HGLOBAL handle);
- MemoryItem &operator[](HGLOBAL handle);
- void erase(MemoryItem *item);
- void erase(HGLOBAL handle);
-
- uint32 getSize(HANDLE handle);
+ static HANDLE allocate(uint32 size, uint flags);
+ static void *alloc(uint32 size, uint flags);
+ static void freeBlock(HANDLE handle);
+ static void destroyItem(HANDLE handle);
+ static uint32 getSize(HANDLE handle);
+ static byte *lockItem(HANDLE handle);
+ static void unlockItem(HANDLE handle);
};
// defines
-#define globalAlloc(flags, size) _vm->_memoryManager.alloc(size, flags)
-#define globalAllocate(size) _vm->_memoryManager.allocate(size, 0)
-#define globalFree(handle) _vm->_memoryManager.erase(handle)
-#define globalLock(handle) (_vm->_memoryManager.getItem(handle).dataPointer())
-#define globalUnlock(handle) {}
-#define globalSize(handle) (_vm->_memoryManager.getItem(handle).size())
+#define globalAlloc(flags, size) MemoryManager::alloc(size, flags)
+#define globalAllocate(flags, size) MemoryManager::allocate(size, flags)
+#define globalFree(handle) MemoryManager::freeBlock(handle)
+#define globalDestroy(handle) MemoryManager::destroyItem(handle)
+#define globalLock(handle) MemoryManager::lockItem(handle)
+#define globalUnlock(handle) MemoryManager::unlockItem(handle)
+#define globalSize(handle) MemoryManager::getSize(handle)
#define GMEM_FIXED 1
#define GMEM_MOVEABLE 2
diff --git a/engines/tony/mpal/mpal.cpp b/engines/tony/mpal/mpal.cpp
index 95c0b067d5..425fe187fc 100644
--- a/engines/tony/mpal/mpal.cpp
+++ b/engines/tony/mpal/mpal.cpp
@@ -402,7 +402,7 @@ HGLOBAL resLoad(uint32 dwId) {
if (GLOBALS.hMpr.err())
return NULL;
- h = globalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT, nSizeDecomp + (nSizeDecomp / 1024) * 16);
+ h = globalAllocate(GMEM_MOVEABLE | GMEM_ZEROINIT, nSizeDecomp + (nSizeDecomp / 1024) * 16);
buf = (byte *)globalLock(h);
temp = (byte *)globalAlloc(GMEM_FIXED | GMEM_ZEROINIT,nSizeComp);
@@ -414,7 +414,7 @@ HGLOBAL resLoad(uint32 dwId) {
if (nBytesRead != nSizeDecomp)
return NULL;
- globalFree(temp);
+ globalDestroy(temp);
globalUnlock(h);
return h;
}
@@ -741,7 +741,7 @@ void ActionThread(CORO_PARAM, const void *param) {
}
}
- globalFree(item);
+ globalDestroy(item);
debugC(DEBUG_DETAILED, kTonyDebugActions, "Action Process %d ended", CoroScheduler.getCurrentPID());
@@ -803,6 +803,7 @@ void LocationPollThread(CORO_PARAM, const void *param) {
} MYTHREAD;
CORO_BEGIN_CONTEXT;
+ // TODO: Requires endian fix
uint32 *il;
int i, j, k;
int numitems;
@@ -859,7 +860,7 @@ void LocationPollThread(CORO_PARAM, const void *param) {
/* If there is nothing left, we can exit */
if (_ctx->nRealItems == 0) {
- globalFree(_ctx->il);
+ globalDestroy(_ctx->il);
CORO_KILL_SELF();
return;
}
@@ -1456,7 +1457,7 @@ bool mpalInit(const char *lpszMpcFileName, const char *lpszMprFileName,
if (nBytesRead != dwSizeDecomp)
return false;
- globalFree(cmpbuf);
+ globalDestroy(cmpbuf);
} else {
/* If the file is not compressed, we directly read in the data */
nBytesRead = hMpc.read(lpMpcImage, dwSizeDecomp);
@@ -1471,7 +1472,7 @@ bool mpalInit(const char *lpszMpcFileName, const char *lpszMprFileName,
if (ParseMpc(lpMpcImage) == false)
return false;
- globalFree(lpMpcImage);
+ globalDestroy(lpMpcImage);
/* Calculate memory usage */
/*
@@ -1529,7 +1530,7 @@ bool mpalInit(const char *lpszMpcFileName, const char *lpszMprFileName,
if (nBytesRead != (uint32)GLOBALS.nResources * 8)
return false;
- globalFree(cmpbuf);
+ globalDestroy(cmpbuf);
/* Reset back to the start of the file, leaving it open */
GLOBALS.hMpr.seek(0, SEEK_SET);
diff --git a/engines/tony/mpal/mpal.h b/engines/tony/mpal/mpal.h
index fb3d019051..f23eaf8e4a 100644
--- a/engines/tony/mpal/mpal.h
+++ b/engines/tony/mpal/mpal.h
@@ -85,18 +85,13 @@
#include "common/coroutines.h"
#include "common/rect.h"
#include "common/str.h"
+#include "tony/mpal/memory.h"
namespace Tony {
namespace MPAL {
/****************************************************************************\
-* Type definitions
-\****************************************************************************/
-
-typedef void *HANDLE;
-
-/****************************************************************************\
* Macro definitions and structures
\****************************************************************************/