1 /*---------------------------------------------------------------------------*
2   Project:     MEM library
3   File:        heapCommoni.h
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 #ifndef MEM_HEAPCOMMONI_H__
16 #define MEM_HEAPCOMMONI_H__
17 
18 #include <revolution/mem/heapCommon.h>
19 #include <string.h>
20 
21 #ifdef __cplusplus
22 extern "C" {
23 #endif
24 
25 
26 /* =======================================================================
27     Type Definitions
28    ======================================================================== */
29 
30 typedef s32 IntPtr;     // Signed integer type mutually convertible with void* pointer
31 typedef u32 UIntPtr;    // Un-signed integer type mutually convertible with void* pointer
32 
33 
34 /* ========================================================================
35     Macro Functions
36    ======================================================================== */
37 
38 /*---------------------------------------------------------------------------*
39   Name:         RoundUp
40 
41   Description:  Rounds up to align with specified alignment.
42 
43   Arguments:    value:   Targeted data
44                 alignment:   Alignment value
45 
46   Returns:      Returns a value that has been rounded up to the specified alignment value.
47  *---------------------------------------------------------------------------*/
48 #define RoundUp( value, alignment ) \
49                 (((value) + ((alignment)-1)) & ~((alignment)-1))
50 
51 #define RoundUpPtr( ptr, alignment ) \
52                 ( (void*)RoundUp(GetUIntPtr(ptr), (alignment)) )
53 
54 
55 /*---------------------------------------------------------------------------*
56   Name:         RoundDown
57 
58   Description:  Rounds down to align for a specified alignment value.
59 
60   Arguments:    value:   Targeted data
61                 alignment:   Alignment value
62 
63   Returns:      Returns a value that has been rounded down to the specified alignment.
64  *---------------------------------------------------------------------------*/
65 #define RoundDown( value, alignment ) \
66                 ( (value) & ~((alignment)-1) )
67 
68 #define RoundDownPtr(ptr, alignment) \
69                 ( (void*)RoundDown(GetUIntPtr(ptr), (alignment)) )
70 
71 
72 /* =======================================================================
73     Function Prototype
74    ======================================================================== */
75 
76 void    MEMiInitHeapHead(
77                 MEMiHeapHead*     pHeapHd,
78                 u32               signature,
79                 void*             heapStart,
80                 void*             heapEnd,
81                 u16               optFlag );
82 
83 void    MEMiFinalizeHeap( MEMiHeapHead* pHeapHd );
84 
85 void    MEMiDumpHeapHead( MEMiHeapHead* pHeapHd );
86 
87 
88 /* ========================================================================
89     inline function
90    ======================================================================== */
91 
92 /* ------------------------------------------------------------------------
93     Pointer Operations
94    ------------------------------------------------------------------------ */
95 
96 // Convert from pointer to u32
97 static inline UIntPtr
GetUIntPtr(const void * ptr)98 GetUIntPtr( const void* ptr )
99 {
100     return (UIntPtr)(ptr);
101 }
102 
103 // Gets the offset value of the two pointers.
104 static inline u32
GetOffsetFromPtr(const void * start,const void * end)105 GetOffsetFromPtr( const void* start, const void* end )
106 {
107     return GetUIntPtr(end) - GetUIntPtr(start);
108 }
109 
110 // Adds u32 value to the pointer.
111 static inline void*
AddU32ToPtr(void * ptr,u32 val)112 AddU32ToPtr( void* ptr, u32 val )
113 {
114     return (void*)( GetUIntPtr(ptr) + val );
115 }
116 
117 // Adds u32 value to the const pointer.
118 static inline const void*
AddU32ToCPtr(const void * ptr,u32 val)119 AddU32ToCPtr( const void* ptr, u32 val )
120 {
121     return (const void*)( GetUIntPtr(ptr) + val );
122 }
123 
124 // Subtracts u32 value from the pointer.
125 static inline void*
SubU32ToPtr(void * ptr,u32 val)126 SubU32ToPtr( void* ptr, u32 val )
127 {
128     return (void*)( GetUIntPtr(ptr) - val );
129 }
130 
131 // Subtracts u32 value from the const pointer.
132 static inline const void*
SubU32ToCPtr(const void * ptr,u32 val)133 SubU32ToCPtr( const void* ptr, u32 val )
134 {
135     return (const void*)( GetUIntPtr(ptr) - val );
136 }
137 
138 // Compares the two pointer addresses.
139 static inline int
ComparePtr(const void * a,const void * b)140 ComparePtr( const void* a, const void* b )
141 {
142     const u8* wa = (const u8*)a;
143     const u8* wb = (const u8*)b;
144 
145     return wa - wb;
146 }
147 
148 
149 /*---------------------------------------------------------------------------*
150   Name:         GetOptForHeap
151 
152   Description:  Gets the option flag from the heap.
153 
154   Arguments:    pHeapHd:       Heap handle
155 
156   Returns:      Value of the option flag.
157  *---------------------------------------------------------------------------*/
158 static inline u16
GetOptForHeap(const MEMiHeapHead * pHeapHd)159 GetOptForHeap( const MEMiHeapHead* pHeapHd )
160 {
161     return (u16)pHeapHd->attribute.fields.optFlag;
162 }
163 
164 
165 /*---------------------------------------------------------------------------*
166   Name:         SetOptForHeap
167 
168   Description:  Sets the option flag for the heap.
169 
170   Arguments:    pHeapHd:       Heap handle
171 
172   Returns:      None.
173  *---------------------------------------------------------------------------*/
174 static inline void
SetOptForHeap(MEMiHeapHead * pHeapHd,u16 optFlag)175 SetOptForHeap(
176     MEMiHeapHead*     pHeapHd,
177     u16               optFlag
178 )
179 {
180     pHeapHd->attribute.fields.optFlag = (u8)optFlag;
181 }
182 
183 /* ------------------------------------------------------------------------
184     Exclusive control of the heap
185    ------------------------------------------------------------------------ */
186 /*---------------------------------------------------------------------------*
187   Name:         LockHeap
188 
189   Description:  Lock function for performing exclusive control of heap.
190 
191   Arguments:    pHeapHd:       Heap handle
192 
193   Returns:      None
194  *---------------------------------------------------------------------------*/
195 static inline void
LockHeap(MEMiHeapHead * pHeapHd)196 LockHeap( MEMiHeapHead*  pHeapHd )
197 {
198     if ( GetOptForHeap( pHeapHd ) & MEM_HEAP_OPT_THREAD_SAFE )
199     {
200         OSLockMutex( &pHeapHd->mutex );
201     }
202 }
203 
204 
205 /*---------------------------------------------------------------------------*
206   Name:         LockHeap
207 
208   Description:  Unlock function for performing exclusive control of the heap.
209 
210   Arguments:    pHeapHd:       Heap handle
211 
212   Returns:      None
213  *---------------------------------------------------------------------------*/
214 static inline void
UnlockHeap(MEMiHeapHead * pHeapHd)215 UnlockHeap( MEMiHeapHead* pHeapHd )
216 {
217     if ( GetOptForHeap( pHeapHd ) & MEM_HEAP_OPT_THREAD_SAFE )
218     {
219         OSUnlockMutex( &pHeapHd->mutex );
220     }
221 }
222 
223 
224 /* ------------------------------------------------------------------------
225     Fill memory
226    ------------------------------------------------------------------------ */
227 
228 /*---------------------------------------------------------------------------*
229   Name:         FillAllocMemory
230 
231   Description:  Memory fill immediately after allocation.
232 
233   Arguments:    pHeapHd:       Heap handle
234                 address:       Address
235                 size:          Size
236 
237   Returns:      None
238  *---------------------------------------------------------------------------*/
239 static inline void
FillAllocMemory(MEMiHeapHead * pHeapHd,void * address,u32 size)240 FillAllocMemory(
241     MEMiHeapHead*   pHeapHd,
242     void*           address,
243     u32             size
244 )
245 {
246 
247     if ( GetOptForHeap(pHeapHd) & MEM_HEAP_OPT_0_CLEAR )
248     {
249         (void)memset( address, 0, size );
250     }
251     else
252     {
253         #if defined( _DEBUG )
254             if ( GetOptForHeap(pHeapHd) & MEM_HEAP_OPT_DEBUG_FILL )
255             {
256                 (void)memset( address, (int)MEMGetFillValForHeap(MEM_HEAP_FILL_ALLOC), size );
257             }
258         #endif
259     }
260 }
261 
262 
263 
264 #if ! defined(_DEBUG)
265 
266 #define FillFreeMemory(  pHeapHd, address, size )  ((void) 0)
267 #define FillNoUseMemory( pHeapHd, address, size )  ((void) 0)
268 
269 #else
270 
271 /*---------------------------------------------------------------------------*
272   Name:         FillFreeMemory
273 
274   Description:  Memory fill immediately after deallocation.
275 
276   Arguments:    pHeapHd:       Heap handle
277                 address:       Address
278                 size:          Size
279 
280   Returns:      None
281  *---------------------------------------------------------------------------*/
282 static inline void
FillFreeMemory(MEMiHeapHead * pHeapHd,void * address,u32 size)283 FillFreeMemory(
284     MEMiHeapHead*     pHeapHd,
285     void*             address,
286     u32               size
287 )
288 {
289     if ( GetOptForHeap(pHeapHd) & MEM_HEAP_OPT_DEBUG_FILL )
290     {
291         (void)memset( address, (int)MEMGetFillValForHeap(MEM_HEAP_FILL_FREE), size );
292     }
293 }
294 
295 /*---------------------------------------------------------------------------*
296   Name:         FillNoUseMemory
297 
298   Description:  Unused memory memory fill.
299 
300   Arguments:    pHeapHd:       Heap handle
301                 address:       Address
302                 size:          Size
303 
304   Returns:      None
305  *---------------------------------------------------------------------------*/
306 static inline void
FillNoUseMemory(MEMiHeapHead * pHeapHd,void * address,u32 size)307 FillNoUseMemory(
308     MEMiHeapHead*     pHeapHd,
309     void*             address,
310     u32               size
311 )
312 {
313     if ( GetOptForHeap(pHeapHd) & MEM_HEAP_OPT_DEBUG_FILL )
314     {
315         (void)memset( address, (int)MEMGetFillValForHeap(MEM_HEAP_FILL_NOUSE), size );
316     }
317 }
318 
319 #endif
320 
321 
322 #ifdef __cplusplus
323 } /* extern "C" */
324 #endif
325 
326 /* MEM_HEAPCOMMONI_H__ */
327 #endif
328