1 /*---------------------------------------------------------------------------*
2 Project: MEM library
3 File: exp-1.c
4 Programmers: Takano Makoto
5
6 Copyright 2005 Nintendo. All rights reserved.
7
8 These coded instructions, statements, and computer programs contain
9 proprietary information of Nintendo of America Inc. and/or Nintendo
10 Company Ltd., and are protected by Federal copyright law. They may
11 not be disclosed to third parties or copied or duplicated in any form,
12 in whole or in part, without the prior written consent of Nintendo.
13 *---------------------------------------------------------------------------*/
14
15 /*---------------------------------------------------------------------------*
16 Note: a demo for using the expansion heap
17
18 1. An expansion heap is created using statically allocated memory.
19 2. Memory is allocated from both the front and rear of the heap.
20 3. The group ID is changed to 1 and more memory is allocated.
21 4. The visitor function is used to get the size of the allocated memory taken from the heap's rear.
22 5. Using the function visitor, all of the memory for group ID 1 is released, and the size of the released memory is calculated.
23
24 6. Destroys the expansion heap.
25 *---------------------------------------------------------------------------*/
26
27 #include <revolution/mem.h>
28 #include <string.h>
29
30 // Outputs the heap status for non-debug builds.
31 static void ReportExpHeap( MEMHeapHandle heap );
32
33 #define HEAP_BUF_ELEMENT_NUM (4096 / sizeof(u32))
34
35 static u32 sHeapBuf[ HEAP_BUF_ELEMENT_NUM ];
36
37 /*
38 The structure that holds the group ID and the total size.
39 Used to specify parameters when calling the visitor function.
40 */
41 typedef struct
42 {
43 u16 groupID; // Group ID specification
44 u16 padding; // Not used
45 u32 size; // Data size storage region
46 } TGroupParam;
47
48
49 /*---------------------------------------------------------------------------*
50 Name: GetTailSizeVisitorFunc
51
52 Description: A Visitor function that gets total size of the allocated memory from the end of the heap.
53
54
55 Arguments: memBlock: the memory block
56 heap: expansion heap handle
57 userParam: call parameter for the visitor function
58 Gets the total memory size.
59
60 Returns: None.
61 *---------------------------------------------------------------------------*/
62 static void
GetTailSizeVisitorFunc(void * memBlock,MEMHeapHandle heap,u32 userParam)63 GetTailSizeVisitorFunc(
64 void* memBlock,
65 MEMHeapHandle heap,
66 u32 userParam
67 )
68 {
69 #pragma unused( heap )
70 // Performs process for memory allocated from the rear of the heap.
71 if ( MEMGetAllocDirForMBlockExpHeap(memBlock) == MEM_EXPHEAP_ALLOC_MODE_NEAR )
72 {
73 *(u32*)userParam += MEMGetSizeForMBlockExpHeap(memBlock);
74 }
75 }
76
77
78 /*---------------------------------------------------------------------------*
79 Name: FreeGroupVisitorFunc
80
81 Description: Visitor function that specifies a group to release the heap.
82
83 Arguments: memBlock: The memory block
84 heap: Handle for expanded heap
85 userParam: call parameter for the visitor function
86 pointer to the TGroupParam format data
87
88 Returns: None.
89 *---------------------------------------------------------------------------*/
90 static void
FreeGroupVisitorFunc(void * memBlock,MEMHeapHandle heap,u32 userParam)91 FreeGroupVisitorFunc(
92 void* memBlock,
93 MEMHeapHandle heap,
94 u32 userParam
95 )
96 {
97 TGroupParam* pGrpParam = (TGroupParam*)userParam;
98
99 // Performs process for memory whose group ID is the same as the argument ID.
100 if ( MEMGetGroupIDForMBlockExpHeap(memBlock) == pGrpParam->groupID )
101 {
102 // Adds the size
103 pGrpParam->size += MEMGetSizeForMBlockExpHeap(memBlock);
104 // Releases the heap
105 MEMFreeToExpHeap( heap, memBlock );
106 }
107 }
108
109
110
111 /*---------------------------------------------------------------------------*
112 Name: SampleExpHeap
113
114 Description: The sample of the expanded heap.
115
116 Arguments: heapAddress: The starting address of the memory allocated to the heap.
117 heapSize: The size of the memory allocated to the heap.
118
119 Returns: None.
120 *---------------------------------------------------------------------------*/
121 static void
SampleExpHeap(void * heapAddress,u32 heapSize)122 SampleExpHeap(
123 void* heapAddress,
124 u32 heapSize
125 )
126 {
127 void* pMBlocks[4];
128
129 // Creation of the expanded heap
130 MEMHeapHandle hExpHeap = MEMCreateExpHeap( heapAddress, heapSize );
131
132 // Normal allocation of the memory blocks
133 pMBlocks[0] = MEMAllocFromExpHeap( hExpHeap, 100 );
134 ASSERT( pMBlocks[0] != NULL );
135
136 // Allocates from the end of the heap region. The default alignment value is 4.
137 pMBlocks[2] = MEMAllocFromExpHeapEx( hExpHeap, 100, -MEM_HEAP_DEFAULT_ALIGNMENT );
138 ASSERT( pMBlocks[2] != NULL );
139
140 // Changes the group ID to 1. group ID is 0 when the heap is created.
141 (void)MEMSetGroupIDForExpHeap( hExpHeap, 1 );
142
143 // Allocates the memory blocks. The alignment is 16.
144 pMBlocks[1] = MEMAllocFromExpHeapEx( hExpHeap, 200, 16 );
145 ASSERT( pMBlocks[1] != NULL );
146
147 // Allocates from the end of the heap region. The alignment is 16.
148 pMBlocks[3] = MEMAllocFromExpHeapEx( hExpHeap, 200, -16 );
149 ASSERT( pMBlocks[3] != NULL );
150
151 // Dump output of heap data
152 #ifdef _DEBUG // MEMDumpHeap is only valid in debug builds.
153 MEMDumpHeap( hExpHeap );
154 #else
155 ReportExpHeap( hExpHeap );
156 #endif
157 // Expansion of the memory block from 200 to 300
158 if ( MEMResizeForMBlockExpHeap( hExpHeap, pMBlocks[1], 300 ) == 0 )
159 {
160 // Reallocates if there is a failure in memory block resizing.
161 void* tmp;
162 tmp = MEMAllocFromExpHeapEx( hExpHeap, 300, 16 );
163 ASSERT( tmp != NULL );
164 memcpy( tmp, pMBlocks[1], 200 );
165 MEMFreeToExpHeap( hExpHeap, pMBlocks[1] );
166 pMBlocks[1] = tmp;
167 }
168
169 // Gets the total size of the memory block allocated from the rear of the expansion heap.
170 {
171 u32 size = 0;
172
173 MEMVisitAllocatedForExpHeap(
174 hExpHeap, // The heap handle
175 GetTailSizeVisitorFunc, // visitor function
176 (u32)&size ); // Region for getting the memory size
177 OSReport("size of allocated from rear = %ld\n", size );
178 }
179
180 // Releases the memory whose group ID is 1.
181 {
182 TGroupParam grpParam;
183 grpParam.groupID = 1;
184 grpParam.size = 0;
185
186 // Processes FreeGroupVisitorFunc for all allocated regions.
187 MEMVisitAllocatedForExpHeap(
188 hExpHeap, // The heap handle
189 FreeGroupVisitorFunc, // visitor function
190 (u32)&grpParam ); // User parameters
191
192 OSReport("[free exp heap] group 1 size %ld\n", grpParam.size );
193 }
194
195 // Dump output of heap data
196 #ifdef _DEBUG // MEMDumpHeap is only valid in debug builds.
197 MEMDumpHeap( hExpHeap );
198 #else
199 ReportExpHeap( hExpHeap );
200 #endif
201
202 // Destroy the expanded heap
203 (void)MEMDestroyExpHeap( hExpHeap );
204 }
205
206
207
208 /*---------------------------------------------------------------------------*
209 Name: main
210 *---------------------------------------------------------------------------*/
211 void
main(void)212 main( void )
213 {
214 OSInit();
215
216 SampleExpHeap( sHeapBuf, sizeof sHeapBuf );
217
218 while(1) {}
219 }
220
221
222
223
224
225 /* ------------------------------------------------------------------------
226 * This is the code for outputting the heap state as a sample for non-debug build.
227 *
228 * Normally, more detailed output can be derived during a debug build by using the MEMDumpHeap function.
229 */
230 #ifndef _DEBUG
231
232 /*
233 Structure that gets information for reports.
234 Used to specify parameters when calling the visitor function.
235 */
236 typedef struct
237 {
238 u32 size; // Data size storage region
239 u32 cnt; // Number of memory blocks used
240 } TReportParam;
241
242
243 /*---------------------------------------------------------------------------*
244 Name: ReportVisitorFunc
245
246 Description: A Visitor function for outputting the heap state.
247
248 Arguments: memBlock: The memory block
249 heap: Handle for expanded heap
250 userParam: call parameter for the visitor function
251 Gets the total memory size.
252
253 Returns: None.
254 *---------------------------------------------------------------------------*/
255 static void
ReportVisitorFunc(void * memBlock,MEMHeapHandle heap,u32 userParam)256 ReportVisitorFunc(
257 void* memBlock,
258 MEMHeapHandle heap,
259 u32 userParam
260 )
261 {
262 #pragma unused( heap )
263 TReportParam* pParam = (TReportParam*)userParam;
264 u16 allocDir = MEMGetAllocDirForMBlockExpHeap( memBlock );
265 u16 groupId = MEMGetGroupIDForMBlockExpHeap ( memBlock );
266 u32 size = MEMGetSizeForMBlockExpHeap ( memBlock );
267
268 pParam->size += MEMGetSizeForMBlockExpHeap( memBlock );
269 pParam->cnt++;
270
271 OSReport(" %s %08x: %8d %3d\n",
272 allocDir == MEM_EXPHEAP_ALLOC_DIR_REAR ? " rear" : "front",
273 (u32)memBlock,
274 size,
275 groupId
276 );
277 }
278
279 /*---------------------------------------------------------------------------*
280 Name: ReportExpHeap
281
282 Description: Outputs the state of the expanded heap.
283 The MEMDumpHeap will provide detailed output for debug builds.
284
285 Arguments: heap: heap handle
286
287 Returns: None.
288 *---------------------------------------------------------------------------*/
289 static void
ReportExpHeap(MEMHeapHandle heap)290 ReportExpHeap( MEMHeapHandle heap )
291 {
292 TReportParam param = { 0, 0 };
293
294 OSReport("[OS Foundation Exp Heap]\n");
295
296 OSReport(" whole [%p - %p)\n", MEMGetHeapStartAddress( heap ), MEMGetHeapEndAddress( heap ) );
297 OSReport(" attr address: size gid\n"); // Header line
298
299 MEMVisitAllocatedForExpHeap(
300 heap, // The heap handle
301 ReportVisitorFunc, // visitor function
302 (u32)¶m // User parameters
303 );
304
305 OSReport("\n");
306
307 {
308 u32 usedSize = param.size;
309 u32 usedCnt = param.cnt;
310
311 OSReport(" %d bytes allocated (U:%d)\n",
312 usedSize, usedCnt);
313 }
314 OSReport("\n");
315 }
316
317 #endif
318
319