1 /*---------------------------------------------------------------------------*
2   Project:     MEM library
3   File:        heapCommoni.h
4   Programmers: Makoto Takano
5 
6   Copyright (C)2005-2007 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;    // unsigned 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:      target 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:      target 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 Prototypes
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 functions
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 // Get 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 // Add 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 // Add 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 // Add an s32 value to the pointer.
125 static inline void*
AddS32ToPtr(void * ptr,s32 val)126 AddS32ToPtr( void* ptr, s32 val )
127 {
128     return (void*)( GetUIntPtr(ptr) + val );
129 }
130 
131 // Add an s32 value to the const pointer.
132 static inline const void*
AddS32ToCPtr(const void * ptr,s32 val)133 AddS32ToCPtr( const void* ptr, s32 val )
134 {
135     return (const void*)( GetUIntPtr(ptr) + val );
136 }
137 
138 // Subtract u32 value from the pointer.
139 static inline void*
SubU32ToPtr(void * ptr,u32 val)140 SubU32ToPtr( void* ptr, u32 val )
141 {
142     return (void*)( GetUIntPtr(ptr) - val );
143 }
144 
145 // Subtract u32 value from the const pointer.
146 static inline const void*
SubU32ToCPtr(const void * ptr,u32 val)147 SubU32ToCPtr( const void* ptr, u32 val )
148 {
149     return (const void*)( GetUIntPtr(ptr) - val );
150 }
151 
152 // Compare the two pointer addresses.
153 static inline int
ComparePtr(const void * a,const void * b)154 ComparePtr( const void* a, const void* b )
155 {
156     const u8* wa = (const u8*)a;
157     const u8* wb = (const u8*)b;
158 
159     return wa - wb;
160 }
161 
162 
163 /*---------------------------------------------------------------------------*
164   Name:         GetOptForHeap
165 
166   Description:  Gets the option flag from the heap.
167 
168   Arguments:    pHeapHd     Heap handle
169 
170   Returns:      Value of the option flag.
171  *---------------------------------------------------------------------------*/
172 static inline u16
GetOptForHeap(const MEMiHeapHead * pHeapHd)173 GetOptForHeap( const MEMiHeapHead* pHeapHd )
174 {
175     return (u16)pHeapHd->attribute.fields.optFlag;
176 }
177 
178 
179 /*---------------------------------------------------------------------------*
180   Name:         SetOptForHeap
181 
182   Description:  Sets the option flag for the heap.
183 
184   Arguments:    pHeapHd     Heap handle
185 
186   Returns:      None.
187  *---------------------------------------------------------------------------*/
188 static inline void
SetOptForHeap(MEMiHeapHead * pHeapHd,u16 optFlag)189 SetOptForHeap(
190     MEMiHeapHead*     pHeapHd,
191     u16               optFlag
192 )
193 {
194     pHeapHd->attribute.fields.optFlag = (u8)optFlag;
195 }
196 
197 /* ------------------------------------------------------------------------
198     Exclusive control of the heap
199    ------------------------------------------------------------------------ */
200 /*---------------------------------------------------------------------------*
201   Name:         LockHeap
202 
203   Description:  Lock function for performing exclusive control of heap.
204 
205   Arguments:    pHeapHd     Heap handle
206 
207   Returns:      None.
208  *---------------------------------------------------------------------------*/
209 static inline void
LockHeap(MEMiHeapHead * pHeapHd)210 LockHeap( MEMiHeapHead*  pHeapHd )
211 {
212     if ( GetOptForHeap( pHeapHd ) & MEM_HEAP_OPT_THREAD_SAFE )
213     {
214         OSLockMutex( &pHeapHd->mutex );
215     }
216 }
217 
218 
219 /*---------------------------------------------------------------------------*
220   Name:         LockHeap
221 
222   Description:  Unlock function for performing exclusive control of the heap.
223 
224   Arguments:    pHeapHd     Heap handle
225 
226   Returns:      None.
227  *---------------------------------------------------------------------------*/
228 static inline void
UnlockHeap(MEMiHeapHead * pHeapHd)229 UnlockHeap( MEMiHeapHead* pHeapHd )
230 {
231     if ( GetOptForHeap( pHeapHd ) & MEM_HEAP_OPT_THREAD_SAFE )
232     {
233         OSUnlockMutex( &pHeapHd->mutex );
234     }
235 }
236 
237 
238 /* ------------------------------------------------------------------------
239     fill memory
240    ------------------------------------------------------------------------ */
241 
242 /*---------------------------------------------------------------------------*
243   Name:         FillAllocMemory
244 
245   Description:  Memory fill immediately after allocation.
246 
247   Arguments:    pHeapHd     Heap handle
248                 address     Address
249                 size        Size
250 
251   Returns:      None.
252  *---------------------------------------------------------------------------*/
253 static inline void
FillAllocMemory(MEMiHeapHead * pHeapHd,void * address,u32 size)254 FillAllocMemory(
255     MEMiHeapHead*   pHeapHd,
256     void*           address,
257     u32             size
258 )
259 {
260 
261     if ( GetOptForHeap(pHeapHd) & MEM_HEAP_OPT_0_CLEAR )
262     {
263         (void)memset( address, 0, size );
264     }
265     else
266     {
267         #if defined( _DEBUG )
268             if ( GetOptForHeap(pHeapHd) & MEM_HEAP_OPT_DEBUG_FILL )
269             {
270                 (void)memset( address, (int)MEMGetFillValForHeap(MEM_HEAP_FILL_ALLOC), size );
271             }
272         #endif
273     }
274 }
275 
276 
277 
278 #if ! defined(_DEBUG)
279 
280 #define FillFreeMemory(  pHeapHd, address, size )  ((void) 0)
281 #define FillNoUseMemory( pHeapHd, address, size )  ((void) 0)
282 
283 #else
284 
285 /*---------------------------------------------------------------------------*
286   Name:         FillFreeMemory
287 
288   Description:  Memory fill immediately after deallocation.
289 
290   Arguments:    pHeapHd     Heap handle
291                 address     Address
292                 size        Size
293 
294   Returns:      None.
295  *---------------------------------------------------------------------------*/
296 static inline void
FillFreeMemory(MEMiHeapHead * pHeapHd,void * address,u32 size)297 FillFreeMemory(
298     MEMiHeapHead*     pHeapHd,
299     void*             address,
300     u32               size
301 )
302 {
303     if ( GetOptForHeap(pHeapHd) & MEM_HEAP_OPT_DEBUG_FILL )
304     {
305         (void)memset( address, (int)MEMGetFillValForHeap(MEM_HEAP_FILL_FREE), size );
306     }
307 }
308 
309 /*---------------------------------------------------------------------------*
310   Name:         FillNoUseMemory
311 
312   Description:  Unused memory memory fill.
313 
314   Arguments:    pHeapHd     Heap handle
315                 address     Address
316                 size        Size
317 
318   Returns:      None.
319  *---------------------------------------------------------------------------*/
320 static inline void
FillNoUseMemory(MEMiHeapHead * pHeapHd,void * address,u32 size)321 FillNoUseMemory(
322     MEMiHeapHead*     pHeapHd,
323     void*             address,
324     u32               size
325 )
326 {
327     if ( GetOptForHeap(pHeapHd) & MEM_HEAP_OPT_DEBUG_FILL )
328     {
329         (void)memset( address, (int)MEMGetFillValForHeap(MEM_HEAP_FILL_NOUSE), size );
330     }
331 }
332 
333 #endif
334 
335 
336 #ifdef __cplusplus
337 } /* extern "C" */
338 #endif
339 
340 /* MEM_HEAPCOMMONI_H__ */
341 #endif
342