1 /* ScummVM - Graphic Adventure Engine
2  *
3  * ScummVM is the legal property of its developers, whose names
4  * are too numerous to list here. Please refer to the COPYRIGHT
5  * file distributed with this source distribution.
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 2
10  * of the License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20  *
21  */
22 
23 #include "common/algorithm.h"
24 #include "common/textconsole.h"
25 #include "tony/mpal/memory.h"
26 
27 namespace Tony {
28 
29 namespace MPAL {
30 
31 /****************************************************************************\
32 *       MemoryManager methods
33 \****************************************************************************/
34 
35 /**
36  * Allocates a new memory block
37  * @return					Returns a MemoryItem instance for the new block
38  */
allocate(uint32 size,uint flags)39 MpalHandle MemoryManager::allocate(uint32 size, uint flags) {
40 	MemoryItem *newItem = (MemoryItem *)malloc(sizeof(MemoryItem) + size);
41 	newItem->_id = BLOCK_ID;
42 	newItem->_size = size;
43 	newItem->_lockCount = 0;
44 
45 	// If requested, clear the allocated data block
46 	if ((flags & GMEM_ZEROINIT) != 0) {
47 		byte *dataP = newItem->_data;
48 		Common::fill(dataP, dataP + size, 0);
49 	}
50 
51 	return (MpalHandle)newItem;
52 }
53 
54 /**
55  * Allocates a new memory block and returns its data pointer
56  * @return					Data pointer to allocated block
57  */
alloc(uint32 size,uint flags)58 void *MemoryManager::alloc(uint32 size, uint flags) {
59 	MemoryItem *item = (MemoryItem *)allocate(size, flags);
60 	++item->_lockCount;
61 	return &item->_data[0];
62 }
63 
64 #define OFFSETOF(type, field)    ((size_t) &(((type *) 0)->field))
65 
66 /**
67  * Returns a reference to the MemoryItem for a gien byte pointer
68  * @param block				Byte pointer
69  */
getItem(MpalHandle handle)70 MemoryItem *MemoryManager::getItem(MpalHandle handle) {
71 	MemoryItem *rec = (MemoryItem *)((byte *)handle - OFFSETOF(MemoryItem, _data));
72 	assert(rec->_id == BLOCK_ID);
73 	return rec;
74 }
75 
76 /**
77  * Returns a size of a memory block given its pointer
78  */
getSize(MpalHandle handle)79 uint32 MemoryManager::getSize(MpalHandle handle) {
80 	MemoryItem *item = (MemoryItem *)handle;
81 	assert(item->_id == BLOCK_ID);
82 	return item->_size;
83 }
84 
85 /**
86  * Erases a given item
87  */
freeBlock(MpalHandle handle)88 void MemoryManager::freeBlock(MpalHandle handle) {
89 	MemoryItem *item = (MemoryItem *)handle;
90 	assert(item->_id == BLOCK_ID);
91 	free(item);
92 }
93 
94 /**
95  * Erases a given item
96  */
destroyItem(MpalHandle handle)97 void MemoryManager::destroyItem(MpalHandle handle) {
98 	MemoryItem *item = getItem(handle);
99 	assert(item->_id == BLOCK_ID);
100 	free(item);
101 }
102 
103 /**
104  * Locks an item for access
105  */
lockItem(MpalHandle handle)106 byte *MemoryManager::lockItem(MpalHandle handle) {
107 	MemoryItem *item = (MemoryItem *)handle;
108 	assert(item->_id == BLOCK_ID);
109 	++item->_lockCount;
110 	return &item->_data[0];
111 }
112 
113 /**
114  * Unlocks a locked item
115  */
unlockItem(MpalHandle handle)116 void MemoryManager::unlockItem(MpalHandle handle) {
117 	MemoryItem *item = (MemoryItem *)handle;
118 	assert(item->_id == BLOCK_ID);
119 	assert(item->_lockCount > 0);
120 	--item->_lockCount;
121 }
122 
123 } // end of namespace MPAL
124 
125 } // end of namespace Tony
126