1 /*---------------------------------------------------------------------------*
2 Project: How to set up new/delete operators for C++
3 File: cppsetupdemo.cpp
4
5 Copyright 1998, 1999 Nintendo. All rights reserved.
6
7 These coded instructions, statements, and computer programs contain
8 proprietary information of Nintendo of America Inc. and/or Nintendo
9 Company Ltd., and are protected by Federal copyright law. They may
10 not be disclosed to third parties or copied or duplicated in any form,
11 in whole or in part, without the prior written consent of Nintendo.
12
13 $Log: cppsetupdemo.cpp,v $
14 Revision 1.2 02/20/2006 04:13:11 mitu
15 changed include path from dolphin/ to revolution/.
16
17 Revision 1.1 01/13/2006 11:24:13 hiratsu
18 Initial check in.
19
20
21 4 6/11/01 7:55p Tian
22 Integrated SN changes
23
24 3 3/16/01 12:04p Tian
25 Comments fix
26
27 2 9/29/00 5:27p Tian
28 OS now supports pre-main new.
29
30 1 6/22/00 7:24p Tian
31 Initial check-in.
32 $NoKeywords: $
33 *---------------------------------------------------------------------------*/
34
35 /*---------------------------------------------------------------------------*
36 This demo shows how to override the standard new/delete operators with the
37 Dolphin OS memory allocator. Note the following important caveats:
38
39 - the standard Metrowerks new/delete operators are NOT supported,
40 and will cause a DSI exception if you attempt to use them.
41
42 - this demo works because our new/delete operators occur earlier in
43 the link order than the Metrowerks Standard Libraries. If the MSL
44 libraries occur earlier in the link order than your definition of
45 new/delete, then the MSL new/delete will be used throughout your
46 code.
47
48 This demo does show how to use static global constructors. The trick is
49 to initialize the heap in the first invocation of new(). The flag
50 /IsHeapInitialized/ is used in this example to indicate whether or not
51 the heap has been initialized.
52 *---------------------------------------------------------------------------*/
53
54 #include <revolution.h>
55 #include <stddef.h>
56 /*---------------------------------------------------------------------------*
57 Override new and delete
58 *---------------------------------------------------------------------------*/
59
60 #define HEAP_ID 0
61
62 static BOOL IsHeapInitialized = FALSE;
63
64
65 /*---------------------------------------------------------------------------*
66 Name: CPPInit
67
68 Description: Initializes the Dolphin OS memory allocator and ensures that
69 new and delete will work properly.
70
71 Arguments: None.
72
73 Returns: None.
74 *---------------------------------------------------------------------------*/
CPPInit()75 static void CPPInit()
76 {
77 void* arenaLo;
78 void* arenaHi;
79
80 if (IsHeapInitialized)
81 {
82 return;
83 }
84
85
86 arenaLo = OSGetArenaLo();
87 arenaHi = OSGetArenaHi();
88
89 // Create a heap
90 // OSInitAlloc should only ever be invoked once.
91 arenaLo = OSInitAlloc(arenaLo, arenaHi, 1); // 1 heap
92 OSSetArenaLo(arenaLo);
93
94 // Ensure boundaries are 32B aligned
95 arenaLo = (void*)OSRoundUp32B(arenaLo);
96 arenaHi = (void*)OSRoundDown32B(arenaHi);
97
98 // The boundaries given to OSCreateHeap should be 32B aligned
99 OSSetCurrentHeap(OSCreateHeap(arenaLo, arenaHi));
100 // From here on out, OSAlloc and OSFree behave like malloc and free
101 // respectively
102 OSSetArenaLo(arenaLo=arenaHi);
103 IsHeapInitialized = TRUE;
104
105 }
106
operator new(size_t blocksize)107 inline void* operator new ( size_t blocksize )
108 {
109 if (!IsHeapInitialized)
110 {
111 CPPInit();
112 }
113 return OSAllocFromHeap(HEAP_ID, blocksize);
114 }
115
operator new[](size_t blocksize)116 inline void* operator new[] ( size_t blocksize )
117 {
118 if (!IsHeapInitialized)
119 {
120 CPPInit();
121 }
122 return OSAllocFromHeap(HEAP_ID, blocksize);
123 }
124
operator delete(void * block)125 inline void operator delete ( void* block )
126 {
127 OSFreeToHeap(HEAP_ID, block);
128 }
129
operator delete[](void * block)130 inline void operator delete[] ( void* block )
131 {
132 OSFreeToHeap(HEAP_ID, block);
133 }
134
135
136
137 /*---------------------------------------------------------------------------*
138 Trivial C++ code to test new and delete
139 *---------------------------------------------------------------------------*/
140
141
142 class Foo
143 {
144 private:
145 u32 a;
146 u32 b;
147 char* array;
148
149 public:
150 Foo();
151 ~Foo();
152
printA(void)153 void printA(void)
154 {
155 OSReport("a = %d\n", a);
156 }
157 void printB(void);
158 };
159
160
161 /*---------------------------------------------------------------------------*
162 Name: Foo::Foo
163
164 Description: Constructor for class Foo. Simply initialize private
165 members.
166
167 Arguments:
168
169 Returns:
170 *---------------------------------------------------------------------------*/
Foo()171 Foo::Foo()
172 {
173 a = 42;
174 b = 24;
175
176 array = new char[32];
177 }
178
179
180 /*---------------------------------------------------------------------------*
181 Name: Foo::~Foo
182
183 Description: Destructor for class Foo. Performs an OSReport so we know
184 it got called properly.
185
186 Arguments:
187
188 Returns:
189 *---------------------------------------------------------------------------*/
~Foo()190 Foo::~Foo()
191 {
192 OSReport("Foo destructor\n");
193 }
194
195
196
197 /*---------------------------------------------------------------------------*
198 Name: Foo::printB
199
200 Description: function to print out b member
201
202 Arguments:
203
204 Returns:
205 *---------------------------------------------------------------------------*/
printB()206 void Foo::printB()
207 {
208 OSReport("b = %d\n", b);
209 }
210 static Foo StaticFoo;
211
212
main()213 int main()
214 {
215 Foo * foo;
216
217 OSInit();
218 CPPInit();
219
220 foo = new Foo;
221
222 foo->printA();
223 foo->printB();
224 StaticFoo.printA();
225
226 delete foo;
227 return 0;
228 }
229