diff options
author | Jacek Antonelli | 2008-08-15 23:44:46 -0500 |
---|---|---|
committer | Jacek Antonelli | 2008-08-15 23:44:46 -0500 |
commit | 38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4 (patch) | |
tree | adca584755d22ca041a2dbfc35d4eca01f70b32c /linden/indra/llcommon/llmemory.h | |
parent | README.txt (diff) | |
download | meta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.zip meta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.tar.gz meta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.tar.bz2 meta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.tar.xz |
Second Life viewer sources 1.13.2.12
Diffstat (limited to 'linden/indra/llcommon/llmemory.h')
-rw-r--r-- | linden/indra/llcommon/llmemory.h | 319 |
1 files changed, 319 insertions, 0 deletions
diff --git a/linden/indra/llcommon/llmemory.h b/linden/indra/llcommon/llmemory.h new file mode 100644 index 0000000..b40ab79 --- /dev/null +++ b/linden/indra/llcommon/llmemory.h | |||
@@ -0,0 +1,319 @@ | |||
1 | /** | ||
2 | * @file llmemory.h | ||
3 | * @brief Memory allocation/deallocation header-stuff goes here. | ||
4 | * | ||
5 | * Copyright (c) 2002-2007, Linden Research, Inc. | ||
6 | * | ||
7 | * The source code in this file ("Source Code") is provided by Linden Lab | ||
8 | * to you under the terms of the GNU General Public License, version 2.0 | ||
9 | * ("GPL"), unless you have obtained a separate licensing agreement | ||
10 | * ("Other License"), formally executed by you and Linden Lab. Terms of | ||
11 | * the GPL can be found in doc/GPL-license.txt in this distribution, or | ||
12 | * online at http://secondlife.com/developers/opensource/gplv2 | ||
13 | * | ||
14 | * There are special exceptions to the terms and conditions of the GPL as | ||
15 | * it is applied to this Source Code. View the full text of the exception | ||
16 | * in the file doc/FLOSS-exception.txt in this software distribution, or | ||
17 | * online at http://secondlife.com/developers/opensource/flossexception | ||
18 | * | ||
19 | * By copying, modifying or distributing this software, you acknowledge | ||
20 | * that you have read and understood your obligations described above, | ||
21 | * and agree to abide by those obligations. | ||
22 | * | ||
23 | * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO | ||
24 | * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, | ||
25 | * COMPLETENESS OR PERFORMANCE. | ||
26 | */ | ||
27 | #ifndef LL_MEMORY_H | ||
28 | #define LL_MEMORY_H | ||
29 | |||
30 | #include <new> | ||
31 | #include <cstdlib> | ||
32 | |||
33 | #include "llerror.h" | ||
34 | #include "llthread.h" | ||
35 | #include "llmemtype.h" | ||
36 | |||
37 | extern S32 gTotalDAlloc; | ||
38 | extern S32 gTotalDAUse; | ||
39 | extern S32 gDACount; | ||
40 | |||
41 | const U32 LLREFCOUNT_SENTINEL_VALUE = 0xAAAAAAAA; | ||
42 | |||
43 | //---------------------------------------------------------------------------- | ||
44 | |||
45 | class LLMemory | ||
46 | { | ||
47 | public: | ||
48 | static void initClass(); | ||
49 | static void cleanupClass(); | ||
50 | static void freeReserve(); | ||
51 | private: | ||
52 | static char* reserveMem; | ||
53 | }; | ||
54 | |||
55 | //---------------------------------------------------------------------------- | ||
56 | // RefCount objects should generally only be accessed by way of LLPointer<>'s | ||
57 | // NOTE: LLPointer<LLFoo> x = new LLFoo(); MAY NOT BE THREAD SAFE | ||
58 | // if LLFoo::LLFoo() does anything like put itself in an update queue. | ||
59 | // The queue may get accessed before it gets assigned to x. | ||
60 | // The correct implementation is: | ||
61 | // LLPointer<LLFoo> x = new LLFoo; // constructor does not do anything interesting | ||
62 | // x->instantiate(); // does stuff like place x into an update queue | ||
63 | |||
64 | class LLThreadSafeRefCount | ||
65 | { | ||
66 | public: | ||
67 | static void initClass(); // creates sMutex | ||
68 | static void cleanupClass(); // destroys sMutex | ||
69 | |||
70 | private: | ||
71 | static LLMutex* sMutex; | ||
72 | |||
73 | private: | ||
74 | LLThreadSafeRefCount(const LLThreadSafeRefCount&); // not implemented | ||
75 | LLThreadSafeRefCount&operator=(const LLThreadSafeRefCount&); // not implemented | ||
76 | |||
77 | protected: | ||
78 | virtual ~LLThreadSafeRefCount(); // use unref() | ||
79 | |||
80 | public: | ||
81 | LLThreadSafeRefCount(); | ||
82 | |||
83 | void ref() | ||
84 | { | ||
85 | if (sMutex) sMutex->lock(); | ||
86 | mRef++; | ||
87 | if (sMutex) sMutex->unlock(); | ||
88 | } | ||
89 | |||
90 | S32 unref() | ||
91 | { | ||
92 | llassert(mRef >= 1); | ||
93 | if (sMutex) sMutex->lock(); | ||
94 | S32 res = --mRef; | ||
95 | if (sMutex) sMutex->unlock(); | ||
96 | if (0 == res) | ||
97 | { | ||
98 | delete this; | ||
99 | res = 0; | ||
100 | } | ||
101 | return res; | ||
102 | } | ||
103 | S32 getNumRefs() const | ||
104 | { | ||
105 | return mRef; | ||
106 | } | ||
107 | |||
108 | private: | ||
109 | S32 mRef; | ||
110 | }; | ||
111 | |||
112 | //---------------------------------------------------------------------------- | ||
113 | |||
114 | class LLRefCount | ||
115 | { | ||
116 | protected: | ||
117 | LLRefCount(const LLRefCount&); // not implemented | ||
118 | private: | ||
119 | LLRefCount&operator=(const LLRefCount&); // not implemented | ||
120 | |||
121 | protected: | ||
122 | virtual ~LLRefCount(); // use unref() | ||
123 | |||
124 | public: | ||
125 | LLRefCount(); | ||
126 | |||
127 | void ref() | ||
128 | { | ||
129 | mRef++; | ||
130 | } | ||
131 | |||
132 | S32 unref() | ||
133 | { | ||
134 | llassert(mRef >= 1); | ||
135 | if (0 == --mRef) | ||
136 | { | ||
137 | delete this; | ||
138 | return 0; | ||
139 | } | ||
140 | return mRef; | ||
141 | } | ||
142 | S32 getNumRefs() const | ||
143 | { | ||
144 | return mRef; | ||
145 | } | ||
146 | |||
147 | private: | ||
148 | S32 mRef; | ||
149 | }; | ||
150 | |||
151 | //---------------------------------------------------------------------------- | ||
152 | |||
153 | template <class Type> class LLPointer | ||
154 | { | ||
155 | public: | ||
156 | |||
157 | LLPointer() : | ||
158 | mPointer(NULL) | ||
159 | { | ||
160 | } | ||
161 | |||
162 | LLPointer(Type* ptr) : | ||
163 | mPointer(ptr) | ||
164 | { | ||
165 | ref(); | ||
166 | } | ||
167 | |||
168 | LLPointer(const LLPointer<Type>& ptr) : | ||
169 | mPointer(ptr.mPointer) | ||
170 | { | ||
171 | ref(); | ||
172 | } | ||
173 | |||
174 | // support conversion up the type hierarchy. See Item 45 in Effective C++, 3rd Ed. | ||
175 | template<typename Subclass> | ||
176 | LLPointer(const LLPointer<Subclass>& ptr) : | ||
177 | mPointer(ptr.get()) | ||
178 | { | ||
179 | ref(); | ||
180 | } | ||
181 | |||
182 | ~LLPointer() | ||
183 | { | ||
184 | unref(); | ||
185 | } | ||
186 | |||
187 | Type* get() const { return mPointer; } | ||
188 | const Type* operator->() const { return mPointer; } | ||
189 | Type* operator->() { return mPointer; } | ||
190 | const Type& operator*() const { return *mPointer; } | ||
191 | Type& operator*() { return *mPointer; } | ||
192 | |||
193 | operator BOOL() const { return (mPointer != NULL); } | ||
194 | operator bool() const { return (mPointer != NULL); } | ||
195 | bool operator!() const { return (mPointer == NULL); } | ||
196 | bool isNull() const { return (mPointer == NULL); } | ||
197 | bool notNull() const { return (mPointer != NULL); } | ||
198 | |||
199 | operator Type*() const { return mPointer; } | ||
200 | operator const Type*() const { return mPointer; } | ||
201 | bool operator !=(Type* ptr) const { return (mPointer != ptr); } | ||
202 | bool operator ==(Type* ptr) const { return (mPointer == ptr); } | ||
203 | bool operator ==(const LLPointer<Type>& ptr) const { return (mPointer == ptr.mPointer); } | ||
204 | bool operator < (const LLPointer<Type>& ptr) const { return (mPointer < ptr.mPointer); } | ||
205 | bool operator > (const LLPointer<Type>& ptr) const { return (mPointer > ptr.mPointer); } | ||
206 | |||
207 | LLPointer<Type>& operator =(Type* ptr) | ||
208 | { | ||
209 | if( mPointer != ptr ) | ||
210 | { | ||
211 | unref(); | ||
212 | mPointer = ptr; | ||
213 | ref(); | ||
214 | } | ||
215 | |||
216 | return *this; | ||
217 | } | ||
218 | |||
219 | LLPointer<Type>& operator =(const LLPointer<Type>& ptr) | ||
220 | { | ||
221 | if( mPointer != ptr.mPointer ) | ||
222 | { | ||
223 | unref(); | ||
224 | mPointer = ptr.mPointer; | ||
225 | ref(); | ||
226 | } | ||
227 | return *this; | ||
228 | } | ||
229 | |||
230 | // support assignment up the type hierarchy. See Item 45 in Effective C++, 3rd Ed. | ||
231 | template<typename Subclass> | ||
232 | LLPointer<Type>& operator =(const LLPointer<Subclass>& ptr) | ||
233 | { | ||
234 | if( mPointer != ptr.get() ) | ||
235 | { | ||
236 | unref(); | ||
237 | mPointer = ptr.get(); | ||
238 | ref(); | ||
239 | } | ||
240 | return *this; | ||
241 | } | ||
242 | |||
243 | protected: | ||
244 | void ref() | ||
245 | { | ||
246 | if (mPointer) | ||
247 | { | ||
248 | mPointer->ref(); | ||
249 | } | ||
250 | } | ||
251 | |||
252 | void unref() | ||
253 | { | ||
254 | if (mPointer) | ||
255 | { | ||
256 | Type *tempp = mPointer; | ||
257 | mPointer = NULL; | ||
258 | tempp->unref(); | ||
259 | if (mPointer != NULL) | ||
260 | { | ||
261 | llwarns << "Unreference did assignment to non-NULL because of destructor" << llendl; | ||
262 | unref(); | ||
263 | } | ||
264 | } | ||
265 | } | ||
266 | |||
267 | protected: | ||
268 | Type* mPointer; | ||
269 | }; | ||
270 | |||
271 | // LLInitializedPointer is just a pointer with a default constructor that initializes it to NULL | ||
272 | // NOT a smart pointer like LLPointer<> | ||
273 | // Useful for example in std::map<int,LLInitializedPointer<LLFoo> > | ||
274 | // (std::map uses the default constructor for creating new entries) | ||
275 | template <typename T> class LLInitializedPointer | ||
276 | { | ||
277 | public: | ||
278 | LLInitializedPointer() : mPointer(NULL) {} | ||
279 | ~LLInitializedPointer() { delete mPointer; } | ||
280 | |||
281 | const T* operator->() const { return mPointer; } | ||
282 | T* operator->() { return mPointer; } | ||
283 | const T& operator*() const { return *mPointer; } | ||
284 | T& operator*() { return *mPointer; } | ||
285 | operator const T*() const { return mPointer; } | ||
286 | operator T*() { return mPointer; } | ||
287 | T* operator=(T* x) { return (mPointer = x); } | ||
288 | operator bool() const { return mPointer != NULL; } | ||
289 | bool operator!() const { return mPointer == NULL; } | ||
290 | bool operator==(T* rhs) { return mPointer == rhs; } | ||
291 | bool operator==(const LLInitializedPointer<T>* rhs) { return mPointer == rhs.mPointer; } | ||
292 | |||
293 | protected: | ||
294 | T* mPointer; | ||
295 | }; | ||
296 | |||
297 | //---------------------------------------------------------------------------- | ||
298 | |||
299 | // LLSingleton implements the getInstance() method part of the Singleton pattern. It can't make | ||
300 | // the derived class constructors protected, though, so you have to do that yourself. | ||
301 | // The proper way to use LLSingleton is to inherit from it while using the typename that you'd | ||
302 | // like to be static as the template parameter, like so: | ||
303 | // class FooBar: public LLSingleton<FooBar> | ||
304 | // As currently written, it is not thread-safe. | ||
305 | template <typename T> | ||
306 | class LLSingleton | ||
307 | { | ||
308 | public: | ||
309 | static T* getInstance() | ||
310 | { | ||
311 | static T instance; | ||
312 | return &instance; | ||
313 | } | ||
314 | }; | ||
315 | |||
316 | //---------------------------------------------------------------------------- | ||
317 | |||
318 | #endif | ||
319 | |||