Skip to content

Commit

Permalink
TONY: Refactored the memory manager to increase performance
Browse files Browse the repository at this point in the history
  • Loading branch information
dreammaster committed Jun 8, 2012
1 parent 1866cbd commit d477737
Show file tree
Hide file tree
Showing 10 changed files with 99 additions and 133 deletions.
2 changes: 1 addition & 1 deletion engines/tony/loc.cpp
Expand Up @@ -2305,7 +2305,7 @@ RMMessage::RMMessage() {

RMMessage::~RMMessage() {
if (lpMessage)
globalFree(lpMessage);
globalDestroy(lpMessage);
}

void RMMessage::load(uint32 dwId) {
Expand Down
4 changes: 2 additions & 2 deletions engines/tony/mpal/expr.cpp
Expand Up @@ -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;
}
Expand All @@ -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;

Expand Down
2 changes: 2 additions & 0 deletions engines/tony/mpal/expr.h
Expand Up @@ -29,6 +29,8 @@
#ifndef MPAL_EXPR_H
#define MPAL_EXPR_H

#include "tony/mpal/memory.h"

namespace Tony {

namespace MPAL {
Expand Down
16 changes: 8 additions & 8 deletions engines/tony/mpal/loadmpc.cpp
Expand Up @@ -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]);
Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -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;

Expand All @@ -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;) {
Expand Down Expand Up @@ -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;

Expand All @@ -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;

Expand All @@ -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;

Expand All @@ -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;

Expand Down
128 changes: 53 additions & 75 deletions engines/tony/mpal/memory.cpp
Expand Up @@ -29,123 +29,101 @@ 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
\****************************************************************************/
Expand Down
53 changes: 22 additions & 31 deletions engines/tony/mpal/memory.h
Expand Up @@ -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
Expand Down

0 comments on commit d477737

Please sign in to comment.