1 /*---------------------------------------------------------------------------*
2 Project: MEM library
3 File: frm-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: Frame heap use demo.
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 'FRST', 'SCND', or 'THRD' for the state.
20
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 // First create the expanded heap and then create the frame heap inside it.
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 // Normal allocation of the 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 reduce 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 // Reduce the frame heap
147 frmHeapSize = MEMAdjustFrmHeap( hFrmHeap );
148
149 // Reduce the memory block of the expanded heap along with the reduction 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 // Destroy the frame heap
172 void* addr = MEMDestroyFrmHeap( hFrmHeap );
173 MEMFreeToExpHeap( hExpHeap, addr );
174
175 // Destroy 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 for non-debug build.
204 *
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, // visitor function
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