summaryrefslogtreecommitdiff
path: root/indra/llcommon
diff options
context:
space:
mode:
authorRichard Linden <none@none>2012-12-23 12:27:25 -0800
committerRichard Linden <none@none>2012-12-23 12:27:25 -0800
commit3fd640a6e3dea7a3551c239323d782fb082e1dbd (patch)
tree2e0736320792e74d10570087982fb13938315d52 /indra/llcommon
parent013f04cabec8e110ee659d9b3f75a4d25f114b7b (diff)
SH-3468 WIP add memory tracking base class
fixed crash on exit by making LLInstanceTracker iterators use atomic iterator nesting count for thread safety
Diffstat (limited to 'indra/llcommon')
-rw-r--r--indra/llcommon/llapr.cpp1
-rw-r--r--indra/llcommon/llapr.h137
-rw-r--r--indra/llcommon/llinstancetracker.cpp18
-rw-r--r--indra/llcommon/llinstancetracker.h27
-rw-r--r--indra/llcommon/llstl.h1
-rw-r--r--indra/llcommon/llthreadlocalpointer.h164
-rw-r--r--indra/llcommon/lltrace.h1
-rw-r--r--indra/llcommon/llworkerthread.h5
8 files changed, 209 insertions, 145 deletions
diff --git a/indra/llcommon/llapr.cpp b/indra/llcommon/llapr.cpp
index 6affdad61b..092c276936 100644
--- a/indra/llcommon/llapr.cpp
+++ b/indra/llcommon/llapr.cpp
@@ -29,6 +29,7 @@
#include "linden_common.h"
#include "llapr.h"
#include "apr_dso.h"
+#include "llthreadlocalpointer.h"
apr_pool_t *gAPRPoolp = NULL; // Global APR memory pool
LLVolatileAPRPool *LLAPRFile::sAPRFilePoolp = NULL ; //global volatile APR memory pool.
diff --git a/indra/llcommon/llapr.h b/indra/llcommon/llapr.h
index 2faf4aad2d..b3c9bfd58c 100644
--- a/indra/llcommon/llapr.h
+++ b/indra/llcommon/llapr.h
@@ -42,7 +42,6 @@
#include "apr_atomic.h"
#include "llstring.h"
-#include "llinstancetracker.h"
extern LL_COMMON_API apr_thread_mutex_t* gLogMutexp;
extern apr_thread_mutex_t* gCallStacksLogMutexp;
@@ -170,14 +169,17 @@ public:
LLAtomic32<Type>(Type x) {apr_atomic_set32(&mData, apr_uint32_t(x)); };
~LLAtomic32<Type>() {};
- operator const Type() { apr_uint32_t data = apr_atomic_read32(&mData); return Type(data); }
+ operator const Type() { return get(); }
Type operator =(const Type& x) { apr_atomic_set32(&mData, apr_uint32_t(x)); return Type(mData); }
void operator -=(Type x) { apr_atomic_sub32(&mData, apr_uint32_t(x)); }
void operator +=(Type x) { apr_atomic_add32(&mData, apr_uint32_t(x)); }
Type operator ++(int) { return apr_atomic_inc32(&mData); } // Type++
- Type operator --(int) { return apr_atomic_dec32(&mData); } // approximately --Type (0 if final is 0, non-zero otherwise)
+ Type operator ++() { apr_atomic_inc32(&mData); return get(); } // ++Type
+ Type operator --(int) { const Type result(get()); apr_atomic_dec32(&mData); return result; } // Type--
+ Type operator --() { return apr_atomic_dec32(&mData); } // approximately --Type (0 if final is 0, non-zero otherwise)
private:
+ const Type get() { apr_uint32_t data = apr_atomic_read32(&mData); return Type(data); }
apr_uint32_t mData;
};
@@ -262,134 +264,5 @@ public:
//*******************************************************************************************************************************
};
-class LLThreadLocalPointerBase : public LLInstanceTracker<LLThreadLocalPointerBase>
-{
-public:
- LLThreadLocalPointerBase()
- : mThreadKey(NULL)
- {
- if (sInitialized)
- {
- initStorage();
- }
- }
-
- LLThreadLocalPointerBase( const LLThreadLocalPointerBase& other)
- : mThreadKey(NULL)
- {
- if (sInitialized)
- {
- initStorage();
- }
- }
-
- ~LLThreadLocalPointerBase()
- {
- destroyStorage();
- }
-
- static void initAllThreadLocalStorage();
- static void destroyAllThreadLocalStorage();
-
-protected:
- void set(void* value);
-
- LL_FORCE_INLINE void* get()
- {
- // llassert(sInitialized);
- void* ptr;
- apr_status_t result =
- apr_threadkey_private_get(&ptr, mThreadKey);
- if (result != APR_SUCCESS)
- {
- ll_apr_warn_status(result);
- llerrs << "Failed to get thread local data" << llendl;
- }
- return ptr;
- }
-
- LL_FORCE_INLINE const void* get() const
- {
- void* ptr;
- apr_status_t result =
- apr_threadkey_private_get(&ptr, mThreadKey);
- if (result != APR_SUCCESS)
- {
- ll_apr_warn_status(result);
- llerrs << "Failed to get thread local data" << llendl;
- }
- return ptr;
- }
-
- void initStorage();
- void destroyStorage();
-
-protected:
- apr_threadkey_t* mThreadKey;
- static bool sInitialized;
-};
-
-template <typename T>
-class LLThreadLocalPointer : public LLThreadLocalPointerBase
-{
-public:
-
- LLThreadLocalPointer()
- {}
-
- explicit LLThreadLocalPointer(T* value)
- {
- set(value);
- }
-
-
- LLThreadLocalPointer(const LLThreadLocalPointer<T>& other)
- : LLThreadLocalPointerBase(other)
- {
- set(other.get());
- }
-
- LL_FORCE_INLINE T* get()
- {
- return (T*)LLThreadLocalPointerBase::get();
- }
-
- const T* get() const
- {
- return (const T*)LLThreadLocalPointerBase::get();
- }
-
- T* operator -> ()
- {
- return (T*)get();
- }
-
- const T* operator -> () const
- {
- return (T*)get();
- }
-
- T& operator*()
- {
- return *(T*)get();
- }
-
- const T& operator*() const
- {
- return *(T*)get();
- }
-
- LLThreadLocalPointer<T>& operator = (T* value)
- {
- set((void*)value);
- return *this;
- }
-
- bool operator ==(T* other)
- {
- if (!sInitialized) return false;
- return get() == other;
- }
-};
#endif // LL_LLAPR_H
diff --git a/indra/llcommon/llinstancetracker.cpp b/indra/llcommon/llinstancetracker.cpp
index 5dc3ea5d7b..071a637cda 100644
--- a/indra/llcommon/llinstancetracker.cpp
+++ b/indra/llcommon/llinstancetracker.cpp
@@ -27,6 +27,8 @@
#include "linden_common.h"
// associated header
#include "llinstancetracker.h"
+#include "llapr.h"
+
// STL headers
// std headers
// external library headers
@@ -47,3 +49,19 @@ void * & LLInstanceTrackerBase::getInstances(std::type_info const & info)
InstancesMap::mapped_type()))
.first->second;
}
+
+void LLInstanceTrackerBase::StaticBase::incrementDepth()
+{
+ apr_atomic_inc32(&sIterationNestDepth);
+}
+
+void LLInstanceTrackerBase::StaticBase::decrementDepth()
+{
+ apr_atomic_dec32(&sIterationNestDepth);
+}
+
+U32 LLInstanceTrackerBase::StaticBase::getDepth()
+{
+ apr_uint32_t data = apr_atomic_read32(&sIterationNestDepth);
+ return data;
+}
diff --git a/indra/llcommon/llinstancetracker.h b/indra/llcommon/llinstancetracker.h
index 3a1187a4c1..9dd6d4a7ed 100644
--- a/indra/llcommon/llinstancetracker.h
+++ b/indra/llcommon/llinstancetracker.h
@@ -70,7 +70,12 @@ protected:
StaticBase():
sIterationNestDepth(0)
{}
- S32 sIterationNestDepth;
+
+ void incrementDepth();
+ void decrementDepth();
+ U32 getDepth();
+ private:
+ U32 sIterationNestDepth;
};
};
@@ -99,12 +104,12 @@ public:
instance_iter(const typename InstanceMap::iterator& it)
: mIterator(it)
{
- ++getStatic().sIterationNestDepth;
+ getStatic().incrementDepth();
}
~instance_iter()
{
- --getStatic().sIterationNestDepth;
+ getStatic().decrementDepth();
}
@@ -133,18 +138,18 @@ public:
key_iter(typename InstanceMap::iterator it)
: mIterator(it)
{
- ++getStatic().sIterationNestDepth;
+ getStatic().incrementDepth();
}
key_iter(const key_iter& other)
: mIterator(other.mIterator)
{
- ++getStatic().sIterationNestDepth;
+ getStatic().incrementDepth();
}
~key_iter()
{
- --getStatic().sIterationNestDepth;
+ getStatic().decrementDepth();
}
@@ -203,7 +208,7 @@ protected:
virtual ~LLInstanceTracker()
{
// it's unsafe to delete instances of this type while all instances are being iterated over.
- llassert_always(getStatic().sIterationNestDepth == 0);
+ llassert_always(getStatic().getDepth() == 0);
remove_();
}
virtual void setKey(KEY key) { remove_(); add_(key); }
@@ -262,18 +267,18 @@ public:
instance_iter(const typename InstanceSet::iterator& it)
: mIterator(it)
{
- ++getStatic().sIterationNestDepth;
+ getStatic().incrementDepth();
}
instance_iter(const instance_iter& other)
: mIterator(other.mIterator)
{
- ++getStatic().sIterationNestDepth;
+ getStatic().incrementDepth();
}
~instance_iter()
{
- --getStatic().sIterationNestDepth;
+ getStatic().decrementDepth();
}
private:
@@ -306,7 +311,7 @@ protected:
virtual ~LLInstanceTracker()
{
// it's unsafe to delete instances of this type while all instances are being iterated over.
- llassert_always(getStatic().sIterationNestDepth == 0);
+ llassert_always(getStatic().getDepth() == 0);
getSet_().erase(static_cast<T*>(this));
}
diff --git a/indra/llcommon/llstl.h b/indra/llcommon/llstl.h
index d3941e1bc9..424138dad1 100644
--- a/indra/llcommon/llstl.h
+++ b/indra/llcommon/llstl.h
@@ -31,6 +31,7 @@
#include <algorithm>
#include <map>
#include <vector>
+#include <list>
#include <set>
#include <deque>
#include <typeinfo>
diff --git a/indra/llcommon/llthreadlocalpointer.h b/indra/llcommon/llthreadlocalpointer.h
new file mode 100644
index 0000000000..d40a8b5a27
--- /dev/null
+++ b/indra/llcommon/llthreadlocalpointer.h
@@ -0,0 +1,164 @@
+/**
+ * @file llthreadlocalpointer.h
+ * @author Richard
+ * @brief Pointer class that manages a distinct value per thread
+ *
+ * $LicenseInfo:firstyear=2004&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLTHREADLOCALPOINTER_H
+#define LL_LLTHREADLOCALPOINTER_H
+
+#include "llinstancetracker.h"
+#include "llapr.h"
+
+class LLThreadLocalPointerBase : public LLInstanceTracker<LLThreadLocalPointerBase>
+{
+public:
+ LLThreadLocalPointerBase()
+ : mThreadKey(NULL)
+ {
+ if (sInitialized)
+ {
+ initStorage();
+ }
+ }
+
+ LLThreadLocalPointerBase( const LLThreadLocalPointerBase& other)
+ : mThreadKey(NULL)
+ {
+ if (sInitialized)
+ {
+ initStorage();
+ }
+ }
+
+ ~LLThreadLocalPointerBase()
+ {
+ destroyStorage();
+ }
+
+ static void initAllThreadLocalStorage();
+ static void destroyAllThreadLocalStorage();
+
+protected:
+ void set(void* value);
+
+ LL_FORCE_INLINE void* get()
+ {
+ // llassert(sInitialized);
+ void* ptr;
+ apr_status_t result =
+ apr_threadkey_private_get(&ptr, mThreadKey);
+ if (result != APR_SUCCESS)
+ {
+ ll_apr_warn_status(result);
+ llerrs << "Failed to get thread local data" << llendl;
+ }
+ return ptr;
+ }
+
+ LL_FORCE_INLINE const void* get() const
+ {
+ void* ptr;
+ apr_status_t result =
+ apr_threadkey_private_get(&ptr, mThreadKey);
+ if (result != APR_SUCCESS)
+ {
+ ll_apr_warn_status(result);
+ llerrs << "Failed to get thread local data" << llendl;
+ }
+ return ptr;
+ }
+
+ void initStorage();
+ void destroyStorage();
+
+protected:
+ apr_threadkey_t* mThreadKey;
+ static bool sInitialized;
+};
+
+template <typename T>
+class LLThreadLocalPointer : public LLThreadLocalPointerBase
+{
+public:
+
+ LLThreadLocalPointer()
+ {}
+
+ explicit LLThreadLocalPointer(T* value)
+ {
+ set(value);
+ }
+
+
+ LLThreadLocalPointer(const LLThreadLocalPointer<T>& other)
+ : LLThreadLocalPointerBase(other)
+ {
+ set(other.get());
+ }
+
+ LL_FORCE_INLINE T* get()
+ {
+ return (T*)LLThreadLocalPointerBase::get();
+ }
+
+ const T* get() const
+ {
+ return (const T*)LLThreadLocalPointerBase::get();
+ }
+
+ T* operator -> ()
+ {
+ return (T*)get();
+ }
+
+ const T* operator -> () const
+ {
+ return (T*)get();
+ }
+
+ T& operator*()
+ {
+ return *(T*)get();
+ }
+
+ const T& operator*() const
+ {
+ return *(T*)get();
+ }
+
+ LLThreadLocalPointer<T>& operator = (T* value)
+ {
+ set((void*)value);
+ return *this;
+ }
+
+ bool operator ==(T* other)
+ {
+ if (!sInitialized) return false;
+ return get() == other;
+ }
+};
+
+#endif // LL_LLTHREADLOCALPOINTER_H
diff --git a/indra/llcommon/lltrace.h b/indra/llcommon/lltrace.h
index 4bb19f6070..05191cafaa 100644
--- a/indra/llcommon/lltrace.h
+++ b/indra/llcommon/lltrace.h
@@ -34,6 +34,7 @@
#include "llrefcount.h"
#include "llunit.h"
#include "llapr.h"
+#include "llthreadlocalpointer.h"
#include <list>
diff --git a/indra/llcommon/llworkerthread.h b/indra/llcommon/llworkerthread.h
index be46394d6e..09776816a8 100644
--- a/indra/llcommon/llworkerthread.h
+++ b/indra/llcommon/llworkerthread.h
@@ -26,10 +26,11 @@
#ifndef LL_LLWORKERTHREAD_H
#define LL_LLWORKERTHREAD_H
-#include <queue>
-#include <string>
+#include <list>
#include <map>
+#include <queue>
#include <set>
+#include <string>
#include "llqueuedthread.h"
#include "llapr.h"