aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/llcommon/llmemory.h
diff options
context:
space:
mode:
authorJacek Antonelli2008-08-15 23:44:46 -0500
committerJacek Antonelli2008-08-15 23:44:46 -0500
commit38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4 (patch)
treeadca584755d22ca041a2dbfc35d4eca01f70b32c /linden/indra/llcommon/llmemory.h
parentREADME.txt (diff)
downloadmeta-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.h319
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
37extern S32 gTotalDAlloc;
38extern S32 gTotalDAUse;
39extern S32 gDACount;
40
41const U32 LLREFCOUNT_SENTINEL_VALUE = 0xAAAAAAAA;
42
43//----------------------------------------------------------------------------
44
45class LLMemory
46{
47public:
48 static void initClass();
49 static void cleanupClass();
50 static void freeReserve();
51private:
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
64class LLThreadSafeRefCount
65{
66public:
67 static void initClass(); // creates sMutex
68 static void cleanupClass(); // destroys sMutex
69
70private:
71 static LLMutex* sMutex;
72
73private:
74 LLThreadSafeRefCount(const LLThreadSafeRefCount&); // not implemented
75 LLThreadSafeRefCount&operator=(const LLThreadSafeRefCount&); // not implemented
76
77protected:
78 virtual ~LLThreadSafeRefCount(); // use unref()
79
80public:
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
108private:
109 S32 mRef;
110};
111
112//----------------------------------------------------------------------------
113
114class LLRefCount
115{
116protected:
117 LLRefCount(const LLRefCount&); // not implemented
118private:
119 LLRefCount&operator=(const LLRefCount&); // not implemented
120
121protected:
122 virtual ~LLRefCount(); // use unref()
123
124public:
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
147private:
148 S32 mRef;
149};
150
151//----------------------------------------------------------------------------
152
153template <class Type> class LLPointer
154{
155public:
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
243protected:
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
267protected:
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)
275template <typename T> class LLInitializedPointer
276{
277public:
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
293protected:
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.
305template <typename T>
306class LLSingleton
307{
308public:
309 static T* getInstance()
310 {
311 static T instance;
312 return &instance;
313 }
314};
315
316//----------------------------------------------------------------------------
317
318#endif
319