1 /*---------------------------------------------------------------------------*
2   Project:     MEM library
3   File:        mem_allocator.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 #include <revolution/mem/heapCommon.h>
16 #include <revolution/mem/expHeap.h>
17 #include <revolution/mem/frameHeap.h>
18 #include <revolution/mem/unitHeap.h>
19 #include <revolution/mem/allocator.h>
20 
21 
22 /* ========================================================================
23     static functions
24    ======================================================================== */
25 
26 /* ------------------------------------------------------------------------
27     For Exp Heap
28    ------------------------------------------------------------------------ */
29 
30 /*---------------------------------------------------------------------------*
31   Name:         AllocatorAllocForExpHeap_
32 
33   Description:  Function that gets memory from the expansion heap.
34 
35   Arguments:    pAllocator:    pointer to the allocator
36                 size:          size of memory to be gotten
37 
38   Returns:      A pointer to the memory region gotten from the expansion heap.
39  *---------------------------------------------------------------------------*/
40 static void*
AllocatorAllocForExpHeap_(MEMAllocator * pAllocator,u32 size)41 AllocatorAllocForExpHeap_(
42     MEMAllocator*   pAllocator,
43     u32             size
44 )
45 {
46     MEMHeapHandle const heap = (MEMHeapHandle)pAllocator->pHeap;
47     int const alignment   = (int)pAllocator->heapParam1;
48     return MEMAllocFromExpHeapEx( heap, size, alignment );
49 }
50 
51 /*---------------------------------------------------------------------------*
52   Name:         AllocatorFreeForExpHeap_
53 
54   Description:  Function that deallocates memory to the expansion heap.
55 
56   Arguments:    pAllocator:    pointer to the allocator
57                 memBlock:      pointer to the memory block to be deallocated
58 
59   Returns:      None
60  *---------------------------------------------------------------------------*/
61 static void
AllocatorFreeForExpHeap_(MEMAllocator * pAllocator,void * memBlock)62 AllocatorFreeForExpHeap_(
63     MEMAllocator*   pAllocator,
64     void*           memBlock
65 )
66 {
67     MEMHeapHandle const heap = (MEMHeapHandle)pAllocator->pHeap;
68     MEMFreeToExpHeap( heap, memBlock );
69 }
70 
71 /* ------------------------------------------------------------------------
72     For Frame Heap
73    ------------------------------------------------------------------------ */
74 
75 /*---------------------------------------------------------------------------*
76   Name:         AllocatorAllocForFrmHeap_
77 
78   Description:  Function that gets memory from the frame heap.
79 
80   Arguments:    pAllocator:    pointer to the allocator
81                 size:          size of memory to be gotten
82 
83   Returns:      A pointer to the memory region gotten from the frame heap.
84  *---------------------------------------------------------------------------*/
85 static void*
AllocatorAllocForFrmHeap_(MEMAllocator * pAllocator,u32 size)86 AllocatorAllocForFrmHeap_(
87     MEMAllocator*   pAllocator,
88     u32             size
89 )
90 {
91     MEMHeapHandle const heap = (MEMHeapHandle)pAllocator->pHeap;
92     int const alignment   = (int)pAllocator->heapParam1;
93     return MEMAllocFromFrmHeapEx( heap, size, alignment );
94 }
95 
96 /*---------------------------------------------------------------------------*
97   Name:         AllocatorFreeForFrmHeap_
98 
99   Description:  Function that deallocates memory to the frame heap.
100 
101   Arguments:    pAllocator:    pointer to the allocator
102                 memBlock:      pointer to the memory block to be deallocated
103 
104   Returns:      None
105  *---------------------------------------------------------------------------*/
106 static void
AllocatorFreeForFrmHeap_(MEMAllocator * pAllocator,void * memBlock)107 AllocatorFreeForFrmHeap_(
108     MEMAllocator*     pAllocator,
109     void*             memBlock
110 )
111 {
112 #pragma unused( pAllocator, memBlock )
113     /*
114         Since it is not possible in the frame heap to deallocate memory in memory block units, nothing is to occur in this implementation.
115 
116     */
117 }
118 
119 
120 /* ------------------------------------------------------------------------
121     For Unit Heap
122    ------------------------------------------------------------------------ */
123 
124 /*---------------------------------------------------------------------------*
125   Name:         AllocatorAllocForUnitHeap_
126 
127   Description:  Function that gets memory from the unit heap.
128 
129   Arguments:    pAllocator:    pointer to the allocator
130                 size:          size of memory to be gotten
131 
132   Returns:      A pointer to the memory region gotten from the unit heap.
133  *---------------------------------------------------------------------------*/
134 static void*
AllocatorAllocForUnitHeap_(MEMAllocator * pAllocator,u32 size)135 AllocatorAllocForUnitHeap_(
136     MEMAllocator*   pAllocator,
137     u32             size
138 )
139 {
140     /*
141         Null is returned because a block larger than the unit heap's memory block size cannot be allocated.
142 
143     */
144     MEMHeapHandle const heap = (MEMHeapHandle)pAllocator->pHeap;
145 
146     if ( size > MEMGetMemBlockSizeForUnitHeap(heap) )
147     {
148         return NULL;
149     }
150 
151     return MEMAllocFromUnitHeap(heap);
152 }
153 
154 /*---------------------------------------------------------------------------*
155   Name:         AllocatorFreeForUnitHeap_
156 
157   Description:  Function that deallocates memory to the unit heap.
158 
159   Arguments:    pAllocator:    pointer to the allocator
160                 memBlock:      pointer to the memory block to be deallocated
161 
162   Returns:      None
163  *---------------------------------------------------------------------------*/
164 static void
AllocatorFreeForUnitHeap_(MEMAllocator * pAllocator,void * memBlock)165 AllocatorFreeForUnitHeap_(
166     MEMAllocator*   pAllocator,
167     void*           memBlock
168 )
169 {
170     MEMHeapHandle const heap = (MEMHeapHandle)pAllocator->pHeap;
171     MEMFreeToUnitHeap( heap, memBlock );
172 }
173 
174 
175 /* ------------------------------------------------------------------------
176     for the OS heap
177    ------------------------------------------------------------------------ */
178 /*---------------------------------------------------------------------------*
179   Name:         AllocatorAllocForOSHeap_
180 
181   Description:  Function that gets memory from the OS heap.
182 
183   Arguments:    pAllocator:    pointer to the allocator
184                 size:          size of memory to be gotten
185 
186   Returns:      A pointer to the memory region gotten from the OS heap.
187  *---------------------------------------------------------------------------*/
188 static void*
AllocatorAllocForOSHeap_(MEMAllocator * pAllocator,u32 size)189 AllocatorAllocForOSHeap_(
190     MEMAllocator*   pAllocator,
191     u32             size
192 )
193 {
194     OSHeapHandle const heap = (int)pAllocator->pHeap;
195     return OSAllocFromHeap( heap, size );
196 }
197 
198 /*---------------------------------------------------------------------------*
199   Name:         AllocatorFreeForOSHeap_
200 
201   Description:  Function that deallocates memory to the OS heap.
202 
203   Arguments:    pAllocator:    pointer to the allocator
204                 memBlock:      pointer to the memory block to be deallocated
205 
206   Returns:      None
207  *---------------------------------------------------------------------------*/
208 static void
AllocatorFreeForOSHeap_(MEMAllocator * pAllocator,void * memBlock)209 AllocatorFreeForOSHeap_(
210     MEMAllocator*   pAllocator,
211     void*           memBlock
212 )
213 {
214     OSHeapHandle const heap = (int)pAllocator->pHeap;
215     OSFreeToHeap( heap, memBlock );
216 }
217 
218 
219 
220 /* ========================================================================
221     External functions
222    ======================================================================== */
223 
224 /*---------------------------------------------------------------------------*
225   Name:         MEMAllocFromAllocator
226 
227   Description:  Allocates memory blocks from the allocator.
228 
229                 Actual memory allocation will depend on the allocator and the implementation of the associated memory manager.
230 
231 
232   Arguments:    pAllocator:   address of the Allocator structure
233                 size:   memory block size (in bytes)
234 
235   Returns:      If memory block allocation succeeds, returns the beginning address of the block.
236                 Returns NULL if allocation fails.
237  *---------------------------------------------------------------------------*/
238 void*
MEMAllocFromAllocator(MEMAllocator * pAllocator,u32 size)239 MEMAllocFromAllocator(
240     MEMAllocator*   pAllocator,
241     u32             size
242 )
243 {
244     ASSERT(pAllocator);
245     return (*pAllocator->pFunc->pfAlloc)(pAllocator, size);
246 }
247 
248 /*---------------------------------------------------------------------------*
249   Name:         MEMFreeToAllocator
250 
251   Description:  Deallocates a memory block and returns it to allocator.
252 
253                 How the memory is actually returned will depend on the allocator and the implementation of the associated memory manager.
254 
255 
256   Arguments:    pAllocator:   address of the Allocator structure
257                 memBlock:   pointer to the memory block to be deallocated
258 
259   Returns:      None.
260  *---------------------------------------------------------------------------*/
261 void
MEMFreeToAllocator(MEMAllocator * pAllocator,void * memBlock)262 MEMFreeToAllocator(
263     MEMAllocator*   pAllocator,
264     void*           memBlock
265 )
266 {
267     ASSERT(pAllocator && memBlock);
268     (*pAllocator->pFunc->pfFree)(pAllocator, memBlock);
269 }
270 
271 /*---------------------------------------------------------------------------*
272   Name:         MEMInitAllocatorForExpHeap
273 
274   Description:  Initializes the allocator so it can allocate and deallocate memory from the extended heap.
275                 The alignment argument specifies alignment values for all memory blocks that are allocated via the allocator.
276 
277 
278   Arguments:    pAllocator:   address of the MEMAllocator structure
279                 heap:   Handle for expanded heap
280                 alignment:   alignment value to apply to each memory block that is allocated
281 
282   Returns:      None.
283  *---------------------------------------------------------------------------*/
284 void
MEMInitAllocatorForExpHeap(MEMAllocator * pAllocator,MEMHeapHandle heap,int alignment)285 MEMInitAllocatorForExpHeap(
286     MEMAllocator*    pAllocator,
287     MEMHeapHandle    heap,
288     int              alignment
289 )
290 {
291     static const MEMAllocatorFunc sAllocatorFunc =
292     {
293         AllocatorAllocForExpHeap_,
294         AllocatorFreeForExpHeap_,
295     };
296 
297     pAllocator->pFunc = &sAllocatorFunc;
298     pAllocator->pHeap = heap;
299     pAllocator->heapParam1 = (u32)alignment;
300     pAllocator->heapParam2 = 0; // no use
301 }
302 
303 /*---------------------------------------------------------------------------*
304   Name:         MEMInitAllocatorForFrmHeap
305 
306   Description:  Initializes the allocator so it can allocate and deallocate memory from the frame heap.
307                 The alignment argument specifies alignment values for all memory blocks that are allocated via the allocator.
308 
309 
310   Arguments:    pAllocator:   address of the MEMAllocator structure
311                 heap:   Handle for the frame heap
312                 alignment:   alignment value to apply to each memory block that is allocated
313 
314   Returns:      None.
315  *---------------------------------------------------------------------------*/
316 void
MEMInitAllocatorForFrmHeap(MEMAllocator * pAllocator,MEMHeapHandle heap,int alignment)317 MEMInitAllocatorForFrmHeap(
318     MEMAllocator*    pAllocator,
319     MEMHeapHandle    heap,
320     int              alignment
321 )
322 {
323     static const MEMAllocatorFunc sAllocatorFunc =
324     {
325         AllocatorAllocForFrmHeap_,
326         AllocatorFreeForFrmHeap_,
327     };
328 
329     pAllocator->pFunc = &sAllocatorFunc;
330     pAllocator->pHeap = heap;
331     pAllocator->heapParam1 = (u32)alignment;
332     pAllocator->heapParam2 = 0; // no use
333 }
334 
335 /*---------------------------------------------------------------------------*
336   Name:         MEMInitAllocatorForUnitHeap
337 
338   Description:  Initializes the allocator so it can allocate and deallocate memory from the unit heap.
339                 It is not possible to allocated a memory block that is larger than the unit heap memory block size.
340                 In such a case, the AllocFromAllocator() function will return NULL.
341 
342   Arguments:    pAllocator:   address of the MEMAllocator structure
343                 heap:   unit heap handle
344 
345   Returns:      None.
346  *---------------------------------------------------------------------------*/
347 void
MEMInitAllocatorForUnitHeap(MEMAllocator * pAllocator,MEMHeapHandle heap)348 MEMInitAllocatorForUnitHeap(
349     MEMAllocator*    pAllocator,
350     MEMHeapHandle    heap
351 )
352 {
353     static const MEMAllocatorFunc sAllocatorFunc =
354     {
355         AllocatorAllocForUnitHeap_,
356         AllocatorFreeForUnitHeap_,
357     };
358 
359     pAllocator->pFunc = &sAllocatorFunc;
360     pAllocator->pHeap = heap;
361     pAllocator->heapParam1 = 0; // no use
362     pAllocator->heapParam2 = 0; // no use
363 }
364 
365 /*---------------------------------------------------------------------------*
366   Name:         MEMInitAllocatorForOSHeap
367 
368   Description:  Initializes the allocator to perform allocation and deallocation of memory from the heap that is created using the dolphin-SDK's OSCreateHeap() function.
369 
370 
371   Arguments:    pAllocator:   address of the MEMAllocator structure
372                 id:   arena ID the arena that the heap is located in
373                 heap:   the heap handle
374 
375   Returns:      None.
376  *---------------------------------------------------------------------------*/
377 void
MEMInitAllocatorForOSHeap(MEMAllocator * pAllocator,OSHeapHandle heap)378 MEMInitAllocatorForOSHeap(
379     MEMAllocator*      pAllocator,
380     OSHeapHandle       heap
381 )
382 {
383     static const MEMAllocatorFunc sAllocatorFunc =
384     {
385         AllocatorAllocForOSHeap_,
386         AllocatorFreeForOSHeap_,
387     };
388 
389     pAllocator->pFunc = &sAllocatorFunc;
390     pAllocator->pHeap = (void*)heap;
391     pAllocator->heapParam1 = 0; // no use
392     pAllocator->heapParam2 = 0; // no use
393 }
394 
395 
396