diff options
author | Max Horn | 2009-10-26 20:35:06 +0000 |
---|---|---|
committer | Max Horn | 2009-10-26 20:35:06 +0000 |
commit | e1de772e721a7dc0d62223c17617f72af3d2308f (patch) | |
tree | a8f2d75049d2757e14c5ccb8d56a9f4f35c1ef34 /engines | |
parent | 692a4b74dc69f9b8be99456cb02a4421df7c5d6a (diff) | |
download | scummvm-rg350-e1de772e721a7dc0d62223c17617f72af3d2308f.tar.gz scummvm-rg350-e1de772e721a7dc0d62223c17617f72af3d2308f.tar.bz2 scummvm-rg350-e1de772e721a7dc0d62223c17617f72af3d2308f.zip |
TINSEL: Fix handling of free memory blocks
svn-id: r45416
Diffstat (limited to 'engines')
-rw-r--r-- | engines/tinsel/heapmem.cpp | 34 |
1 files changed, 17 insertions, 17 deletions
diff --git a/engines/tinsel/heapmem.cpp b/engines/tinsel/heapmem.cpp index 0e10eab958..42584d5f67 100644 --- a/engines/tinsel/heapmem.cpp +++ b/engines/tinsel/heapmem.cpp @@ -32,6 +32,7 @@ namespace Tinsel { // internal allocation flags +#define DWM_USED 0x0001 ///< the objects memory block is in use #define DWM_DISCARDED 0x0100 ///< the objects memory block has been discarded #define DWM_LOCKED 0x0200 ///< the objects memory block is locked #define DWM_SENTINEL 0x0400 ///< the objects memory block is a sentinel @@ -185,9 +186,6 @@ bool HeapCompact(long size, bool bDiscard) { for (pPrev = pHeap->pNext, pCur = pPrev->pNext; pCur != pHeap; pPrev = pCur, pCur = pCur->pNext) { if (pPrev->flags == 0 && pCur->flags == 0) { - // set the changed flag - bChanged = true; - // both blocks are free - merge them pPrev->size += pCur->size; @@ -198,18 +196,19 @@ bool HeapCompact(long size, bool bDiscard) { // free the current mnode FreeMemNode(pCur); + // set the changed flag + bChanged = true; + // leave the loop break; - } else if ((pPrev->flags & (DWM_LOCKED | DWM_DISCARDED)) == 0 - && pCur->flags == 0) { - // a free block after a moveable block - swap them + } else if (pPrev->flags == DWM_USED && pCur->flags == 0) { + // a free block after a moveable, non-discarded, not locked block - swap them // set the changed flag bChanged = true; // move the unlocked blocks data up (can overlap) - memmove(pPrev->pBaseAddr + pCur->size, - pPrev->pBaseAddr, pPrev->size); + memmove(pPrev->pBaseAddr + pCur->size, pPrev->pBaseAddr, pPrev->size); // swap the order in the linked list pPrev->pPrev->pNext = pCur; @@ -248,7 +247,7 @@ bool HeapCompact(long size, bool bDiscard) { oldest = DwGetCurrentTime(); pOldest = NULL; for (pCur = pHeap->pNext; pCur != pHeap; pCur = pCur->pNext) { - if ((pCur->flags & (DWM_DISCARDED | DWM_LOCKED)) == 0) { + if (pCur->flags == DWM_USED) { // found a non-discarded discardable block if (pCur->lruTime < oldest) { oldest = pCur->lruTime; @@ -271,7 +270,7 @@ bool HeapCompact(long size, bool bDiscard) { * @param flags Allocation attributes * @param size Number of bytes to allocate */ -static MEM_NODE *MemoryAlloc(int flags, long size) { +static MEM_NODE *MemoryAlloc(long size) { const MEM_NODE *pHeap = &heapSentinel; MEM_NODE *pNode; @@ -286,7 +285,7 @@ static MEM_NODE *MemoryAlloc(int flags, long size) { for (pNode = pHeap->pNext; pNode != pHeap; pNode = pNode->pNext) { if (pNode->flags == 0 && pNode->size >= size) { // a free block of the required size - pNode->flags = flags; + pNode->flags = DWM_USED; // update the LRU time pNode->lruTime = DwGetCurrentTime() + 1; @@ -335,7 +334,7 @@ MEM_NODE *MemoryNoAlloc() { // chain a discarded node onto the end of the heap MEM_NODE *pNode = AllocMemNode(); - pNode->flags = DWM_DISCARDED; + pNode->flags = DWM_USED | DWM_DISCARDED; // set mnode at the end of the list pNode->pPrev = pHeap->pPrev; @@ -374,9 +373,10 @@ void MemoryDiscard(MEM_NODE *pMemNode) { // validate mnode pointer assert(pMemNode >= mnodeList && pMemNode <= mnodeList + NUM_MNODES - 1); - // object cannot be locked - assert((pMemNode->flags & DWM_LOCKED) == 0); + // object must be in use and locked + assert((pMemNode->flags & (DWM_USED | DWM_LOCKED)) == DWM_USED); + // discard it if it isn't already if ((pMemNode->flags & DWM_DISCARDED) == 0) { // allocate a free node to replace this node MEM_NODE *pTemp = AllocMemNode(); @@ -452,8 +452,8 @@ void MemoryReAlloc(MEM_NODE *pMemNode, long size) { assert(size); if (size != pMemNode->size) { - // make sure memory object is not locked and discarded - assert(!(pMemNode->flags & DWM_LOCKED) && (pMemNode->flags & DWM_DISCARDED)); + // make sure memory object is discarded and not locked + assert(pMemNode->flags == DWM_USED | DWM_DISCARDED); assert(pMemNode->size == 0); // unlink the mnode from the current heap @@ -461,7 +461,7 @@ void MemoryReAlloc(MEM_NODE *pMemNode, long size) { pMemNode->pPrev->pNext = pMemNode->pNext; // allocate a new node - pNew = MemoryAlloc(pMemNode->flags & ~DWM_DISCARDED, size); + pNew = MemoryAlloc(size); // make sure memory allocated assert(pNew != NULL); |