1 /*---------------------------------------------------------------------------*
2 Project: MEM library
3 File: frm-1.c
4 Programmers: Makoto Takano
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: Demo using frame heap.
17
18 1. The demo creates a frame heap within the expanded heap, once the expanded heap is created.
19 2. Allocates memory from the front and back of the frame heap, and saves using tags marked
20 'FRST', 'SCND', or 'THRD' for the state.
21 3. Again, it allocates memory from the front and back of the frame heap and dumps the statuses.
22 4. Dumps the statuses while restoring the states with the FreeByStateToFrmHeap function.
23 5. Frees all memory allocated from the back.
24 6. Reduces the frame heap's memory capacity using the AdjustFrmHeap function.
25 7. Returns memory to the parent heap's expanded heap. The amount returned is the amount that the frame heap was reduced by.
26 8. Destroys the heap and terminates.
27 *---------------------------------------------------------------------------*/
28
29 #include <revolution.h>
30 #include <revolution/mem.h>
31
32 // Outputs the heap status for non-debug builds.
33 static void ReportFrmHeap( MEMHeapHandle heap );
34 static void ReportExpHeap( MEMHeapHandle heap );
35
36 /*---------------------------------------------------------------------------*
37 Name: SampleFrameHeap
38
39 Description: The sample of the frame heap.
40
41 Arguments: heapAddress: The starting address of the memory allocated to the heap.
42 heapSize: The size of the memory allocated to the heap.
43
44 Returns: None.
45 *---------------------------------------------------------------------------*/
46 static void
SampleFrameHeap(void * heapAddress,u32 heapSize)47 SampleFrameHeap(
48 void* heapAddress,
49 u32 heapSize)
50 {
51 void* pExpMBlock;
52 void* pMBlocks[8];
53 MEMHeapHandle hExpHeap;
54 MEMHeapHandle hFrmHeap;
55 u32 frmHeapSize;
56
57 // --------------------------------------------------------
58 // Makes the frame heap inside the expanded heap once the expanded heap is created.
59 // --------------------------------------------------------
60 {
61 // Creation of the expanded heap
62 hExpHeap = MEMCreateExpHeap( heapAddress, heapSize );
63
64 // Creation of a memory block that appropriates the entire allocatable size
65 pExpMBlock = MEMAllocFromExpHeap(
66 hExpHeap,
67 MEMGetAllocatableSizeForExpHeap( hExpHeap ) );
68 ASSERT( pExpMBlock != NULL );
69
70 // Creation of the frame heap
71 hFrmHeap = MEMCreateFrmHeap(
72 pExpMBlock,
73 MEMGetSizeForMBlockExpHeap( pExpMBlock ) );
74 }
75
76 // --------------------------------------------------------
77 // Conduct the memory block allocation, state save, and restoration
78 // --------------------------------------------------------
79 {
80 // Allocation of the normal memory blocks
81 pMBlocks[0] = MEMAllocFromFrmHeap( hFrmHeap, 100 );
82 ASSERT( pMBlocks[0] != NULL );
83
84 // Allocates from the end of the heap region. The default alignment value is 4.
85 pMBlocks[1] = MEMAllocFromFrmHeapEx( hFrmHeap, 100, -MEM_HEAP_DEFAULT_ALIGNMENT );
86 ASSERT( pMBlocks[1] != NULL );
87
88 // Save the memory block allocation state. The tag is 'FRST'.
89 (void)MEMRecordStateForFrmHeap( hFrmHeap, 'FRST' );
90
91 // Allocate from the beginning and end of the memory block. The alignment is 8.
92 pMBlocks[2] = MEMAllocFromFrmHeapEx( hFrmHeap, 200, 8 );
93 ASSERT( pMBlocks[2] != NULL );
94 pMBlocks[3] = MEMAllocFromFrmHeapEx( hFrmHeap, 200, -8 );
95 ASSERT( pMBlocks[3] != NULL );
96
97 // Save the memory block allocation state. The tag is 'SCND'.
98 (void)MEMRecordStateForFrmHeap( hFrmHeap, 'SCND' );
99
100 // Allocate from the beginning and end of the memory block. The alignment is 16.
101 pMBlocks[4] = MEMAllocFromFrmHeapEx( hFrmHeap, 300, 16 );
102 ASSERT( pMBlocks[4] != NULL );
103 pMBlocks[5] = MEMAllocFromFrmHeapEx( hFrmHeap, 300, -16 );
104 ASSERT( pMBlocks[5] != NULL );
105
106 // Save the memory block allocation state. The tag is 'THRD'
107 (void)MEMRecordStateForFrmHeap( hFrmHeap, 'THRD' );
108
109 // Allocate from the beginning and end of the memory block. The alignment is 32.
110 pMBlocks[6] = MEMAllocFromFrmHeapEx( hFrmHeap, 300, 32 );
111 ASSERT( pMBlocks[6] != NULL );
112 pMBlocks[7] = MEMAllocFromFrmHeapEx( hFrmHeap, 300, -32 );
113 ASSERT( pMBlocks[7] != NULL );
114
115 #ifdef _DEBUG
116 MEMDumpHeap( hFrmHeap );
117 #else
118 ReportFrmHeap( hFrmHeap );
119 #endif
120 // Specify a tag and restore the state
121 (void)MEMFreeByStateToFrmHeap( hFrmHeap, 'SCND' );
122
123 #ifdef _DEBUG
124 MEMDumpHeap( hFrmHeap );
125 #else
126 ReportFrmHeap( hFrmHeap );
127 #endif
128
129 // Restore the state without specifying a tag (restore to the 'FRST' state)
130 (void)MEMFreeByStateToFrmHeap( hFrmHeap, 0 );
131
132 #ifdef _DEBUG
133 MEMDumpHeap( hFrmHeap );
134 #else
135 ReportFrmHeap( hFrmHeap );
136 #endif
137 }
138
139 // --------------------------------------------------------
140 // Free the memory block allocated from the end of the heap region, then compress the frame heap region.
141 // --------------------------------------------------------
142 {
143 // Free the memory block allocated from the end of the heap
144 (void)MEMFreeToFrmHeap( hFrmHeap, MEM_FRMHEAP_FREE_TAIL );
145
146 // Compress the frame heap
147 frmHeapSize = MEMAdjustFrmHeap( hFrmHeap );
148
149 // Compress the memory block of the expanded heap along with the compression of the frame heap
150 (void)MEMResizeForMBlockExpHeap( hExpHeap, pExpMBlock, frmHeapSize );
151
152 // Get the heap that holds the memory block, and dump it.
153 // (Frame heap: the contents of hFrmHeap are displayed))
154 #ifdef _DEBUG
155 MEMDumpHeap( MEMFindContainHeap(pMBlocks[0]) );
156 // Dump the expanded heap
157 MEMDumpHeap( hExpHeap );
158 #else
159 if ( MEMIsFrmHeap( MEMFindContainHeap(pMBlocks[0]) ) )
160 {
161 ReportFrmHeap( MEMFindContainHeap(pMBlocks[0]) );
162 }
163 ReportExpHeap( hExpHeap );
164 #endif
165 }
166
167 // --------------------------------------------------------
168 // Clean up
169 // --------------------------------------------------------
170 {
171 // Get rid of the frame heap
172 void* addr = MEMDestroyFrmHeap( hFrmHeap );
173 MEMFreeToExpHeap( hExpHeap, addr );
174
175 // Gets rid of the expanded heap
176 (void)MEMDestroyExpHeap( hExpHeap );
177 }
178 }
179
180
181 /*---------------------------------------------------------------------------*
182 Name: main
183 *---------------------------------------------------------------------------*/
184 void
main(void)185 main( void )
186 {
187 void *arenaLo, *arenaHi;
188
189 OSInit();
190 arenaLo = OSGetArenaLo();
191 arenaHi = OSGetArenaHi();
192
193 SampleFrameHeap( arenaLo, (u32)arenaHi - (u32) arenaLo );
194
195 while(1) {}
196 }
197
198
199
200
201
202 /* ------------------------------------------------------------------------
203 * This is the code for outputting the heap state as a sample
204 * during non-debug builds.
205 * Normally, more detailed output can be derived during a debug build by using the MEMDumpHeap function.
206 */
207 #ifndef _DEBUG
208 static void
ReportFrmHeap(MEMHeapHandle heap)209 ReportFrmHeap( MEMHeapHandle heap )
210 {
211 u32 allocatableSize = MEMGetAllocatableSizeForFrmHeap( heap );
212 u32 totalSize = (u32)MEMGetHeapTotalUsableSize( heap );
213 u32 usedSize = totalSize - allocatableSize;
214
215 OSReport("[OS Foundation Frame Heap]\n");
216 OSReport(" whole [%p - %p)\n", MEMGetHeapStartAddress( heap ), MEMGetHeapEndAddress( heap ) );
217
218 OSReport(" %d / %d bytes (%6.2f%%) used\n", usedSize, totalSize, 100.0 * usedSize / totalSize );
219 OSReport("\n");
220 }
221
222
223 /*
224 structure that gets information for reports.
225 Used to specify parameters when calling the visitor function.
226 */
227 typedef struct
228 {
229 u32 size; // data size storage region
230 u32 cnt; // number of memory blocks used
231 } TReportParam;
232
233
234 /*---------------------------------------------------------------------------*
235 Name: ReportVisitorFunc
236
237 Description: A Visitor function for outputting the heap state.
238
239 Arguments: memBlock: The memory block
240 heap : Handle for expanded heap
241 userParam: call parameter for the visitor function
242 gets the total memory size
243
244 Returns: None.
245 *---------------------------------------------------------------------------*/
246 static void
ReportVisitorFunc(void * memBlock,MEMHeapHandle heap,u32 userParam)247 ReportVisitorFunc(
248 void* memBlock,
249 MEMHeapHandle heap,
250 u32 userParam
251 )
252 {
253 #pragma unused( heap )
254 TReportParam* pParam = (TReportParam*)userParam;
255 u16 allocDir = MEMGetAllocDirForMBlockExpHeap( memBlock );
256 u16 groupId = MEMGetGroupIDForMBlockExpHeap ( memBlock );
257 u32 size = MEMGetSizeForMBlockExpHeap ( memBlock );
258
259 pParam->size += MEMGetSizeForMBlockExpHeap( memBlock );
260 pParam->cnt++;
261
262 OSReport(" %s %08x: %8d %3d\n",
263 allocDir == MEM_EXPHEAP_ALLOC_DIR_REAR ? " rear" : "front",
264 (u32)memBlock,
265 size,
266 groupId
267 );
268 }
269
270 /*---------------------------------------------------------------------------*
271 Name: ReportExpHeap
272
273 Description: Outputs the state of the expanded heap.
274 The MEMDumpHeap will provide detailed output for debug builds.
275
276 Arguments: heap heap handle
277
278 Returns: None.
279 *---------------------------------------------------------------------------*/
280 static void
ReportExpHeap(MEMHeapHandle heap)281 ReportExpHeap( MEMHeapHandle heap )
282 {
283 TReportParam param = { 0, 0 };
284
285 OSReport("[OS Foundation Exp Heap]\n");
286
287 OSReport(" whole [%p - %p)\n", MEMGetHeapStartAddress( heap ), MEMGetHeapEndAddress( heap ) );
288 OSReport(" attr address: size gid\n"); // Header line
289
290 MEMVisitAllocatedForExpHeap(
291 heap, // The heap handle
292 ReportVisitorFunc, // function visitor
293 (u32)¶m // User parameters
294 );
295
296 OSReport("\n");
297
298 {
299 u32 usedSize = param.size;
300 u32 usedCnt = param.cnt;
301
302 OSReport(" %d bytes allocated (U:%d)\n",
303 usedSize, usedCnt);
304 }
305 OSReport("\n");
306 }
307
308 #endif
309