aboutsummaryrefslogtreecommitdiff
path: root/engines/tinsel/heapmem.cpp
diff options
context:
space:
mode:
authorMax Horn2009-10-26 16:01:34 +0000
committerMax Horn2009-10-26 16:01:34 +0000
commit6591010f66a05538ddc29b3404d64a27dfc29b3f (patch)
tree7dbf0e90ebea0a229d12346693ca6d55b8ab6fe6 /engines/tinsel/heapmem.cpp
parentb9534216edd6d95ec94ac342c8a612e7a59f9289 (diff)
downloadscummvm-rg350-6591010f66a05538ddc29b3404d64a27dfc29b3f.tar.gz
scummvm-rg350-6591010f66a05538ddc29b3404d64a27dfc29b3f.tar.bz2
scummvm-rg350-6591010f66a05538ddc29b3404d64a27dfc29b3f.zip
TINSEL: Further untangle memory managment.
* Add new function MemoryNoAlloc * Make MemoryAlloc private * Get rid of params to various memory related functions svn-id: r45409
Diffstat (limited to 'engines/tinsel/heapmem.cpp')
-rw-r--r--engines/tinsel/heapmem.cpp92
1 files changed, 49 insertions, 43 deletions
diff --git a/engines/tinsel/heapmem.cpp b/engines/tinsel/heapmem.cpp
index bc4183ce35..7a0766098b 100644
--- a/engines/tinsel/heapmem.cpp
+++ b/engines/tinsel/heapmem.cpp
@@ -30,6 +30,14 @@
namespace Tinsel {
+
+// internal allocation flags
+#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
+
+
+
// Specifies the total amount of memory required for DW1 demo, DW1, or DW2 respectively.
// Currently this is set at 5MB for the DW1 demo and DW1 and 10MB for DW2
// This could probably be reduced somewhat
@@ -161,6 +169,7 @@ void FreeMemNode(MEM_NODE *pMemNode) {
* Tries to make space for the specified number of bytes on the specified heap.
* @param size Number of bytes to free up
* @param bDiscard When set - will discard blocks to fullfill the request
+ * @return true if any blocks were discarded, false otherwise
*/
bool HeapCompact(long size, bool bDiscard) {
MEM_NODE *pHeap = &heapSentinel;
@@ -239,8 +248,7 @@ bool HeapCompact(long size, bool bDiscard) {
oldest = DwGetCurrentTime();
pOldest = NULL;
for (pCur = pHeap->pNext; pCur != pHeap; pCur = pCur->pNext) {
- if ((pCur->flags & (DWM_DISCARDABLE | DWM_DISCARDED | DWM_LOCKED))
- == DWM_DISCARDABLE) {
+ if ((pCur->flags & (DWM_DISCARDED | DWM_LOCKED)) == 0) {
// found a non-discarded discardable block
if (pCur->lruTime < oldest) {
oldest = pCur->lruTime;
@@ -263,17 +271,16 @@ bool HeapCompact(long size, bool bDiscard) {
* @param flags Allocation attributes
* @param size Number of bytes to allocate
*/
-MEM_NODE *MemoryAlloc(int flags, long size) {
- MEM_NODE *pHeap = &heapSentinel;
+static MEM_NODE *MemoryAlloc(int flags, long size) {
+ const MEM_NODE *pHeap = &heapSentinel;
MEM_NODE *pNode;
- bool bCompacted = true; // set when heap has been compacted
#ifdef SCUMM_NEED_ALIGNMENT
const int alignPadding = sizeof(void*) - 1;
size = (size + alignPadding) & ~alignPadding; //round up to nearest multiple of sizeof(void*), this ensures the addresses that are returned are alignment-safe.
#endif
- while ((flags & DWM_NOALLOC) == 0 && bCompacted) {
+ do {
// search the heap for a free block
for (pNode = pHeap->pNext; pNode != pHeap; pNode = pNode->pNext) {
@@ -313,36 +320,42 @@ MEM_NODE *MemoryAlloc(int flags, long size) {
}
}
// compact the heap if we get to here
- bCompacted = HeapCompact(size, true);
- }
+ } while (HeapCompact(size, true));
- // not allocated a block if we get to here
- if (flags & DWM_DISCARDABLE) {
- // chain a discarded node onto the end of the heap
- pNode = AllocMemNode();
- pNode->flags = flags | DWM_DISCARDED;
+ // could not allocate a block
+ return 0;
+}
- // set mnode at the end of the list
- pNode->pPrev = pHeap->pPrev;
- pNode->pNext = pHeap;
+/**
+ * Allocate a discarded MEM_NODE. Actual memory can be assigned to it
+ * by using MemoryReAlloc().
+ */
+MEM_NODE *MemoryNoAlloc() {
+ MEM_NODE *pHeap = &heapSentinel;
- // fix links to this mnode
- pHeap->pPrev->pNext = pNode;
- pHeap->pPrev = pNode;
+ // chain a discarded node onto the end of the heap
+ MEM_NODE *pNode = AllocMemNode();
+ pNode->flags = DWM_DISCARDED;
- // return the discarded node
- return pNode;
- }
+ // set mnode at the end of the list
+ pNode->pPrev = pHeap->pPrev;
+ pNode->pNext = pHeap;
- // could not allocate a block
- return NULL;
-}
+ // fix links to this mnode
+ pHeap->pPrev->pNext = pNode;
+ pHeap->pPrev = pNode;
+ // return the discarded node
+ return pNode;
+}
+/**
+ * Allocate a fixed block of data.
+ * @note For now, we simply malloc it!
+ * @todo We really should keep a list of the allocated pointers,
+ * so that we can discard them later on, when the engine quits.
+ */
void *MemoryAllocFixed(long size) {
- // Allocate a fixed block of data. For now, we simply malloc it!
- // TODO: We really should keep a list of the allocated pointers,
- // so that we can discard them later on, when the engine quits.
#ifdef SCUMM_NEED_ALIGNMENT
const int alignPadding = sizeof(void*) - 1;
@@ -361,9 +374,6 @@ void MemoryDiscard(MEM_NODE *pMemNode) {
// validate mnode pointer
assert(pMemNode >= mnodeList && pMemNode <= mnodeList + NUM_MNODES - 1);
- // object must be discardable
- assert(pMemNode->flags & DWM_DISCARDABLE);
-
// object cannot be locked
assert((pMemNode->flags & DWM_LOCKED) == 0);
@@ -425,12 +435,11 @@ void *MemoryLock(MEM_NODE *pMemNode) {
}
/**
- * Changes the size or attributes of a specified memory object.
+ * Changes the size of a specified memory object and re-allocate it if necessary.
* @param pMemNode Node of the memory object
* @param size New size of block
- * @param flags How to reallocate the object
*/
-void MemoryReAlloc(MEM_NODE *pMemNode, long size, int flags) {
+void MemoryReAlloc(MEM_NODE *pMemNode, long size) {
MEM_NODE *pNew;
// validate mnode pointer
@@ -442,25 +451,22 @@ void MemoryReAlloc(MEM_NODE *pMemNode, long size, int flags) {
// validate the size
assert(size);
- if (size == pMemNode->size) {
- // must be just a change in flags
+ if (size != pMemNode->size) {
+
+ // make sure memory object is not locked and discarded
+ assert(pMemNode->flags == DWM_LOCKED | DWM_DISCARDED);
+ assert(pMemNode->size == 0);
- // update the nodes flags
- pMemNode->flags = flags;
- } else {
// unlink the mnode from the current heap
pMemNode->pNext->pPrev = pMemNode->pPrev;
pMemNode->pPrev->pNext = pMemNode->pNext;
// allocate a new node
- pNew = MemoryAlloc(flags, size);
+ pNew = MemoryAlloc(pMemNode->flags & ~DWM_DISCARDED, size);
// make sure memory allocated
assert(pNew != NULL);
- // update the nodes flags
- pNew->flags = flags;
-
// copy the node to the current node
memcpy(pMemNode, pNew, sizeof(MEM_NODE));