diff options
author | Paul Gilbert | 2012-06-08 23:00:48 +1000 |
---|---|---|
committer | Paul Gilbert | 2012-06-08 23:00:48 +1000 |
commit | d4777379d23b70aa07feec3ef2e90fcf376f4117 (patch) | |
tree | 1309d5caa0cd9d075ad6ef2ea25d8f9ada125828 /engines/tony/mpal | |
parent | 1866cbd0fb0d7df1c1a4059e98b5d0f6d851c2d4 (diff) | |
download | scummvm-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.cpp | 4 | ||||
-rw-r--r-- | engines/tony/mpal/expr.h | 2 | ||||
-rw-r--r-- | engines/tony/mpal/loadmpc.cpp | 16 | ||||
-rw-r--r-- | engines/tony/mpal/memory.cpp | 128 | ||||
-rw-r--r-- | engines/tony/mpal/memory.h | 53 | ||||
-rw-r--r-- | engines/tony/mpal/mpal.cpp | 15 | ||||
-rw-r--r-- | engines/tony/mpal/mpal.h | 7 |
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 \****************************************************************************/ |