[Scummvm-cvs-logs] SF.net SVN: scummvm:[45409] scummvm/trunk/engines/tinsel

fingolfin at users.sourceforge.net fingolfin at users.sourceforge.net
Mon Oct 26 17:01:34 CET 2009


Revision: 45409
          http://scummvm.svn.sourceforge.net/scummvm/?rev=45409&view=rev
Author:   fingolfin
Date:     2009-10-26 16:01:34 +0000 (Mon, 26 Oct 2009)

Log Message:
-----------
TINSEL: Further untangle memory managment.

* Add new function MemoryNoAlloc
* Make MemoryAlloc private
* Get rid of params to various memory related functions

Modified Paths:
--------------
    scummvm/trunk/engines/tinsel/handle.cpp
    scummvm/trunk/engines/tinsel/heapmem.cpp
    scummvm/trunk/engines/tinsel/heapmem.h

Modified: scummvm/trunk/engines/tinsel/handle.cpp
===================================================================
--- scummvm/trunk/engines/tinsel/handle.cpp	2009-10-26 16:01:12 UTC (rev 45408)
+++ scummvm/trunk/engines/tinsel/handle.cpp	2009-10-26 16:01:34 UTC (rev 45409)
@@ -170,7 +170,7 @@
 #endif
 		else {
 			// allocate a discarded memory node for other files
-			pH->_node = MemoryAlloc(DWM_DISCARDABLE | DWM_NOALLOC, pH->filesize & FSIZE_MASK);
+			pH->_node = MemoryNoAlloc();
 			pH->_ptr = NULL;
 
 			// make sure memory allocated
@@ -306,17 +306,6 @@
 			// discardable - lock the memory
 			addr = (uint8 *)MemoryLock(pH->_node);
 		}
-#ifdef DEBUG
-		if (addr == NULL) {
-			if (pH->filesize & fPreload)
-				// preload - no need to lock the memory
-				addr = pH->_ptr;
-			else {
-				// discardable - lock the memory
-				addr = (uint8 *)MemoryLock(pH->_node);
-			}
-		}
-#endif
 
 		// make sure address is valid
 		assert(addr);
@@ -381,7 +370,7 @@
 
 		if (pH->_node->pBaseAddr == NULL)
 			// must have been discarded - reallocate the memory
-			MemoryReAlloc(pH->_node, cdTopHandle - cdBaseHandle, DWM_DISCARDABLE);
+			MemoryReAlloc(pH->_node, cdTopHandle - cdBaseHandle);
 
 		if (pH->_node->pBaseAddr == NULL)
 			error("Out of memory");
@@ -403,7 +392,7 @@
 
 		if (pH->_node->pBaseAddr == NULL)
 			// must have been discarded - reallocate the memory
-			MemoryReAlloc(pH->_node, pH->filesize & FSIZE_MASK, DWM_DISCARDABLE);
+			MemoryReAlloc(pH->_node, pH->filesize & FSIZE_MASK);
 
 		if (pH->_node->pBaseAddr == NULL)
 			error("Out of memory");
@@ -422,7 +411,7 @@
 }
 
 /**
- * Called to make the current scene non-discardable.
+ * Called to lock the current scene and make it non-discardable.
  * @param offset			Handle and offset to data
  */
 void LockScene(SCNHANDLE offset) {
@@ -443,11 +432,12 @@
 	HeapCompact(MAX_INT, false);
 
 	if ((pH->filesize & fPreload) == 0) {
-		// change the flags for the node
-		// WORKAROUND: The original didn't include the DWM_LOCKED flag. It's being
-		// included because the method is 'LockScene' so it's presumed that the
-		// point of this was that the scene's memory block be locked
-		MemoryReAlloc(pH->_node, pH->filesize & FSIZE_MASK, DWM_LOCKED);
+		// Ensure the scene handle is allocated.
+		MemoryReAlloc(pH->_node, pH->filesize & FSIZE_MASK);
+
+		// Now lock it to make sure it stays allocated and in a fixed position.
+		MemoryLock(pH->_node);
+
 #ifdef DEBUG
 		bLockedScene = true;
 #endif
@@ -469,8 +459,9 @@
 	pH = handleTable + handle;
 
 	if ((pH->filesize & fPreload) == 0) {
-		// change the flags for the node
-		MemoryReAlloc(pH->_node, pH->filesize & FSIZE_MASK, DWM_DISCARDABLE);
+		// unlock the scene data
+		MemoryUnlock(pH->_node);
+
 #ifdef DEBUG
 		bLockedScene = false;
 #endif

Modified: scummvm/trunk/engines/tinsel/heapmem.cpp
===================================================================
--- scummvm/trunk/engines/tinsel/heapmem.cpp	2009-10-26 16:01:12 UTC (rev 45408)
+++ scummvm/trunk/engines/tinsel/heapmem.cpp	2009-10-26 16:01:34 UTC (rev 45409)
@@ -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 @@
  * 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 @@
 		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 @@
  * @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 @@
 			}
 		}
 		// 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 @@
 	// 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 @@
 }
 
 /**
- * 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 @@
 	// validate the size
 	assert(size);
 
-	if (size == pMemNode->size) {
-		// must be just a change in flags
+	if (size != pMemNode->size) {
 
-		// update the nodes flags
-		pMemNode->flags = flags;
-	} else {
+		// make sure memory object is not locked and discarded
+		assert(pMemNode->flags == DWM_LOCKED | DWM_DISCARDED);
+		assert(pMemNode->size == 0);
+
 		// 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));
 

Modified: scummvm/trunk/engines/tinsel/heapmem.h
===================================================================
--- scummvm/trunk/engines/tinsel/heapmem.h	2009-10-26 16:01:12 UTC (rev 45408)
+++ scummvm/trunk/engines/tinsel/heapmem.h	2009-10-26 16:01:34 UTC (rev 45409)
@@ -43,25 +43,16 @@
 };
 
 // allocation flags for the MemoryAlloc function
-#define	DWM_DISCARDABLE	0x0004	///< allocates discardable memory
-#define	DWM_NOALLOC		0x0008	///< when used with discardable memory - allocates a discarded block
 
-// 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
 
-
 /*----------------------------------------------------------------------*\
 |*			Memory Function Prototypes			*|
 \*----------------------------------------------------------------------*/
 
 void MemoryInit(void);		// initialises the memory manager
 
-// allocates a movable block with the specified number of bytes from the heap
-MEM_NODE *MemoryAlloc(
-	int flags,		// allocation attributes
-	long size);		// number of bytes to allocate
+// reserves a memory node for a movable & discardable block
+MEM_NODE *MemoryNoAlloc();
 
 // allocates a fixed block with the specified number of bytes
 void *MemoryAllocFixed(long size);
@@ -74,8 +65,7 @@
 
 void MemoryReAlloc(	// changes the size or attributes of a specified memory object
 	MEM_NODE *pMemNode,	// node of the memory object
-	long size,		// new size of block
-	int flags);		// how to reallocate the object
+	long size);		// new size of block
 
 void MemoryUnlock(		// unlocks a memory object
 	MEM_NODE *pMemNode);	// node of the memory object


This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.




More information about the Scummvm-git-logs mailing list