From df08808640031bd27a11177ea49a08f797d2d570 Mon Sep 17 00:00:00 2001
From: "Graham Madarasz (Graham)" <graham@lindenlab.com>
Date: Thu, 28 Feb 2013 09:33:41 -0800
Subject: Improve perf of GLSL uniform lookups by name

---
 indra/llcommon/llstringtable.h | 480 ++++++++++++++++++++++-------------------
 1 file changed, 263 insertions(+), 217 deletions(-)

(limited to 'indra/llcommon')

diff --git a/indra/llcommon/llstringtable.h b/indra/llcommon/llstringtable.h
index 59d7372ed4..4f6417328c 100644
--- a/indra/llcommon/llstringtable.h
+++ b/indra/llcommon/llstringtable.h
@@ -1,217 +1,263 @@
-/** 
- * @file llstringtable.h
- * @brief The LLStringTable class provides a _fast_ method for finding
- * unique copies of strings.
- *
- * $LicenseInfo:firstyear=2001&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_STRING_TABLE_H
-#define LL_STRING_TABLE_H
-
-#include "lldefs.h"
-#include "llformat.h"
-#include "llstl.h"
-#include <list>
-#include <set>
-
-#if LL_WINDOWS
-# if (_MSC_VER >= 1300 && _MSC_VER < 1400)
-#  define STRING_TABLE_HASH_MAP 1
-# endif
-#else
-//# define STRING_TABLE_HASH_MAP 1
-#endif
-
-#if STRING_TABLE_HASH_MAP
-# if LL_WINDOWS
-#  include <hash_map>
-# else
-#  include <ext/hash_map>
-# endif
-#endif
-
-const U32 MAX_STRINGS_LENGTH = 256;
-
-class LL_COMMON_API LLStringTableEntry
-{
-public:
-	LLStringTableEntry(const char *str);
-	~LLStringTableEntry();
-
-	void incCount()		{ mCount++; }
-	BOOL decCount()		{ return --mCount; }
-
-	char *mString;
-	S32  mCount;
-};
-
-class LL_COMMON_API LLStringTable
-{
-public:
-	LLStringTable(int tablesize);
-	~LLStringTable();
-
-	char *checkString(const char *str);
-	char *checkString(const std::string& str);
-	LLStringTableEntry *checkStringEntry(const char *str);
-	LLStringTableEntry *checkStringEntry(const std::string& str);
-
-	char *addString(const char *str);
-	char *addString(const std::string& str);
-	LLStringTableEntry *addStringEntry(const char *str);
-	LLStringTableEntry *addStringEntry(const std::string& str);
-	void  removeString(const char *str);
-
-	S32 mMaxEntries;
-	S32 mUniqueEntries;
-	
-#if STRING_TABLE_HASH_MAP
-#if LL_WINDOWS
-	typedef std::hash_multimap<U32, LLStringTableEntry *> string_hash_t;
-#else
-	typedef __gnu_cxx::hash_multimap<U32, LLStringTableEntry *> string_hash_t;
-#endif
-	string_hash_t mStringHash;
-#else
-	typedef std::list<LLStringTableEntry *> string_list_t;
-	typedef string_list_t * string_list_ptr_t;
-	string_list_ptr_t	*mStringList;
-#endif	
-};
-
-extern LL_COMMON_API LLStringTable gStringTable;
-
-//============================================================================
-
-// This class is designed to be used locally,
-// e.g. as a member of an LLXmlTree
-// Strings can be inserted only, then quickly looked up
-
-typedef const std::string* LLStdStringHandle;
-
-class LL_COMMON_API LLStdStringTable
-{
-public:
-	LLStdStringTable(S32 tablesize = 0)
-	{
-		if (tablesize == 0)
-		{
-			tablesize = 256; // default
-		}
-		// Make sure tablesize is power of 2
-		for (S32 i = 31; i>0; i--)
-		{
-			if (tablesize & (1<<i))
-			{
-				if (tablesize >= (3<<(i-1)))
-					tablesize = (1<<(i+1));
-				else
-					tablesize = (1<<i);
-				break;
-			}
-		}
-		mTableSize = tablesize;
-		mStringList = new string_set_t[tablesize];
-	}
-	~LLStdStringTable()
-	{
-		cleanup();
-		delete[] mStringList;
-	}
-	void cleanup()
-	{
-		// remove strings
-		for (S32 i = 0; i<mTableSize; i++)
-		{
-			string_set_t& stringset = mStringList[i];
-			for (string_set_t::iterator iter = stringset.begin(); iter != stringset.end(); iter++)
-			{
-				delete *iter;
-			}
-			stringset.clear();
-		}
-	}
-
-	LLStdStringHandle lookup(const std::string& s)
-	{
-		U32 hashval = makehash(s);
-		return lookup(hashval, s);
-	}
-	
-	LLStdStringHandle checkString(const std::string& s)
-	{
-		U32 hashval = makehash(s);
-		return lookup(hashval, s);
-	}
-
-	LLStdStringHandle insert(const std::string& s)
-	{
-		U32 hashval = makehash(s);
-		LLStdStringHandle result = lookup(hashval, s);
-		if (result == NULL)
-		{
-			result = new std::string(s);
-			mStringList[hashval].insert(result);
-		}
-		return result;
-	}
-	LLStdStringHandle addString(const std::string& s)
-	{
-		return insert(s);
-	}
-	
-private:
-	U32 makehash(const std::string& s)
-	{
-		S32 len = (S32)s.size();
-		const char* c = s.c_str();
-		U32 hashval = 0;
-		for (S32 i=0; i<len; i++)
-		{
-			hashval = ((hashval<<5) + hashval) + *c++;
-		}
-		return hashval & (mTableSize-1);
-	}
-	LLStdStringHandle lookup(U32 hashval, const std::string& s)
-	{
-		string_set_t& stringset = mStringList[hashval];
-		LLStdStringHandle handle = &s;
-		string_set_t::iterator iter = stringset.find(handle); // compares actual strings
-		if (iter != stringset.end())
-		{
-			return *iter;
-		}
-		else
-		{
-			return NULL;
-		}
-	}
-	
-private:
-	S32 mTableSize;
-	typedef std::set<LLStdStringHandle, compare_pointer_contents<std::string> > string_set_t;
-	string_set_t* mStringList; // [mTableSize]
-};
-
-
-#endif
+/** 
+ * @file llstringtable.h
+ * @brief The LLStringTable class provides a _fast_ method for finding
+ * unique copies of strings.
+ *
+ * $LicenseInfo:firstyear=2001&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_STRING_TABLE_H
+#define LL_STRING_TABLE_H
+
+#include "lldefs.h"
+#include "llformat.h"
+#include "llstl.h"
+#include <list>
+#include <set>
+#include <hash_map>
+
+#if LL_WINDOWS
+# if (_MSC_VER >= 1300 && _MSC_VER < 1400)
+#  define STRING_TABLE_HASH_MAP 1
+# endif
+#else
+//# define STRING_TABLE_HASH_MAP 1
+#endif
+
+#if STRING_TABLE_HASH_MAP
+# if LL_WINDOWS
+#  include <hash_map>
+# else
+#  include <ext/hash_map>
+# endif
+#endif
+
+class LLStaticHashedString
+{
+public:
+
+	LLStaticHashedString(const std::string& s)
+	{
+		string_hash = makehash(s);
+		string		= s;
+	}
+
+	const std::string&	String() const { return string;		}
+	size_t				Hash()	 const { return string_hash;  }
+
+protected:
+
+	size_t makehash(const std::string& s)
+	{
+		size_t len = s.size();
+		const char* c = s.c_str();
+		size_t hashval = 0;
+		for (size_t i=0; i<len; i++)
+		{
+			hashval = ((hashval<<5) + hashval) + *c++;
+		}
+		return hashval;
+	}
+
+	std::string string;
+	size_t		string_hash;
+};
+
+template<class T>
+struct LLStaticStringHasher
+{
+	enum { bucket_size = 8 };
+	size_t operator()(const T& key_value)		   const { return key_value.Hash();			  }
+	bool operator()(const T& left, const T& right) const { return left.Hash() < right.Hash(); }
+};
+
+template< typename MappedObject >
+class LL_COMMON_API LLStaticStringTable
+	: public std::hash_map< LLStaticHashedString , MappedObject, LLStaticStringHasher< LLStaticHashedString > >
+{
+};
+
+const U32 MAX_STRINGS_LENGTH = 256;
+
+class LL_COMMON_API LLStringTableEntry
+{
+public:
+	LLStringTableEntry(const char *str);
+	~LLStringTableEntry();
+
+	void incCount()		{ mCount++; }
+	BOOL decCount()		{ return --mCount; }
+
+	char *mString;
+	S32  mCount;
+};
+
+class LL_COMMON_API LLStringTable
+{
+public:
+	LLStringTable(int tablesize);
+	~LLStringTable();
+
+	char *checkString(const char *str);
+	char *checkString(const std::string& str);
+	LLStringTableEntry *checkStringEntry(const char *str);
+	LLStringTableEntry *checkStringEntry(const std::string& str);
+
+	char *addString(const char *str);
+	char *addString(const std::string& str);
+	LLStringTableEntry *addStringEntry(const char *str);
+	LLStringTableEntry *addStringEntry(const std::string& str);
+	void  removeString(const char *str);
+
+	S32 mMaxEntries;
+	S32 mUniqueEntries;
+	
+#if STRING_TABLE_HASH_MAP
+#if LL_WINDOWS
+	typedef std::hash_multimap<U32, LLStringTableEntry *> string_hash_t;
+#else
+	typedef __gnu_cxx::hash_multimap<U32, LLStringTableEntry *> string_hash_t;
+#endif
+	string_hash_t mStringHash;
+#else
+	typedef std::list<LLStringTableEntry *> string_list_t;
+	typedef string_list_t * string_list_ptr_t;
+	string_list_ptr_t	*mStringList;
+#endif	
+};
+
+extern LL_COMMON_API LLStringTable gStringTable;
+
+//============================================================================
+
+// This class is designed to be used locally,
+// e.g. as a member of an LLXmlTree
+// Strings can be inserted only, then quickly looked up
+
+typedef const std::string* LLStdStringHandle;
+
+class LL_COMMON_API LLStdStringTable
+{
+public:
+	LLStdStringTable(S32 tablesize = 0)
+	{
+		if (tablesize == 0)
+		{
+			tablesize = 256; // default
+		}
+		// Make sure tablesize is power of 2
+		for (S32 i = 31; i>0; i--)
+		{
+			if (tablesize & (1<<i))
+			{
+				if (tablesize >= (3<<(i-1)))
+					tablesize = (1<<(i+1));
+				else
+					tablesize = (1<<i);
+				break;
+			}
+		}
+		mTableSize = tablesize;
+		mStringList = new string_set_t[tablesize];
+	}
+	~LLStdStringTable()
+	{
+		cleanup();
+		delete[] mStringList;
+	}
+	void cleanup()
+	{
+		// remove strings
+		for (S32 i = 0; i<mTableSize; i++)
+		{
+			string_set_t& stringset = mStringList[i];
+			for (string_set_t::iterator iter = stringset.begin(); iter != stringset.end(); iter++)
+			{
+				delete *iter;
+			}
+			stringset.clear();
+		}
+	}
+
+	LLStdStringHandle lookup(const std::string& s)
+	{
+		U32 hashval = makehash(s);
+		return lookup(hashval, s);
+	}
+	
+	LLStdStringHandle checkString(const std::string& s)
+	{
+		U32 hashval = makehash(s);
+		return lookup(hashval, s);
+	}
+
+	LLStdStringHandle insert(const std::string& s)
+	{
+		U32 hashval = makehash(s);
+		LLStdStringHandle result = lookup(hashval, s);
+		if (result == NULL)
+		{
+			result = new std::string(s);
+			mStringList[hashval].insert(result);
+		}
+		return result;
+	}
+	LLStdStringHandle addString(const std::string& s)
+	{
+		return insert(s);
+	}
+	
+private:
+	U32 makehash(const std::string& s)
+	{
+		S32 len = (S32)s.size();
+		const char* c = s.c_str();
+		U32 hashval = 0;
+		for (S32 i=0; i<len; i++)
+		{
+			hashval = ((hashval<<5) + hashval) + *c++;
+		}
+		return hashval & (mTableSize-1);
+	}
+	LLStdStringHandle lookup(U32 hashval, const std::string& s)
+	{
+		string_set_t& stringset = mStringList[hashval];
+		LLStdStringHandle handle = &s;
+		string_set_t::iterator iter = stringset.find(handle); // compares actual strings
+		if (iter != stringset.end())
+		{
+			return *iter;
+		}
+		else
+		{
+			return NULL;
+		}
+	}
+	
+private:
+	S32 mTableSize;
+	typedef std::set<LLStdStringHandle, compare_pointer_contents<std::string> > string_set_t;
+	string_set_t* mStringList; // [mTableSize]
+};
+
+
+#endif
-- 
cgit v1.2.3


From 93eaccae6fe6e8442a3c6e5a2d40a408aa44df77 Mon Sep 17 00:00:00 2001
From: "Graham Madarasz (Graham)" <graham@lindenlab.com>
Date: Thu, 28 Feb 2013 15:35:14 -0800
Subject: Modify LLInstanceTracker to avoid using a map of strings to find a
 map of foo to find some pointers

---
 indra/llcommon/lleventapi.h          |  5 ++--
 indra/llcommon/lleventtimer.h        |  3 ++-
 indra/llcommon/llfasttimer.h         |  5 ++--
 indra/llcommon/llinstancetracker.cpp | 14 ++++-------
 indra/llcommon/llinstancetracker.h   | 46 ++++++++++++++++++++++++++++--------
 indra/llcommon/llleap.h              |  3 ++-
 6 files changed, 51 insertions(+), 25 deletions(-)

(limited to 'indra/llcommon')

diff --git a/indra/llcommon/lleventapi.h b/indra/llcommon/lleventapi.h
index 1a37d780b6..10c7e7a23f 100644
--- a/indra/llcommon/lleventapi.h
+++ b/indra/llcommon/lleventapi.h
@@ -41,12 +41,13 @@
  * Deriving from LLInstanceTracker lets us enumerate instances.
  */
 class LL_COMMON_API LLEventAPI: public LLDispatchListener,
-                  public LLInstanceTracker<LLEventAPI, std::string>
+                  public INSTANCE_TRACKER_KEYED(LLEventAPI, std::string)
 {
     typedef LLDispatchListener lbase;
-    typedef LLInstanceTracker<LLEventAPI, std::string> ibase;
+    typedef INSTANCE_TRACKER_KEYED(LLEventAPI, std::string) ibase;
 
 public:
+
     /**
      * @param name LLEventPump name on which this LLEventAPI will listen. This
      * also serves as the LLInstanceTracker instance key.
diff --git a/indra/llcommon/lleventtimer.h b/indra/llcommon/lleventtimer.h
index 7f42623d01..e55f851758 100644
--- a/indra/llcommon/lleventtimer.h
+++ b/indra/llcommon/lleventtimer.h
@@ -33,9 +33,10 @@
 #include "lltimer.h"
 
 // class for scheduling a function to be called at a given frequency (approximate, inprecise)
-class LL_COMMON_API LLEventTimer : public LLInstanceTracker<LLEventTimer>
+class LL_COMMON_API LLEventTimer : public INSTANCE_TRACKER(LLEventTimer)
 {
 public:
+
 	LLEventTimer(F32 period);	// period is the amount of time between each call to tick() in seconds
 	LLEventTimer(const LLDate& time);
 	virtual ~LLEventTimer();
diff --git a/indra/llcommon/llfasttimer.h b/indra/llcommon/llfasttimer.h
index e42e549df5..440d42ab5a 100644
--- a/indra/llcommon/llfasttimer.h
+++ b/indra/llcommon/llfasttimer.h
@@ -63,7 +63,7 @@ public:
 
 	// stores a "named" timer instance to be reused via multiple LLFastTimer stack instances
 	class LL_COMMON_API NamedTimer
-	:	public LLInstanceTracker<NamedTimer>
+	:	public LLInstanceTracker<NamedTimer, InstanceTrackType_NamedTimer >
 	{
 		friend class DeclareTimer;
 	public:
@@ -137,10 +137,11 @@ public:
 
 	// used to statically declare a new named timer
 	class LL_COMMON_API DeclareTimer
-	:	public LLInstanceTracker<DeclareTimer>
+	:	public LLInstanceTracker< DeclareTimer, InstanceTrackType_DeclareTimer >
 	{
 		friend class LLFastTimer;
 	public:
+
 		DeclareTimer(const std::string& name, bool open);
 		DeclareTimer(const std::string& name);
 
diff --git a/indra/llcommon/llinstancetracker.cpp b/indra/llcommon/llinstancetracker.cpp
index 5dc3ea5d7b..0804be358f 100644
--- a/indra/llcommon/llinstancetracker.cpp
+++ b/indra/llcommon/llinstancetracker.cpp
@@ -32,18 +32,14 @@
 // external library headers
 // other Linden headers
 
-//static 
-void * & LLInstanceTrackerBase::getInstances(std::type_info const & info)
-{
-	typedef std::map<std::string, void *> InstancesMap;
-	static InstancesMap instances;
+static void* sInstanceTrackerData[ kInstanceTrackTypeCount ] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
 
+void * & LLInstanceTrackerBase::getInstances(InstanceTrackType t)
+{
 	// std::map::insert() is just what we want here. You attempt to insert a
 	// (key, value) pair. If the specified key doesn't yet exist, it inserts
 	// the pair and returns a std::pair of (iterator, true). If the specified
 	// key DOES exist, insert() simply returns (iterator, false). One lookup
 	// handles both cases.
-	return instances.insert(InstancesMap::value_type(info.name(),
-													 InstancesMap::mapped_type()))
-		.first->second;
-}
+	return sInstanceTrackerData[t];
+}
\ No newline at end of file
diff --git a/indra/llcommon/llinstancetracker.h b/indra/llcommon/llinstancetracker.h
index 403df08990..70bccde992 100644
--- a/indra/llcommon/llinstancetracker.h
+++ b/indra/llcommon/llinstancetracker.h
@@ -38,6 +38,31 @@
 #include <boost/iterator/transform_iterator.hpp>
 #include <boost/iterator/indirect_iterator.hpp>
 
+enum InstanceTrackType
+{
+	InstanceTrackType_LLEventAPI,
+	InstanceTrackType_LLEventTimer,
+	InstanceTrackType_NamedTimer,
+	InstanceTrackType_DeclareTimer,
+	InstanceTrackType_LLLeap,
+	InstanceTrackType_LLGLNamePool,
+	InstanceTrackType_LLConsole,
+	InstanceTrackType_LLFloater,
+	InstanceTrackType_LLFloaterWebContent,
+	InstanceTrackType_LLLayoutStack,
+	InstanceTrackType_LLNotificationContext,
+	InstanceTrackType_LLWindow,
+	InstanceTrackType_LLControlGroup,
+	InstanceTrackType_LLControlCache,
+	InstanceTrackType_LLMediaCtrl,
+	InstanceTrackType_LLNameListCtrl,
+	InstanceTrackType_LLToast,
+	kInstanceTrackTypeCount
+};
+
+#define INSTANCE_TRACKER(T)			LLInstanceTracker< T, InstanceTrackType_##T >
+#define INSTANCE_TRACKER_KEYED(T,K)	LLInstanceTracker< T, InstanceTrackType_##T, K >
+
 /**
  * Base class manages "class-static" data that must actually have singleton
  * semantics: one instance per process, rather than one instance per module as
@@ -47,14 +72,15 @@ class LL_COMMON_API LLInstanceTrackerBase : public boost::noncopyable
 {
 protected:
 	/// Get a process-unique void* pointer slot for the specified type_info
-	static void * & getInstances(std::type_info const & info);
+	//static void * & getInstances(std::type_info const & info);
+	static void * & getInstances(InstanceTrackType t);
 
 	/// Find or create a STATICDATA instance for the specified TRACKED class.
 	/// STATICDATA must be default-constructible.
-	template<typename STATICDATA, class TRACKED>
+	template<typename STATICDATA, class TRACKED, class INST, InstanceTrackType TRACKEDTYPE>
 	static STATICDATA& getStatic()
 	{
-		void *& instances = getInstances(typeid(TRACKED));
+		void *& instances = getInstances(TRACKEDTYPE);
 		if (! instances)
 		{
 			instances = new STATICDATA;
@@ -78,16 +104,16 @@ protected:
 /// The (optional) key associates a value of type KEY with a given instance of T, for quick lookup
 /// If KEY is not provided, then instances are stored in a simple set
 /// @NOTE: see explicit specialization below for default KEY==T* case
-template<typename T, typename KEY = T*>
+template<typename T, enum InstanceTrackType TRACKED, typename KEY = T*>
 class LLInstanceTracker : public LLInstanceTrackerBase
 {
-	typedef LLInstanceTracker<T, KEY> MyT;
+	typedef LLInstanceTracker<T, TRACKED, KEY> MyT;
 	typedef typename std::map<KEY, T*> InstanceMap;
 	struct StaticData: public StaticBase
 	{
 		InstanceMap sMap;
 	};
-	static StaticData& getStatic() { return LLInstanceTrackerBase::getStatic<StaticData, MyT>(); }
+	static StaticData& getStatic() { return LLInstanceTrackerBase::getStatic<StaticData, MyT, T, TRACKED>(); }
 	static InstanceMap& getMap_() { return getStatic().sMap; }
 
 public:
@@ -226,16 +252,16 @@ private:
 
 /// explicit specialization for default case where KEY is T*
 /// use a simple std::set<T*>
-template<typename T>
-class LLInstanceTracker<T, T*> : public LLInstanceTrackerBase
+template<typename T, enum InstanceTrackType TRACKED>
+class LLInstanceTracker<T, TRACKED, T*> : public LLInstanceTrackerBase
 {
-	typedef LLInstanceTracker<T, T*> MyT;
+	typedef LLInstanceTracker<T, TRACKED, T*> MyT;
 	typedef typename std::set<T*> InstanceSet;
 	struct StaticData: public StaticBase
 	{
 		InstanceSet sSet;
 	};
-	static StaticData& getStatic() { return LLInstanceTrackerBase::getStatic<StaticData, MyT>(); }
+	static StaticData& getStatic() { return LLInstanceTrackerBase::getStatic<StaticData, MyT, T, TRACKED>(); }
 	static InstanceSet& getSet_() { return getStatic().sSet; }
 
 public:
diff --git a/indra/llcommon/llleap.h b/indra/llcommon/llleap.h
index 1a1ad23d39..d4e138f4be 100644
--- a/indra/llcommon/llleap.h
+++ b/indra/llcommon/llleap.h
@@ -29,9 +29,10 @@
  * LLLeap* pointer should be validated before use by
  * LLLeap::getInstance(LLLeap*) (see LLInstanceTracker).
  */
-class LL_COMMON_API LLLeap: public LLInstanceTracker<LLLeap>
+class LL_COMMON_API LLLeap: public INSTANCE_TRACKER(LLLeap)
 {
 public:
+
     /**
      * Pass a brief string description, mostly for logging purposes. The desc
      * need not be unique, but obviously the clearer we can make it, the
-- 
cgit v1.2.3


From ae1aa461ea3f96c092e2a50ae40f290b03b25356 Mon Sep 17 00:00:00 2001
From: "Graham Madarasz (Graham)" <graham@lindenlab.com>
Date: Thu, 28 Feb 2013 16:37:09 -0800
Subject: Attempt at a faster ThreadSafeRefCount class

---
 indra/llcommon/llapr.h      |  8 +++++++-
 indra/llcommon/llthread.cpp |  8 --------
 indra/llcommon/llthread.h   | 40 ++++++++++++++++++----------------------
 3 files changed, 25 insertions(+), 31 deletions(-)

(limited to 'indra/llcommon')

diff --git a/indra/llcommon/llapr.h b/indra/llcommon/llapr.h
index 034546c3f3..8042fe2502 100644
--- a/indra/llcommon/llapr.h
+++ b/indra/llcommon/llapr.h
@@ -164,14 +164,20 @@ public:
 	~LLAtomic32<Type>() {};
 
 	operator const Type() { apr_uint32_t data = apr_atomic_read32(&mData); return Type(data); }
+	
+	Type	CurrentValue() const { apr_uint32_t data = apr_atomic_read32(const_cast< volatile apr_uint32_t* >(&mData)); return Type(data); }
+
 	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 ++() { return apr_atomic_inc32(&mData); } // Type++
+	Type operator --() { return apr_atomic_dec32(&mData); } // approximately --Type (0 if final is 0, non-zero otherwise)
 	
 private:
-	apr_uint32_t mData;
+	volatile apr_uint32_t mData;
 };
 
 typedef LLAtomic32<U32> LLAtomicU32;
diff --git a/indra/llcommon/llthread.cpp b/indra/llcommon/llthread.cpp
index 1d56a52c32..6c117f7daf 100644
--- a/indra/llcommon/llthread.cpp
+++ b/indra/llcommon/llthread.cpp
@@ -495,15 +495,7 @@ LLThreadSafeRefCount::LLThreadSafeRefCount() :
 
 LLThreadSafeRefCount::LLThreadSafeRefCount(const LLThreadSafeRefCount& src)
 {
-	if (sMutex)
-	{
-		sMutex->lock();
-	}
 	mRef = 0;
-	if (sMutex)
-	{
-		sMutex->unlock();
-	}
 }
 
 LLThreadSafeRefCount::~LLThreadSafeRefCount()
diff --git a/indra/llcommon/llthread.h b/indra/llcommon/llthread.h
index 5c8bbca2ca..c2f4184a8a 100644
--- a/indra/llcommon/llthread.h
+++ b/indra/llcommon/llthread.h
@@ -241,47 +241,43 @@ public:
 	LLThreadSafeRefCount(const LLThreadSafeRefCount&);
 	LLThreadSafeRefCount& operator=(const LLThreadSafeRefCount& ref) 
 	{
-		if (sMutex)
-		{
-			sMutex->lock();
-		}
 		mRef = 0;
-		if (sMutex)
-		{
-			sMutex->unlock();
-		}
 		return *this;
 	}
 
-
-	
 	void ref()
 	{
-		if (sMutex) sMutex->lock();
 		mRef++; 
-		if (sMutex) sMutex->unlock();
 	} 
 
 	S32 unref()
 	{
-		llassert(mRef >= 1);
-		if (sMutex) sMutex->lock();
-		S32 res = --mRef;
-		if (sMutex) sMutex->unlock();
-		if (0 == res) 
+		llassert(mRef >= 1);		
+		bool time_to_die = (mRef == 1);		
+		if (time_to_die)
 		{
-			delete this; 
+			if (sMutex) sMutex->lock();
+			// Looks redundant, but is very much not
+			// We need to check again once we've acquired the lock
+			// so that two threads who get into the if in parallel
+			// don't both attempt to the delete.
+			//
+			if (mRef == 1)
+				delete this; 
+			mRef--;
+			if (sMutex) sMutex->unlock();
 			return 0;
 		}
-		return res;
-	}	
+		return --mRef;		
+	}
 	S32 getNumRefs() const
 	{
-		return mRef;
+		const S32 currentVal = mRef.CurrentValue();
+		return currentVal;
 	}
 
 private: 
-	S32	mRef; 
+	LLAtomic32< S32	> mRef; 
 };
 
 //============================================================================
-- 
cgit v1.2.3


From dfda8826eb4654845430520dac48c011e058e1c0 Mon Sep 17 00:00:00 2001
From: "Graham Madarasz (Graham)" <graham@lindenlab.com>
Date: Fri, 1 Mar 2013 11:21:35 -0800
Subject: Make WL updates use pre-hashed strings for uniform sets

---
 indra/llcommon/CMakeLists.txt  |  1 +
 indra/llcommon/llstringtable.h | 54 ------------------------------------------
 indra/llcommon/llthread.h      |  4 ++--
 3 files changed, 3 insertions(+), 56 deletions(-)

(limited to 'indra/llcommon')

diff --git a/indra/llcommon/CMakeLists.txt b/indra/llcommon/CMakeLists.txt
index 5cce8ff2c4..e019c17280 100644
--- a/indra/llcommon/CMakeLists.txt
+++ b/indra/llcommon/CMakeLists.txt
@@ -236,6 +236,7 @@ set(llcommon_HEADER_FILES
     llstrider.h
     llstring.h
     llstringtable.h
+    llstaticstringtable.h
     llsys.h
     llthread.h
     llthreadsafequeue.h
diff --git a/indra/llcommon/llstringtable.h b/indra/llcommon/llstringtable.h
index 4f6417328c..787a046741 100644
--- a/indra/llcommon/llstringtable.h
+++ b/indra/llcommon/llstringtable.h
@@ -33,7 +33,6 @@
 #include "llstl.h"
 #include <list>
 #include <set>
-#include <hash_map>
 
 #if LL_WINDOWS
 # if (_MSC_VER >= 1300 && _MSC_VER < 1400)
@@ -43,59 +42,6 @@
 //# define STRING_TABLE_HASH_MAP 1
 #endif
 
-#if STRING_TABLE_HASH_MAP
-# if LL_WINDOWS
-#  include <hash_map>
-# else
-#  include <ext/hash_map>
-# endif
-#endif
-
-class LLStaticHashedString
-{
-public:
-
-	LLStaticHashedString(const std::string& s)
-	{
-		string_hash = makehash(s);
-		string		= s;
-	}
-
-	const std::string&	String() const { return string;		}
-	size_t				Hash()	 const { return string_hash;  }
-
-protected:
-
-	size_t makehash(const std::string& s)
-	{
-		size_t len = s.size();
-		const char* c = s.c_str();
-		size_t hashval = 0;
-		for (size_t i=0; i<len; i++)
-		{
-			hashval = ((hashval<<5) + hashval) + *c++;
-		}
-		return hashval;
-	}
-
-	std::string string;
-	size_t		string_hash;
-};
-
-template<class T>
-struct LLStaticStringHasher
-{
-	enum { bucket_size = 8 };
-	size_t operator()(const T& key_value)		   const { return key_value.Hash();			  }
-	bool operator()(const T& left, const T& right) const { return left.Hash() < right.Hash(); }
-};
-
-template< typename MappedObject >
-class LL_COMMON_API LLStaticStringTable
-	: public std::hash_map< LLStaticHashedString , MappedObject, LLStaticStringHasher< LLStaticHashedString > >
-{
-};
-
 const U32 MAX_STRINGS_LENGTH = 256;
 
 class LL_COMMON_API LLStringTableEntry
diff --git a/indra/llcommon/llthread.h b/indra/llcommon/llthread.h
index c2f4184a8a..0d22bc863d 100644
--- a/indra/llcommon/llthread.h
+++ b/indra/llcommon/llthread.h
@@ -262,9 +262,9 @@ public:
 			// so that two threads who get into the if in parallel
 			// don't both attempt to the delete.
 			//
-			if (mRef == 1)
-				delete this; 
 			mRef--;
+			if (mRef == 0)
+				delete this; 			
 			if (sMutex) sMutex->unlock();
 			return 0;
 		}
-- 
cgit v1.2.3


From 7f66555ed6ce46ac85a10a349e9f40b73c136950 Mon Sep 17 00:00:00 2001
From: "Graham Madarasz (Graham)" <graham@lindenlab.com>
Date: Fri, 1 Mar 2013 11:23:46 -0800
Subject: Add llstaticstringtable.h

---
 indra/llcommon/llstaticstringtable.h | 81 ++++++++++++++++++++++++++++++++++++
 1 file changed, 81 insertions(+)
 create mode 100644 indra/llcommon/llstaticstringtable.h

(limited to 'indra/llcommon')

diff --git a/indra/llcommon/llstaticstringtable.h b/indra/llcommon/llstaticstringtable.h
new file mode 100644
index 0000000000..05b0848e30
--- /dev/null
+++ b/indra/llcommon/llstaticstringtable.h
@@ -0,0 +1,81 @@
+/** 
+ * @file llstringtable.h
+ * @brief The LLStringTable class provides a _fast_ method for finding
+ * unique copies of strings.
+ *
+ * $LicenseInfo:firstyear=2001&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_STATIC_STRING_TABLE_H
+#define LL_STATIC_STRING_TABLE_H
+
+#include "lldefs.h"
+#include <boost/unordered_map.hpp>
+#include "llstl.h"
+
+class LLStaticHashedString
+{
+public:
+
+	LLStaticHashedString(const std::string& s)
+	{
+		string_hash = makehash(s);
+		string		= s;
+	}
+
+	const std::string&	String() const { return string;		}
+	size_t				Hash()	 const { return string_hash;  }
+
+	bool operator==(const LLStaticHashedString& b) const { return Hash() == b.Hash(); }
+
+protected:
+
+	size_t makehash(const std::string& s)
+	{
+		size_t len = s.size();
+		const char* c = s.c_str();
+		size_t hashval = 0;
+		for (size_t i=0; i<len; i++)
+		{
+			hashval = ((hashval<<5) + hashval) + *c++;
+		}
+		return hashval;
+	}
+
+	std::string string;
+	size_t		string_hash;
+};
+
+struct LLStaticStringHasher
+{
+	enum { bucket_size = 8 };
+	size_t operator()(const LLStaticHashedString& key_value) const { return key_value.Hash(); }
+	bool operator()(const LLStaticHashedString& left, const LLStaticHashedString& right) const { return left.Hash() < right.Hash(); }
+};
+
+template< typename MappedObject >
+class LL_COMMON_API LLStaticStringTable
+	: public boost::unordered_map< LLStaticHashedString, MappedObject, LLStaticStringHasher >
+{
+};
+
+#endif
\ No newline at end of file
-- 
cgit v1.2.3


From 88de325b36b92aafc1b12aed4617c73c01218b43 Mon Sep 17 00:00:00 2001
From: "Graham Madarasz (Graham)" <graham@lindenlab.com>
Date: Fri, 1 Mar 2013 14:07:55 -0800
Subject: Fix integration tests broken by instancetracker changes

---
 indra/llcommon/tests/llinstancetracker_test.cpp | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

(limited to 'indra/llcommon')

diff --git a/indra/llcommon/tests/llinstancetracker_test.cpp b/indra/llcommon/tests/llinstancetracker_test.cpp
index 454695ff9f..9d5db4b1d9 100644
--- a/indra/llcommon/tests/llinstancetracker_test.cpp
+++ b/indra/llcommon/tests/llinstancetracker_test.cpp
@@ -48,16 +48,16 @@ struct Badness: public std::runtime_error
     Badness(const std::string& what): std::runtime_error(what) {}
 };
 
-struct Keyed: public LLInstanceTracker<Keyed, std::string>
+struct Keyed: public INSTANCE_TRACKER_KEYED(Keyed, std::string)
 {
     Keyed(const std::string& name):
-        LLInstanceTracker<Keyed, std::string>(name),
+        INSTANCE_TRACKER_KEYED(Keyed, std::string)(name),
         mName(name)
     {}
     std::string mName;
 };
 
-struct Unkeyed: public LLInstanceTracker<Unkeyed>
+struct Unkeyed: public INSTANCE_TRACKER(Unkeyed)
 {
     Unkeyed(const std::string& thrw="")
     {
-- 
cgit v1.2.3


From 3849ee79c3810226d1129bcbeb6bd69144aba243 Mon Sep 17 00:00:00 2001
From: "Graham Madarasz (Graham)" <graham@lindenlab.com>
Date: Fri, 1 Mar 2013 14:28:48 -0800
Subject: Added missing enums for integ test usage

---
 indra/llcommon/llinstancetracker.h | 2 ++
 1 file changed, 2 insertions(+)

(limited to 'indra/llcommon')

diff --git a/indra/llcommon/llinstancetracker.h b/indra/llcommon/llinstancetracker.h
index 70bccde992..c31f579f30 100644
--- a/indra/llcommon/llinstancetracker.h
+++ b/indra/llcommon/llinstancetracker.h
@@ -57,6 +57,8 @@ enum InstanceTrackType
 	InstanceTrackType_LLMediaCtrl,
 	InstanceTrackType_LLNameListCtrl,
 	InstanceTrackType_LLToast,
+	InstanceTrackType_Keyed,	// for integ tests
+	InstanceTrackType_Unkeyed,	// for integ tests
 	kInstanceTrackTypeCount
 };
 
-- 
cgit v1.2.3


From 609ed855e1160505238378a1be49e2b92e8496f5 Mon Sep 17 00:00:00 2001
From: Dave Parks <davep@lindenlab.com>
Date: Mon, 4 Mar 2013 18:01:42 -0600
Subject: MAINT-2371 More optimizations.

Reviewed by Graham
---
 indra/llcommon/llmemory.h | 13 ++++++++++++-
 1 file changed, 12 insertions(+), 1 deletion(-)

(limited to 'indra/llcommon')

diff --git a/indra/llcommon/llmemory.h b/indra/llcommon/llmemory.h
index e725bdd9fa..46cabfadcd 100644
--- a/indra/llcommon/llmemory.h
+++ b/indra/llcommon/llmemory.h
@@ -38,17 +38,28 @@ class LLMutex ;
 
 inline void* ll_aligned_malloc( size_t size, int align )
 {
+#if defined(LL_WINDOWS)
+	return _aligned_malloc(size, align);
+#else
 	void* mem = malloc( size + (align - 1) + sizeof(void*) );
 	char* aligned = ((char*)mem) + sizeof(void*);
 	aligned += align - ((uintptr_t)aligned & (align - 1));
 
 	((void**)aligned)[-1] = mem;
 	return aligned;
+#endif
 }
 
 inline void ll_aligned_free( void* ptr )
 {
-	free( ((void**)ptr)[-1] );
+#if defined(LL_WINDOWS)
+	_aligned_free(ptr);
+#else
+	if (ptr)
+	{
+		free( ((void**)ptr)[-1] );
+	}
+#endif
 }
 
 #if !LL_USE_TCMALLOC
-- 
cgit v1.2.3


From b19eeabd54afcfb56e864899c166b64db1ac6790 Mon Sep 17 00:00:00 2001
From: "Graham Madarasz (Graham)" <graham@lindenlab.com>
Date: Mon, 4 Mar 2013 16:05:12 -0800
Subject: Include signal.h instead of replicating typedef to avoid errors from
 redefining it...provides better compat with non-Ubuntu distros

---
 indra/llcommon/llapp.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'indra/llcommon')

diff --git a/indra/llcommon/llapp.h b/indra/llcommon/llapp.h
index a536a06ea5..afa06df23e 100644
--- a/indra/llcommon/llapp.h
+++ b/indra/llcommon/llapp.h
@@ -38,7 +38,7 @@ typedef LLAtomic32<U32> LLAtomicU32;
 class LLErrorThread;
 class LLLiveFile;
 #if LL_LINUX
-typedef struct siginfo siginfo_t;
+#include <signal.h>
 #endif
 
 typedef void (*LLAppErrorHandler)();
-- 
cgit v1.2.3


From 1b3dec4c11e76f5c5ab6ab8bd2464d07177009c4 Mon Sep 17 00:00:00 2001
From: "Graham Madarasz (Graham)" <graham@lindenlab.com>
Date: Thu, 7 Mar 2013 09:00:26 -0800
Subject: Put newline at end of file to appease gcc's OCD

---
 indra/llcommon/llinstancetracker.cpp | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

(limited to 'indra/llcommon')

diff --git a/indra/llcommon/llinstancetracker.cpp b/indra/llcommon/llinstancetracker.cpp
index 0804be358f..65ef4322f6 100644
--- a/indra/llcommon/llinstancetracker.cpp
+++ b/indra/llcommon/llinstancetracker.cpp
@@ -42,4 +42,5 @@ void * & LLInstanceTrackerBase::getInstances(InstanceTrackType t)
 	// key DOES exist, insert() simply returns (iterator, false). One lookup
 	// handles both cases.
 	return sInstanceTrackerData[t];
-}
\ No newline at end of file
+}
+
-- 
cgit v1.2.3


From de4414260d1a898299a8081d85c4a12363eed17f Mon Sep 17 00:00:00 2001
From: "Graham Madarasz (Graham)" <graham@lindenlab.com>
Date: Thu, 7 Mar 2013 14:11:35 -0800
Subject: Fix missing eol at eof

---
 indra/llcommon/llstaticstringtable.h | 163 ++++++++++++++++++-----------------
 1 file changed, 82 insertions(+), 81 deletions(-)

(limited to 'indra/llcommon')

diff --git a/indra/llcommon/llstaticstringtable.h b/indra/llcommon/llstaticstringtable.h
index 05b0848e30..d7e0e8a08d 100644
--- a/indra/llcommon/llstaticstringtable.h
+++ b/indra/llcommon/llstaticstringtable.h
@@ -1,81 +1,82 @@
-/** 
- * @file llstringtable.h
- * @brief The LLStringTable class provides a _fast_ method for finding
- * unique copies of strings.
- *
- * $LicenseInfo:firstyear=2001&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_STATIC_STRING_TABLE_H
-#define LL_STATIC_STRING_TABLE_H
-
-#include "lldefs.h"
-#include <boost/unordered_map.hpp>
-#include "llstl.h"
-
-class LLStaticHashedString
-{
-public:
-
-	LLStaticHashedString(const std::string& s)
-	{
-		string_hash = makehash(s);
-		string		= s;
-	}
-
-	const std::string&	String() const { return string;		}
-	size_t				Hash()	 const { return string_hash;  }
-
-	bool operator==(const LLStaticHashedString& b) const { return Hash() == b.Hash(); }
-
-protected:
-
-	size_t makehash(const std::string& s)
-	{
-		size_t len = s.size();
-		const char* c = s.c_str();
-		size_t hashval = 0;
-		for (size_t i=0; i<len; i++)
-		{
-			hashval = ((hashval<<5) + hashval) + *c++;
-		}
-		return hashval;
-	}
-
-	std::string string;
-	size_t		string_hash;
-};
-
-struct LLStaticStringHasher
-{
-	enum { bucket_size = 8 };
-	size_t operator()(const LLStaticHashedString& key_value) const { return key_value.Hash(); }
-	bool operator()(const LLStaticHashedString& left, const LLStaticHashedString& right) const { return left.Hash() < right.Hash(); }
-};
-
-template< typename MappedObject >
-class LL_COMMON_API LLStaticStringTable
-	: public boost::unordered_map< LLStaticHashedString, MappedObject, LLStaticStringHasher >
-{
-};
-
-#endif
\ No newline at end of file
+/** 
+ * @file llstringtable.h
+ * @brief The LLStringTable class provides a _fast_ method for finding
+ * unique copies of strings.
+ *
+ * $LicenseInfo:firstyear=2001&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_STATIC_STRING_TABLE_H
+#define LL_STATIC_STRING_TABLE_H
+
+#include "lldefs.h"
+#include <boost/unordered_map.hpp>
+#include "llstl.h"
+
+class LLStaticHashedString
+{
+public:
+
+	LLStaticHashedString(const std::string& s)
+	{
+		string_hash = makehash(s);
+		string		= s;
+	}
+
+	const std::string&	String() const { return string;		}
+	size_t				Hash()	 const { return string_hash;  }
+
+	bool operator==(const LLStaticHashedString& b) const { return Hash() == b.Hash(); }
+
+protected:
+
+	size_t makehash(const std::string& s)
+	{
+		size_t len = s.size();
+		const char* c = s.c_str();
+		size_t hashval = 0;
+		for (size_t i=0; i<len; i++)
+		{
+			hashval = ((hashval<<5) + hashval) + *c++;
+		}
+		return hashval;
+	}
+
+	std::string string;
+	size_t		string_hash;
+};
+
+struct LLStaticStringHasher
+{
+	enum { bucket_size = 8 };
+	size_t operator()(const LLStaticHashedString& key_value) const { return key_value.Hash(); }
+	bool   operator()(const LLStaticHashedString& left, const LLStaticHashedString& right) const { return left.Hash() < right.Hash(); }
+};
+
+template< typename MappedObject >
+class LL_COMMON_API LLStaticStringTable
+	: public boost::unordered_map< LLStaticHashedString, MappedObject, LLStaticStringHasher >
+{
+};
+
+#endif
+
-- 
cgit v1.2.3


From f061b2b90e34d74b9c6db3606babb0402473a24d Mon Sep 17 00:00:00 2001
From: "Graham Madarasz (Graham)" <graham@lindenlab.com>
Date: Fri, 8 Mar 2013 15:31:37 -0800
Subject: Optimize interp code to elim hundreds of divides per frame and fix
 jitter bugs.

---
 indra/llcommon/llcriticaldamp.cpp | 51 ++++++++----------------
 indra/llcommon/llcriticaldamp.h   | 82 +++++++++++++++++++++++++++++++++++++--
 2 files changed, 96 insertions(+), 37 deletions(-)

(limited to 'indra/llcommon')

diff --git a/indra/llcommon/llcriticaldamp.cpp b/indra/llcommon/llcriticaldamp.cpp
index 87d79b1ee0..27fef0e6dc 100644
--- a/indra/llcommon/llcriticaldamp.cpp
+++ b/indra/llcommon/llcriticaldamp.cpp
@@ -32,8 +32,9 @@
 // static members
 //-----------------------------------------------------------------------------
 LLFrameTimer LLCriticalDamp::sInternalTimer;
-std::map<F32, F32> LLCriticalDamp::sInterpolants;
 F32 LLCriticalDamp::sTimeDelta;
+F32	LLCriticalDamp::sInterpolants[kNumCachedInterpolants];
+F32 LLCriticalDamp::sInterpolatedValues[kNumCachedInterpolants];
 
 //-----------------------------------------------------------------------------
 // LLCriticalDamp()
@@ -41,6 +42,17 @@ F32 LLCriticalDamp::sTimeDelta;
 LLCriticalDamp::LLCriticalDamp()
 {
 	sTimeDelta = 0.f;
+
+	// Init the core interpolant values (to which many, many enums map)
+	//
+	setInterpolantConstant(InterpDelta_0_025, 0.025f);
+	setInterpolantConstant(InterpDelta_0_05,  0.05f );
+	setInterpolantConstant(InterpDelta_0_06,  0.06f);
+	setInterpolantConstant(InterpDelta_0_10,  0.10f);
+	setInterpolantConstant(InterpDelta_0_15,  0.15f);
+	setInterpolantConstant(InterpDelta_0_20,  0.20f);
+	setInterpolantConstant(InterpDelta_0_25,  0.25f);
+	setInterpolantConstant(InterpDelta_0_30,  0.30f);
 }
 
 // static
@@ -51,39 +63,10 @@ void LLCriticalDamp::updateInterpolants()
 {
 	sTimeDelta = sInternalTimer.getElapsedTimeAndResetF32();
 
-	F32 time_constant;
-
-	for (std::map<F32, F32>::iterator iter = sInterpolants.begin();
-		 iter != sInterpolants.end(); iter++)
-	{
-		time_constant = iter->first;
-		F32 new_interpolant = 1.f - pow(2.f, -sTimeDelta / time_constant);
-		new_interpolant = llclamp(new_interpolant, 0.f, 1.f);
-		sInterpolants[time_constant] = new_interpolant;
-	}
-} 
-
-//-----------------------------------------------------------------------------
-// getInterpolant()
-//-----------------------------------------------------------------------------
-F32 LLCriticalDamp::getInterpolant(const F32 time_constant, BOOL use_cache)
-{
-	if (time_constant == 0.f)
+	U32 i;
+	for (i = 0; i < kNumCachedInterpolants; i++)
 	{
-		return 1.f;
+		sInterpolatedValues[i] = llclamp(sTimeDelta / sInterpolants[ i], 0.0f, 1.0f);
 	}
-
-	if (use_cache && sInterpolants.count(time_constant))
-	{
-		return sInterpolants[time_constant];
-	}
-	
-	F32 interpolant = 1.f - pow(2.f, -sTimeDelta / time_constant);
-	interpolant = llclamp(interpolant, 0.f, 1.f);
-	if (use_cache)
-	{
-		sInterpolants[time_constant] = interpolant;
-	}
-
-	return interpolant;
 }
+
diff --git a/indra/llcommon/llcriticaldamp.h b/indra/llcommon/llcriticaldamp.h
index 52f052ae25..19a2ddb77a 100644
--- a/indra/llcommon/llcriticaldamp.h
+++ b/indra/llcommon/llcriticaldamp.h
@@ -32,22 +32,98 @@
 
 #include "llframetimer.h"
 
+// These enums each represent one fixed-time delta value
+// that we interpolate once given the actual sTimeDelta time
+// that has passed. This allows us to calculate the interp portion
+// of those values once and then look them up repeatedly per frame.
+//
+enum InterpDelta
+{	
+	InterpDelta_0_025,		// 0.025
+	InterpDeltaTeenier					= InterpDelta_0_025,
+	InterpDeltaFolderOpenTime			= InterpDelta_0_025,
+	InterpDeltaFolderCloseTime			= InterpDelta_0_025,
+	InterpDeltaCameraFocusHalfLife		= InterpDelta_0_025,	// USED TO BE ZERO....
+
+	InterpDelta_0_05,		// 0.05
+	InterpDeltaTeeny		= InterpDelta_0_05,
+
+	InterpDelta_0_06,		// 0.06
+	InterpDeltaObjectDampingConstant	= InterpDelta_0_06,	
+	InterpDeltaCameraZoomHalfLife		= InterpDelta_0_06,
+	InterpDeltaFovZoomHalfLife			= InterpDelta_0_06,
+	InterpDeltaManipulatorScaleHalfLife	= InterpDelta_0_06,
+	InterpDeltaContextFadeTime			= InterpDelta_0_06,
+
+	InterpDelta_0_10,		// 0.10
+	InterpDeltaSmaller					= InterpDelta_0_10,
+	InterpDeltaTargetLagHalfLife		= InterpDelta_0_10,
+	InterpDeltaSpeedAdjustTime			= InterpDelta_0_10,
+
+	InterpDelta_0_15,		// 0.15
+	InterpDeltaFadeWeight				= InterpDelta_0_15,
+	InterpDeltaHeadLookAtLagHalfLife	= InterpDelta_0_15,
+
+	InterpDelta_0_20,		// 0.20
+	InterpDeltaSmall					= InterpDelta_0_20,
+	InterpDeltaTorsoLagHalfLife			= InterpDelta_0_20,
+	InterpDeltaPositionDampingTC		= InterpDelta_0_20,
+
+	InterpDelta_0_25,		// 0.25
+	InterpDeltaCameraLagHalfLife		= InterpDelta_0_25,
+	InterpDeltaTorsoTargetLagHalfLife	= InterpDelta_0_25,
+	InterpDeltaTorsoLookAtLagHalfLife	= InterpDelta_0_25,
+
+	InterpDelta_0_30,		// 0.3
+	InterpDeltaSmallish		= InterpDelta_0_30,
+
+	// Dynamically set interpolants which use setInterpolantConstant
+	//
+	InterpDeltaCameraSmoothingHalfLife,	
+	InterpDeltaBehindnessLag,
+	InterpDeltaFocusLag,
+	InterpDeltaPositionLag,
+	InterpDeltaOpenTime,
+	InterpDeltaCloseTime,		
+
+	kNumCachedInterpolants
+};
+
 class LL_COMMON_API LLCriticalDamp 
 {
 public:
 	LLCriticalDamp();
 
-	// MANIPULATORS
+	// Updates all the known interp delta values for fast lookup in calls to getInterpolant(InterpDelta)
+	//
 	static void updateInterpolants();
 
+	static inline void setInterpolantConstant(InterpDelta whichDelta, const F32 time_constant)
+	{
+		llassert(whichDelta < kNumCachedInterpolants);
+		sInterpolants[whichDelta] = time_constant;
+	}
+
 	// ACCESSORS
-	static F32 getInterpolant(const F32 time_constant, BOOL use_cache = TRUE);
+	static inline F32 getInterpolant(InterpDelta whichDelta)
+	{
+		llassert(whichDelta < kNumCachedInterpolants);
+		return sInterpolatedValues[whichDelta];
+	}
+
+	static inline F32 getInterpolant(const F32 time_constant)
+	{
+		return llclamp((sTimeDelta / time_constant), 0.0f, 1.0f);
+	}
 
 protected:	
 	static LLFrameTimer sInternalTimer;	// frame timer for calculating deltas
 
-	static std::map<F32, F32> 	sInterpolants;
+	//static std::map<F32, F32> 	sInterpolants;
+	static F32					sInterpolants[kNumCachedInterpolants];
+	static F32					sInterpolatedValues[kNumCachedInterpolants];
 	static F32					sTimeDelta;
 };
 
 #endif  // LL_LLCRITICALDAMP_H
+
-- 
cgit v1.2.3


From 5616d198bdace981c0d284d000eddd815d4c7491 Mon Sep 17 00:00:00 2001
From: "Graham Madarasz (Graham)" <graham@lindenlab.com>
Date: Mon, 11 Mar 2013 09:55:33 -0700
Subject: Fix missing eol at eof in llinstancetracker.cpp tripping up linux
 build

---
 indra/llcommon/llinstancetracker.cpp | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

(limited to 'indra/llcommon')

diff --git a/indra/llcommon/llinstancetracker.cpp b/indra/llcommon/llinstancetracker.cpp
index 0804be358f..65ef4322f6 100644
--- a/indra/llcommon/llinstancetracker.cpp
+++ b/indra/llcommon/llinstancetracker.cpp
@@ -42,4 +42,5 @@ void * & LLInstanceTrackerBase::getInstances(InstanceTrackType t)
 	// key DOES exist, insert() simply returns (iterator, false). One lookup
 	// handles both cases.
 	return sInstanceTrackerData[t];
-}
\ No newline at end of file
+}
+
-- 
cgit v1.2.3


From 8c1e635317caebbb5532bc0a4dadf0f4a30f737b Mon Sep 17 00:00:00 2001
From: "Graham Madarasz (Graham)" <graham@lindenlab.com>
Date: Mon, 11 Mar 2013 10:12:10 -0700
Subject: Fix missing eol at eof in llstaticstringtable.h breaking linux build

---
 indra/llcommon/llstaticstringtable.h | 163 ++++++++++++++++++-----------------
 1 file changed, 82 insertions(+), 81 deletions(-)

(limited to 'indra/llcommon')

diff --git a/indra/llcommon/llstaticstringtable.h b/indra/llcommon/llstaticstringtable.h
index 05b0848e30..52049b0921 100644
--- a/indra/llcommon/llstaticstringtable.h
+++ b/indra/llcommon/llstaticstringtable.h
@@ -1,81 +1,82 @@
-/** 
- * @file llstringtable.h
- * @brief The LLStringTable class provides a _fast_ method for finding
- * unique copies of strings.
- *
- * $LicenseInfo:firstyear=2001&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_STATIC_STRING_TABLE_H
-#define LL_STATIC_STRING_TABLE_H
-
-#include "lldefs.h"
-#include <boost/unordered_map.hpp>
-#include "llstl.h"
-
-class LLStaticHashedString
-{
-public:
-
-	LLStaticHashedString(const std::string& s)
-	{
-		string_hash = makehash(s);
-		string		= s;
-	}
-
-	const std::string&	String() const { return string;		}
-	size_t				Hash()	 const { return string_hash;  }
-
-	bool operator==(const LLStaticHashedString& b) const { return Hash() == b.Hash(); }
-
-protected:
-
-	size_t makehash(const std::string& s)
-	{
-		size_t len = s.size();
-		const char* c = s.c_str();
-		size_t hashval = 0;
-		for (size_t i=0; i<len; i++)
-		{
-			hashval = ((hashval<<5) + hashval) + *c++;
-		}
-		return hashval;
-	}
-
-	std::string string;
-	size_t		string_hash;
-};
-
-struct LLStaticStringHasher
-{
-	enum { bucket_size = 8 };
-	size_t operator()(const LLStaticHashedString& key_value) const { return key_value.Hash(); }
-	bool operator()(const LLStaticHashedString& left, const LLStaticHashedString& right) const { return left.Hash() < right.Hash(); }
-};
-
-template< typename MappedObject >
-class LL_COMMON_API LLStaticStringTable
-	: public boost::unordered_map< LLStaticHashedString, MappedObject, LLStaticStringHasher >
-{
-};
-
-#endif
\ No newline at end of file
+/** 
+ * @file llstringtable.h
+ * @brief The LLStringTable class provides a _fast_ method for finding
+ * unique copies of strings.
+ *
+ * $LicenseInfo:firstyear=2001&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_STATIC_STRING_TABLE_H
+#define LL_STATIC_STRING_TABLE_H
+
+#include "lldefs.h"
+#include <boost/unordered_map.hpp>
+#include "llstl.h"
+
+class LLStaticHashedString
+{
+public:
+
+	LLStaticHashedString(const std::string& s)
+	{
+		string_hash = makehash(s);
+		string		= s;
+	}
+
+	const std::string&	String() const { return string;		}
+	size_t				Hash()	 const { return string_hash;  }
+
+	bool operator==(const LLStaticHashedString& b) const { return Hash() == b.Hash(); }
+
+protected:
+
+	size_t makehash(const std::string& s)
+	{
+		size_t len = s.size();
+		const char* c = s.c_str();
+		size_t hashval = 0;
+		for (size_t i=0; i<len; i++)
+		{
+			hashval = ((hashval<<5) + hashval) + *c++;
+		}
+		return hashval;
+	}
+
+	std::string string;
+	size_t		string_hash;
+};
+
+struct LLStaticStringHasher
+{
+	enum { bucket_size = 8 };
+	size_t operator()(const LLStaticHashedString& key_value) const { return key_value.Hash(); }
+	bool operator()(const LLStaticHashedString& left, const LLStaticHashedString& right) const { return left.Hash() < right.Hash(); }
+};
+
+template< typename MappedObject >
+class LL_COMMON_API LLStaticStringTable
+	: public boost::unordered_map< LLStaticHashedString, MappedObject, LLStaticStringHasher >
+{
+};
+
+#endif
+
-- 
cgit v1.2.3


From c04f4f66c813181eb378b00045aec969dc2c4aae Mon Sep 17 00:00:00 2001
From: Graham Madarasz <graham@lindenlab.com>
Date: Mon, 11 Mar 2013 12:30:16 -0700
Subject: Moved LLAlignedArray from llmath to llcommon and put template func
 impls in header to work around Mac 4.3.3 link issue.

---
 indra/llcommon/CMakeLists.txt | 1 +
 1 file changed, 1 insertion(+)

(limited to 'indra/llcommon')

diff --git a/indra/llcommon/CMakeLists.txt b/indra/llcommon/CMakeLists.txt
index e019c17280..0c2ceebb52 100644
--- a/indra/llcommon/CMakeLists.txt
+++ b/indra/llcommon/CMakeLists.txt
@@ -121,6 +121,7 @@ set(llcommon_HEADER_FILES
     linden_common.h
     linked_lists.h
     llaccountingcost.h
+    llalignedarray.h
     llallocator.h
     llallocator_heap_profile.h
     llagentconstants.h
-- 
cgit v1.2.3


From 6ac6736994240d9789a81bf585468bef50805fd8 Mon Sep 17 00:00:00 2001
From: Graham Madarasz <graham@lindenlab.com>
Date: Mon, 11 Mar 2013 16:00:25 -0700
Subject: Move 16b aligned memcpy and alignment utilities to llmem in llcommon
 for easier use elsewhere

---
 indra/llcommon/llalignedarray.h |  16 +------
 indra/llcommon/llmemory.h       | 102 +++++++++++++++++++++++++++++++++++++---
 2 files changed, 98 insertions(+), 20 deletions(-)

(limited to 'indra/llcommon')

diff --git a/indra/llcommon/llalignedarray.h b/indra/llcommon/llalignedarray.h
index 5e04e8050f..ed8fd31205 100644
--- a/indra/llcommon/llalignedarray.h
+++ b/indra/llcommon/llalignedarray.h
@@ -29,10 +29,6 @@
 
 #include "llmemory.h"
 
-#if LL_WINDOWS
-#include "llvector4a.h" // for 16b fast copy
-#endif
-
 template <class T, U32 alignment>
 class LLAlignedArray
 {
@@ -81,11 +77,7 @@ void LLAlignedArray<T, alignment>::push_back(const T& elem)
 		T* new_buf = (T*) ll_aligned_malloc(mCapacity*sizeof(T), alignment);
 		if (mArray)
 		{
-#if LL_WINDOWS
-			LLVector4a::memcpyNonAliased16((F32*) new_buf, (F32*) mArray, sizeof(T)*mElementCount);
-#else
-			memcpy((F32*)new_buf, (F32*)mArray, sizeof(T)*mElementCount);
-#endif
+			ll_memcpy_nonaliased_aligned_16((char*)new_buf, (char*)mArray, sizeof(T)*mElementCount);
 		}
 		old_buf = mArray;
 		mArray = new_buf;
@@ -106,11 +98,7 @@ void LLAlignedArray<T, alignment>::resize(U32 size)
 		T* new_buf = mCapacity > 0 ? (T*) ll_aligned_malloc(mCapacity*sizeof(T), alignment) : NULL;
 		if (mArray)
 		{
-#if LL_WINDOWS
-			LLVector4a::memcpyNonAliased16((F32*) new_buf, (F32*) mArray, sizeof(T)*mElementCount);
-#else
-			memcpy((F32*) new_buf, (F32*) mArray, sizeof(T)*mElementCount);
-#endif
+			ll_memcpy_nonaliased_aligned_16((char*) new_buf, (char*) mArray, sizeof(T)*mElementCount);
 			ll_aligned_free(mArray);
 		}
 
diff --git a/indra/llcommon/llmemory.h b/indra/llcommon/llmemory.h
index 46cabfadcd..4938775e2b 100644
--- a/indra/llcommon/llmemory.h
+++ b/indra/llcommon/llmemory.h
@@ -36,6 +36,44 @@ class LLMutex ;
 #define LL_CHECK_MEMORY
 #endif
 
+LL_COMMON_API void ll_assert_aligned_func(uintptr_t ptr,U32 alignment);
+
+#ifdef SHOW_ASSERT
+#define ll_assert_aligned(ptr,alignment) ll_assert_aligned_func(reinterpret_cast<uintptr_t>(ptr),((U32)alignment))
+#else
+#define ll_assert_aligned(ptr,alignment)
+#endif
+
+#include <xmmintrin.h>
+
+template <typename T> T* LL_NEXT_ALIGNED_ADDRESS(T* address) 
+{ 
+	return reinterpret_cast<T*>(
+		(reinterpret_cast<uintptr_t>(address) + 0xF) & ~0xF);
+}
+
+template <typename T> T* LL_NEXT_ALIGNED_ADDRESS_64(T* address) 
+{ 
+	return reinterpret_cast<T*>(
+		(reinterpret_cast<uintptr_t>(address) + 0x3F) & ~0x3F);
+}
+
+#if LL_LINUX || LL_DARWIN
+
+#define			LL_ALIGN_PREFIX(x)
+#define			LL_ALIGN_POSTFIX(x)		__attribute__((aligned(x)))
+
+#elif LL_WINDOWS
+
+#define			LL_ALIGN_PREFIX(x)		__declspec(align(x))
+#define			LL_ALIGN_POSTFIX(x)
+
+#else
+#error "LL_ALIGN_PREFIX and LL_ALIGN_POSTFIX undefined"
+#endif
+
+#define LL_ALIGN_16(var) LL_ALIGN_PREFIX(16) var LL_ALIGN_POSTFIX(16)
+
 inline void* ll_aligned_malloc( size_t size, int align )
 {
 #if defined(LL_WINDOWS)
@@ -144,6 +182,64 @@ inline void ll_aligned_free_32(void *p)
 #endif
 }
 
+
+// Copy words 16-byte blocks from src to dst. Source and destination MUST NOT OVERLAP. 
+// Source and dest must be 16-byte aligned and size must be multiple of 16.
+//
+inline void ll_memcpy_nonaliased_aligned_16(char* __restrict dst, const char* __restrict src, size_t bytes)
+{
+	assert(src != NULL);
+	assert(dst != NULL);
+	assert(bytes > 0);
+	assert((bytes % sizeof(F32))== 0); 
+	ll_assert_aligned(src,16);
+	ll_assert_aligned(dst,16);
+	assert((src < dst) ? ((src + bytes) < dst) : ((dst + bytes) < src));
+	assert(bytes%16==0);
+
+	char* end = dst + bytes;
+
+	if (bytes > 64)
+	{
+		void* begin_64 = LL_NEXT_ALIGNED_ADDRESS_64(dst);
+		
+		//at least 64 bytes before the end of the destination, switch to 16 byte copies
+		void* end_64 = end-64;
+		
+		_mm_prefetch((char*)begin_64, _MM_HINT_NTA);
+		_mm_prefetch((char*)begin_64 + 64, _MM_HINT_NTA);
+		_mm_prefetch((char*)begin_64 + 128, _MM_HINT_NTA);
+		_mm_prefetch((char*)begin_64 + 192, _MM_HINT_NTA);
+		
+		while (dst < begin_64)
+		{
+
+			_mm_store_ps((F32*)dst, _mm_load_ps((F32*)src));
+			dst += 4;
+			src += 4;
+		}
+		
+		while (dst < end_64)
+		{
+			_mm_prefetch((char*)src + 512, _MM_HINT_NTA);
+			_mm_prefetch((char*)dst + 512, _MM_HINT_NTA);
+			_mm_store_ps((F32*)dst, _mm_load_ps((F32*)src));
+			_mm_store_ps((F32*)(dst + 16), _mm_load_ps((F32*)(src + 16)));
+			_mm_store_ps((F32*)(dst + 32), _mm_load_ps((F32*)(src + 32)));
+			_mm_store_ps((F32*)(dst + 48), _mm_load_ps((F32*)(src + 48)));
+			dst += 64;
+			src += 64;
+		}
+	}
+
+	while (dst < end)
+	{
+		_mm_store_ps((F32*)dst, _mm_load_ps((F32*)src));
+		dst += 16;
+		src += 16;
+	}
+}
+
 #ifndef __DEBUG_PRIVATE_MEM__
 #define __DEBUG_PRIVATE_MEM__  0
 #endif
@@ -552,13 +648,7 @@ void  LLPrivateMemoryPoolTester::operator delete[](void* addr)
 
 // LLSingleton moved to llsingleton.h
 
-LL_COMMON_API void ll_assert_aligned_func(uintptr_t ptr,U32 alignment);
 
-#ifdef SHOW_ASSERT
-#define ll_assert_aligned(ptr,alignment) ll_assert_aligned_func(reinterpret_cast<uintptr_t>(ptr),((U32)alignment))
-#else
-#define ll_assert_aligned(ptr,alignment)
-#endif
 
 
 #endif
-- 
cgit v1.2.3


From 6613d80d72931b13cc008c3dcc8ee90a39bec8f5 Mon Sep 17 00:00:00 2001
From: Graham Madarasz <graham@lindenlab.com>
Date: Mon, 11 Mar 2013 14:19:05 -0700
Subject: Clean up moving llalignedarray and fast memcpy to llcommon

---
 indra/llcommon/llmemory.h | 24 +++++++++++++++++++-----
 1 file changed, 19 insertions(+), 5 deletions(-)

(limited to 'indra/llcommon')

diff --git a/indra/llcommon/llmemory.h b/indra/llcommon/llmemory.h
index 4938775e2b..61e30f11cc 100644
--- a/indra/llcommon/llmemory.h
+++ b/indra/llcommon/llmemory.h
@@ -201,24 +201,36 @@ inline void ll_memcpy_nonaliased_aligned_16(char* __restrict dst, const char* __
 
 	if (bytes > 64)
 	{
+
+		// Find start of 64b aligned area within block
+		//
 		void* begin_64 = LL_NEXT_ALIGNED_ADDRESS_64(dst);
 		
 		//at least 64 bytes before the end of the destination, switch to 16 byte copies
 		void* end_64 = end-64;
-		
+	
+		// Prefetch the head of the 64b area now
+		//
 		_mm_prefetch((char*)begin_64, _MM_HINT_NTA);
 		_mm_prefetch((char*)begin_64 + 64, _MM_HINT_NTA);
 		_mm_prefetch((char*)begin_64 + 128, _MM_HINT_NTA);
 		_mm_prefetch((char*)begin_64 + 192, _MM_HINT_NTA);
-		
+	
+		// Copy 16b chunks until we're 64b aligned
+		//
 		while (dst < begin_64)
 		{
 
 			_mm_store_ps((F32*)dst, _mm_load_ps((F32*)src));
-			dst += 4;
-			src += 4;
+			dst += 16;
+			src += 16;
 		}
-		
+	
+		// Copy 64b chunks up to your tail
+		//
+		// might be good to shmoo the 512b prefetch offset
+		// (characterize performance for various values)
+		//
 		while (dst < end_64)
 		{
 			_mm_prefetch((char*)src + 512, _MM_HINT_NTA);
@@ -232,6 +244,8 @@ inline void ll_memcpy_nonaliased_aligned_16(char* __restrict dst, const char* __
 		}
 	}
 
+	// Copy remainder 16b tail chunks (or ALL 16b chunks for sub-64b copies)
+	//
 	while (dst < end)
 	{
 		_mm_store_ps((F32*)dst, _mm_load_ps((F32*)src));
-- 
cgit v1.2.3


From 067a9cdfa903f3657ffd20008ae2933fb82718c8 Mon Sep 17 00:00:00 2001
From: Graham Madarasz <graham@lindenlab.com>
Date: Tue, 12 Mar 2013 01:05:06 -0700
Subject: Better compat with non-Ubuntu distros (bare typedef sometimes
 conflicts with OS decl of same).

---
 indra/llcommon/llapp.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'indra/llcommon')

diff --git a/indra/llcommon/llapp.h b/indra/llcommon/llapp.h
index a536a06ea5..afa06df23e 100644
--- a/indra/llcommon/llapp.h
+++ b/indra/llcommon/llapp.h
@@ -38,7 +38,7 @@ typedef LLAtomic32<U32> LLAtomicU32;
 class LLErrorThread;
 class LLLiveFile;
 #if LL_LINUX
-typedef struct siginfo siginfo_t;
+#include <signal.h>
 #endif
 
 typedef void (*LLAppErrorHandler)();
-- 
cgit v1.2.3


From 5d2fea6262d91eb8d3c06d97a160ca9373b96889 Mon Sep 17 00:00:00 2001
From: "Graham Madarasz (Graham Linden)" <graham@lindenlab.com>
Date: Wed, 13 Mar 2013 10:42:40 -0700
Subject: Move fast memcpy to llcommon and use it in llalignedarray pushback on
 all platforms. Code Review: DaveP

---
 indra/llcommon/llalignedarray.h |  16 +-----
 indra/llcommon/llmemory.h       | 116 +++++++++++++++++++++++++++++++++++++---
 2 files changed, 112 insertions(+), 20 deletions(-)

(limited to 'indra/llcommon')

diff --git a/indra/llcommon/llalignedarray.h b/indra/llcommon/llalignedarray.h
index 5e04e8050f..ed8fd31205 100644
--- a/indra/llcommon/llalignedarray.h
+++ b/indra/llcommon/llalignedarray.h
@@ -29,10 +29,6 @@
 
 #include "llmemory.h"
 
-#if LL_WINDOWS
-#include "llvector4a.h" // for 16b fast copy
-#endif
-
 template <class T, U32 alignment>
 class LLAlignedArray
 {
@@ -81,11 +77,7 @@ void LLAlignedArray<T, alignment>::push_back(const T& elem)
 		T* new_buf = (T*) ll_aligned_malloc(mCapacity*sizeof(T), alignment);
 		if (mArray)
 		{
-#if LL_WINDOWS
-			LLVector4a::memcpyNonAliased16((F32*) new_buf, (F32*) mArray, sizeof(T)*mElementCount);
-#else
-			memcpy((F32*)new_buf, (F32*)mArray, sizeof(T)*mElementCount);
-#endif
+			ll_memcpy_nonaliased_aligned_16((char*)new_buf, (char*)mArray, sizeof(T)*mElementCount);
 		}
 		old_buf = mArray;
 		mArray = new_buf;
@@ -106,11 +98,7 @@ void LLAlignedArray<T, alignment>::resize(U32 size)
 		T* new_buf = mCapacity > 0 ? (T*) ll_aligned_malloc(mCapacity*sizeof(T), alignment) : NULL;
 		if (mArray)
 		{
-#if LL_WINDOWS
-			LLVector4a::memcpyNonAliased16((F32*) new_buf, (F32*) mArray, sizeof(T)*mElementCount);
-#else
-			memcpy((F32*) new_buf, (F32*) mArray, sizeof(T)*mElementCount);
-#endif
+			ll_memcpy_nonaliased_aligned_16((char*) new_buf, (char*) mArray, sizeof(T)*mElementCount);
 			ll_aligned_free(mArray);
 		}
 
diff --git a/indra/llcommon/llmemory.h b/indra/llcommon/llmemory.h
index 46cabfadcd..61e30f11cc 100644
--- a/indra/llcommon/llmemory.h
+++ b/indra/llcommon/llmemory.h
@@ -36,6 +36,44 @@ class LLMutex ;
 #define LL_CHECK_MEMORY
 #endif
 
+LL_COMMON_API void ll_assert_aligned_func(uintptr_t ptr,U32 alignment);
+
+#ifdef SHOW_ASSERT
+#define ll_assert_aligned(ptr,alignment) ll_assert_aligned_func(reinterpret_cast<uintptr_t>(ptr),((U32)alignment))
+#else
+#define ll_assert_aligned(ptr,alignment)
+#endif
+
+#include <xmmintrin.h>
+
+template <typename T> T* LL_NEXT_ALIGNED_ADDRESS(T* address) 
+{ 
+	return reinterpret_cast<T*>(
+		(reinterpret_cast<uintptr_t>(address) + 0xF) & ~0xF);
+}
+
+template <typename T> T* LL_NEXT_ALIGNED_ADDRESS_64(T* address) 
+{ 
+	return reinterpret_cast<T*>(
+		(reinterpret_cast<uintptr_t>(address) + 0x3F) & ~0x3F);
+}
+
+#if LL_LINUX || LL_DARWIN
+
+#define			LL_ALIGN_PREFIX(x)
+#define			LL_ALIGN_POSTFIX(x)		__attribute__((aligned(x)))
+
+#elif LL_WINDOWS
+
+#define			LL_ALIGN_PREFIX(x)		__declspec(align(x))
+#define			LL_ALIGN_POSTFIX(x)
+
+#else
+#error "LL_ALIGN_PREFIX and LL_ALIGN_POSTFIX undefined"
+#endif
+
+#define LL_ALIGN_16(var) LL_ALIGN_PREFIX(16) var LL_ALIGN_POSTFIX(16)
+
 inline void* ll_aligned_malloc( size_t size, int align )
 {
 #if defined(LL_WINDOWS)
@@ -144,6 +182,78 @@ inline void ll_aligned_free_32(void *p)
 #endif
 }
 
+
+// Copy words 16-byte blocks from src to dst. Source and destination MUST NOT OVERLAP. 
+// Source and dest must be 16-byte aligned and size must be multiple of 16.
+//
+inline void ll_memcpy_nonaliased_aligned_16(char* __restrict dst, const char* __restrict src, size_t bytes)
+{
+	assert(src != NULL);
+	assert(dst != NULL);
+	assert(bytes > 0);
+	assert((bytes % sizeof(F32))== 0); 
+	ll_assert_aligned(src,16);
+	ll_assert_aligned(dst,16);
+	assert((src < dst) ? ((src + bytes) < dst) : ((dst + bytes) < src));
+	assert(bytes%16==0);
+
+	char* end = dst + bytes;
+
+	if (bytes > 64)
+	{
+
+		// Find start of 64b aligned area within block
+		//
+		void* begin_64 = LL_NEXT_ALIGNED_ADDRESS_64(dst);
+		
+		//at least 64 bytes before the end of the destination, switch to 16 byte copies
+		void* end_64 = end-64;
+	
+		// Prefetch the head of the 64b area now
+		//
+		_mm_prefetch((char*)begin_64, _MM_HINT_NTA);
+		_mm_prefetch((char*)begin_64 + 64, _MM_HINT_NTA);
+		_mm_prefetch((char*)begin_64 + 128, _MM_HINT_NTA);
+		_mm_prefetch((char*)begin_64 + 192, _MM_HINT_NTA);
+	
+		// Copy 16b chunks until we're 64b aligned
+		//
+		while (dst < begin_64)
+		{
+
+			_mm_store_ps((F32*)dst, _mm_load_ps((F32*)src));
+			dst += 16;
+			src += 16;
+		}
+	
+		// Copy 64b chunks up to your tail
+		//
+		// might be good to shmoo the 512b prefetch offset
+		// (characterize performance for various values)
+		//
+		while (dst < end_64)
+		{
+			_mm_prefetch((char*)src + 512, _MM_HINT_NTA);
+			_mm_prefetch((char*)dst + 512, _MM_HINT_NTA);
+			_mm_store_ps((F32*)dst, _mm_load_ps((F32*)src));
+			_mm_store_ps((F32*)(dst + 16), _mm_load_ps((F32*)(src + 16)));
+			_mm_store_ps((F32*)(dst + 32), _mm_load_ps((F32*)(src + 32)));
+			_mm_store_ps((F32*)(dst + 48), _mm_load_ps((F32*)(src + 48)));
+			dst += 64;
+			src += 64;
+		}
+	}
+
+	// Copy remainder 16b tail chunks (or ALL 16b chunks for sub-64b copies)
+	//
+	while (dst < end)
+	{
+		_mm_store_ps((F32*)dst, _mm_load_ps((F32*)src));
+		dst += 16;
+		src += 16;
+	}
+}
+
 #ifndef __DEBUG_PRIVATE_MEM__
 #define __DEBUG_PRIVATE_MEM__  0
 #endif
@@ -552,13 +662,7 @@ void  LLPrivateMemoryPoolTester::operator delete[](void* addr)
 
 // LLSingleton moved to llsingleton.h
 
-LL_COMMON_API void ll_assert_aligned_func(uintptr_t ptr,U32 alignment);
 
-#ifdef SHOW_ASSERT
-#define ll_assert_aligned(ptr,alignment) ll_assert_aligned_func(reinterpret_cast<uintptr_t>(ptr),((U32)alignment))
-#else
-#define ll_assert_aligned(ptr,alignment)
-#endif
 
 
 #endif
-- 
cgit v1.2.3


From bba84a3fa9a1af87f6a8080f9093f9277feb1292 Mon Sep 17 00:00:00 2001
From: "Graham Madarasz (Graham Linden)" <graham@lindenlab.com>
Date: Wed, 13 Mar 2013 13:38:30 -0700
Subject: Cleanup per code review of prev change with DaveP

---
 indra/llcommon/llmemory.h | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

(limited to 'indra/llcommon')

diff --git a/indra/llcommon/llmemory.h b/indra/llcommon/llmemory.h
index 61e30f11cc..d0e4bc9e25 100644
--- a/indra/llcommon/llmemory.h
+++ b/indra/llcommon/llmemory.h
@@ -188,14 +188,14 @@ inline void ll_aligned_free_32(void *p)
 //
 inline void ll_memcpy_nonaliased_aligned_16(char* __restrict dst, const char* __restrict src, size_t bytes)
 {
-	assert(src != NULL);
-	assert(dst != NULL);
-	assert(bytes > 0);
-	assert((bytes % sizeof(F32))== 0); 
+	llassert(src != NULL);
+	llassert(dst != NULL);
+	llassert(bytes >= 16);
+	llassert((bytes % sizeof(F32))== 0); 
+	llassert((src < dst) ? ((src + bytes) < dst) : ((dst + bytes) < src));
+	llassert(bytes%16==0);
 	ll_assert_aligned(src,16);
 	ll_assert_aligned(dst,16);
-	assert((src < dst) ? ((src + bytes) < dst) : ((dst + bytes) < src));
-	assert(bytes%16==0);
 
 	char* end = dst + bytes;
 
-- 
cgit v1.2.3


From ebb57d28ef2ce37e0803f346610e5dff4d65eb85 Mon Sep 17 00:00:00 2001
From: "Graham Madarasz (Graham Linden)" <graham@lindenlab.com>
Date: Wed, 13 Mar 2013 16:40:06 -0700
Subject: Resurrect merge victim...restoring ll_memcpy_nonaliased_aligned_16
 definition

---
 indra/llcommon/llmemory.h | 78 +++++++++++++++++++++++++++++++++++++++++++----
 1 file changed, 72 insertions(+), 6 deletions(-)

(limited to 'indra/llcommon')

diff --git a/indra/llcommon/llmemory.h b/indra/llcommon/llmemory.h
index 528af83b8f..61e30f11cc 100644
--- a/indra/llcommon/llmemory.h
+++ b/indra/llcommon/llmemory.h
@@ -182,6 +182,78 @@ inline void ll_aligned_free_32(void *p)
 #endif
 }
 
+
+// Copy words 16-byte blocks from src to dst. Source and destination MUST NOT OVERLAP. 
+// Source and dest must be 16-byte aligned and size must be multiple of 16.
+//
+inline void ll_memcpy_nonaliased_aligned_16(char* __restrict dst, const char* __restrict src, size_t bytes)
+{
+	assert(src != NULL);
+	assert(dst != NULL);
+	assert(bytes > 0);
+	assert((bytes % sizeof(F32))== 0); 
+	ll_assert_aligned(src,16);
+	ll_assert_aligned(dst,16);
+	assert((src < dst) ? ((src + bytes) < dst) : ((dst + bytes) < src));
+	assert(bytes%16==0);
+
+	char* end = dst + bytes;
+
+	if (bytes > 64)
+	{
+
+		// Find start of 64b aligned area within block
+		//
+		void* begin_64 = LL_NEXT_ALIGNED_ADDRESS_64(dst);
+		
+		//at least 64 bytes before the end of the destination, switch to 16 byte copies
+		void* end_64 = end-64;
+	
+		// Prefetch the head of the 64b area now
+		//
+		_mm_prefetch((char*)begin_64, _MM_HINT_NTA);
+		_mm_prefetch((char*)begin_64 + 64, _MM_HINT_NTA);
+		_mm_prefetch((char*)begin_64 + 128, _MM_HINT_NTA);
+		_mm_prefetch((char*)begin_64 + 192, _MM_HINT_NTA);
+	
+		// Copy 16b chunks until we're 64b aligned
+		//
+		while (dst < begin_64)
+		{
+
+			_mm_store_ps((F32*)dst, _mm_load_ps((F32*)src));
+			dst += 16;
+			src += 16;
+		}
+	
+		// Copy 64b chunks up to your tail
+		//
+		// might be good to shmoo the 512b prefetch offset
+		// (characterize performance for various values)
+		//
+		while (dst < end_64)
+		{
+			_mm_prefetch((char*)src + 512, _MM_HINT_NTA);
+			_mm_prefetch((char*)dst + 512, _MM_HINT_NTA);
+			_mm_store_ps((F32*)dst, _mm_load_ps((F32*)src));
+			_mm_store_ps((F32*)(dst + 16), _mm_load_ps((F32*)(src + 16)));
+			_mm_store_ps((F32*)(dst + 32), _mm_load_ps((F32*)(src + 32)));
+			_mm_store_ps((F32*)(dst + 48), _mm_load_ps((F32*)(src + 48)));
+			dst += 64;
+			src += 64;
+		}
+	}
+
+	// Copy remainder 16b tail chunks (or ALL 16b chunks for sub-64b copies)
+	//
+	while (dst < end)
+	{
+		_mm_store_ps((F32*)dst, _mm_load_ps((F32*)src));
+		dst += 16;
+		src += 16;
+	}
+}
+
 #ifndef __DEBUG_PRIVATE_MEM__
 #define __DEBUG_PRIVATE_MEM__  0
 #endif
@@ -590,13 +662,7 @@ void  LLPrivateMemoryPoolTester::operator delete[](void* addr)
 
 // LLSingleton moved to llsingleton.h
 
-LL_COMMON_API void ll_assert_aligned_func(uintptr_t ptr,U32 alignment);
 
-#ifdef SHOW_ASSERT
-#define ll_assert_aligned(ptr,alignment) ll_assert_aligned_func(reinterpret_cast<uintptr_t>(ptr),((U32)alignment))
-#else
-#define ll_assert_aligned(ptr,alignment)
-#endif
 
 
 #endif
-- 
cgit v1.2.3


From e8dfa28697c177e8ed08ff76a9b81f920805a92f Mon Sep 17 00:00:00 2001
From: "Graham Madarasz (Graham Linden)" <graham@lindenlab.com>
Date: Thu, 14 Mar 2013 14:12:26 -0700
Subject: Rollback Maestro interp changes

---
 indra/llcommon/llcriticaldamp.cpp | 50 ++++++++++++++++--------
 indra/llcommon/llcriticaldamp.h   | 82 ++-------------------------------------
 2 files changed, 37 insertions(+), 95 deletions(-)

(limited to 'indra/llcommon')

diff --git a/indra/llcommon/llcriticaldamp.cpp b/indra/llcommon/llcriticaldamp.cpp
index 27fef0e6dc..49aac9ce75 100644
--- a/indra/llcommon/llcriticaldamp.cpp
+++ b/indra/llcommon/llcriticaldamp.cpp
@@ -32,9 +32,8 @@
 // static members
 //-----------------------------------------------------------------------------
 LLFrameTimer LLCriticalDamp::sInternalTimer;
+std::map<F32, F32> LLCriticalDamp::sInterpolants;
 F32 LLCriticalDamp::sTimeDelta;
-F32	LLCriticalDamp::sInterpolants[kNumCachedInterpolants];
-F32 LLCriticalDamp::sInterpolatedValues[kNumCachedInterpolants];
 
 //-----------------------------------------------------------------------------
 // LLCriticalDamp()
@@ -42,17 +41,6 @@ F32 LLCriticalDamp::sInterpolatedValues[kNumCachedInterpolants];
 LLCriticalDamp::LLCriticalDamp()
 {
 	sTimeDelta = 0.f;
-
-	// Init the core interpolant values (to which many, many enums map)
-	//
-	setInterpolantConstant(InterpDelta_0_025, 0.025f);
-	setInterpolantConstant(InterpDelta_0_05,  0.05f );
-	setInterpolantConstant(InterpDelta_0_06,  0.06f);
-	setInterpolantConstant(InterpDelta_0_10,  0.10f);
-	setInterpolantConstant(InterpDelta_0_15,  0.15f);
-	setInterpolantConstant(InterpDelta_0_20,  0.20f);
-	setInterpolantConstant(InterpDelta_0_25,  0.25f);
-	setInterpolantConstant(InterpDelta_0_30,  0.30f);
 }
 
 // static
@@ -63,10 +51,40 @@ void LLCriticalDamp::updateInterpolants()
 {
 	sTimeDelta = sInternalTimer.getElapsedTimeAndResetF32();
 
-	U32 i;
-	for (i = 0; i < kNumCachedInterpolants; i++)
+	F32 time_constant;
+
+	for (std::map<F32, F32>::iterator iter = sInterpolants.begin();
+		 iter != sInterpolants.end(); iter++)
+	{
+		time_constant = iter->first;
+		F32 new_interpolant = 1.f - pow(2.f, -sTimeDelta / time_constant);
+		new_interpolant = llclamp(new_interpolant, 0.f, 1.f);
+		sInterpolants[time_constant] = new_interpolant;
+	}
+} 
+
+//-----------------------------------------------------------------------------
+// getInterpolant()
+//-----------------------------------------------------------------------------
+F32 LLCriticalDamp::getInterpolant(const F32 time_constant, BOOL use_cache)
+{
+	if (time_constant == 0.f)
+	{
+		return 1.f;
+	}
+
+	if (use_cache && sInterpolants.count(time_constant))
 	{
-		sInterpolatedValues[i] = llclamp(sTimeDelta / sInterpolants[ i], 0.0f, 1.0f);
+		return sInterpolants[time_constant];
 	}
+	
+	F32 interpolant = 1.f - pow(2.f, -sTimeDelta / time_constant);
+	interpolant = llclamp(interpolant, 0.f, 1.f);
+	if (use_cache)
+	{
+		sInterpolants[time_constant] = interpolant;
+	}
+
+	return interpolant;
 }
 
diff --git a/indra/llcommon/llcriticaldamp.h b/indra/llcommon/llcriticaldamp.h
index 19a2ddb77a..52f052ae25 100644
--- a/indra/llcommon/llcriticaldamp.h
+++ b/indra/llcommon/llcriticaldamp.h
@@ -32,98 +32,22 @@
 
 #include "llframetimer.h"
 
-// These enums each represent one fixed-time delta value
-// that we interpolate once given the actual sTimeDelta time
-// that has passed. This allows us to calculate the interp portion
-// of those values once and then look them up repeatedly per frame.
-//
-enum InterpDelta
-{	
-	InterpDelta_0_025,		// 0.025
-	InterpDeltaTeenier					= InterpDelta_0_025,
-	InterpDeltaFolderOpenTime			= InterpDelta_0_025,
-	InterpDeltaFolderCloseTime			= InterpDelta_0_025,
-	InterpDeltaCameraFocusHalfLife		= InterpDelta_0_025,	// USED TO BE ZERO....
-
-	InterpDelta_0_05,		// 0.05
-	InterpDeltaTeeny		= InterpDelta_0_05,
-
-	InterpDelta_0_06,		// 0.06
-	InterpDeltaObjectDampingConstant	= InterpDelta_0_06,	
-	InterpDeltaCameraZoomHalfLife		= InterpDelta_0_06,
-	InterpDeltaFovZoomHalfLife			= InterpDelta_0_06,
-	InterpDeltaManipulatorScaleHalfLife	= InterpDelta_0_06,
-	InterpDeltaContextFadeTime			= InterpDelta_0_06,
-
-	InterpDelta_0_10,		// 0.10
-	InterpDeltaSmaller					= InterpDelta_0_10,
-	InterpDeltaTargetLagHalfLife		= InterpDelta_0_10,
-	InterpDeltaSpeedAdjustTime			= InterpDelta_0_10,
-
-	InterpDelta_0_15,		// 0.15
-	InterpDeltaFadeWeight				= InterpDelta_0_15,
-	InterpDeltaHeadLookAtLagHalfLife	= InterpDelta_0_15,
-
-	InterpDelta_0_20,		// 0.20
-	InterpDeltaSmall					= InterpDelta_0_20,
-	InterpDeltaTorsoLagHalfLife			= InterpDelta_0_20,
-	InterpDeltaPositionDampingTC		= InterpDelta_0_20,
-
-	InterpDelta_0_25,		// 0.25
-	InterpDeltaCameraLagHalfLife		= InterpDelta_0_25,
-	InterpDeltaTorsoTargetLagHalfLife	= InterpDelta_0_25,
-	InterpDeltaTorsoLookAtLagHalfLife	= InterpDelta_0_25,
-
-	InterpDelta_0_30,		// 0.3
-	InterpDeltaSmallish		= InterpDelta_0_30,
-
-	// Dynamically set interpolants which use setInterpolantConstant
-	//
-	InterpDeltaCameraSmoothingHalfLife,	
-	InterpDeltaBehindnessLag,
-	InterpDeltaFocusLag,
-	InterpDeltaPositionLag,
-	InterpDeltaOpenTime,
-	InterpDeltaCloseTime,		
-
-	kNumCachedInterpolants
-};
-
 class LL_COMMON_API LLCriticalDamp 
 {
 public:
 	LLCriticalDamp();
 
-	// Updates all the known interp delta values for fast lookup in calls to getInterpolant(InterpDelta)
-	//
+	// MANIPULATORS
 	static void updateInterpolants();
 
-	static inline void setInterpolantConstant(InterpDelta whichDelta, const F32 time_constant)
-	{
-		llassert(whichDelta < kNumCachedInterpolants);
-		sInterpolants[whichDelta] = time_constant;
-	}
-
 	// ACCESSORS
-	static inline F32 getInterpolant(InterpDelta whichDelta)
-	{
-		llassert(whichDelta < kNumCachedInterpolants);
-		return sInterpolatedValues[whichDelta];
-	}
-
-	static inline F32 getInterpolant(const F32 time_constant)
-	{
-		return llclamp((sTimeDelta / time_constant), 0.0f, 1.0f);
-	}
+	static F32 getInterpolant(const F32 time_constant, BOOL use_cache = TRUE);
 
 protected:	
 	static LLFrameTimer sInternalTimer;	// frame timer for calculating deltas
 
-	//static std::map<F32, F32> 	sInterpolants;
-	static F32					sInterpolants[kNumCachedInterpolants];
-	static F32					sInterpolatedValues[kNumCachedInterpolants];
+	static std::map<F32, F32> 	sInterpolants;
 	static F32					sTimeDelta;
 };
 
 #endif  // LL_LLCRITICALDAMP_H
-
-- 
cgit v1.2.3


From 205938b652bc9218494835afadce095b29f1d19d Mon Sep 17 00:00:00 2001
From: simon <none@none>
Date: Mon, 15 Apr 2013 16:27:13 -0700
Subject: Fix crash introduced by LLInstanceTrackerBase optimization.  Reviewed
 by Kelly

---
 indra/llcommon/llinstancetracker.cpp | 13 ++++++++++++-
 1 file changed, 12 insertions(+), 1 deletion(-)

(limited to 'indra/llcommon')

diff --git a/indra/llcommon/llinstancetracker.cpp b/indra/llcommon/llinstancetracker.cpp
index 65ef4322f6..89430f82d7 100644
--- a/indra/llcommon/llinstancetracker.cpp
+++ b/indra/llcommon/llinstancetracker.cpp
@@ -32,7 +32,9 @@
 // external library headers
 // other Linden headers
 
-static void* sInstanceTrackerData[ kInstanceTrackTypeCount ] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
+static bool sInstanceTrackerData_initialized = false;
+static void* sInstanceTrackerData[ kInstanceTrackTypeCount ];
+
 
 void * & LLInstanceTrackerBase::getInstances(InstanceTrackType t)
 {
@@ -41,6 +43,15 @@ void * & LLInstanceTrackerBase::getInstances(InstanceTrackType t)
 	// the pair and returns a std::pair of (iterator, true). If the specified
 	// key DOES exist, insert() simply returns (iterator, false). One lookup
 	// handles both cases.
+	if (!sInstanceTrackerData_initialized)
+	{
+		for (S32 i = 0; i < (S32) kInstanceTrackTypeCount; i++)
+		{
+			sInstanceTrackerData[i] = NULL;
+		}
+		sInstanceTrackerData_initialized = true;
+	}
+
 	return sInstanceTrackerData[t];
 }
 
-- 
cgit v1.2.3


From 6742d90d39fbb5c5bc3b675f37841fd6c8ec09c9 Mon Sep 17 00:00:00 2001
From: simon <none@none>
Date: Wed, 17 Apr 2013 11:17:46 -0700
Subject: Some minor cleanups while hunting crashes.  Reviewed by Kelly

---
 indra/llcommon/llcommon.cpp        | 1 +
 indra/llcommon/llinstancetracker.h | 8 +++++++-
 indra/llcommon/llthread.cpp        | 3 ++-
 indra/llcommon/llthread.h          | 2 ++
 4 files changed, 12 insertions(+), 2 deletions(-)

(limited to 'indra/llcommon')

diff --git a/indra/llcommon/llcommon.cpp b/indra/llcommon/llcommon.cpp
index 8be9e4f4de..b938b0e65a 100644
--- a/indra/llcommon/llcommon.cpp
+++ b/indra/llcommon/llcommon.cpp
@@ -44,6 +44,7 @@ void LLCommon::initClass()
 	}
 	LLTimer::initClass();
 	LLThreadSafeRefCount::initThreadSafeRefCount();
+	assert_main_thread();		// Make sure we record the main thread
 // 	LLWorkerThread::initClass();
 // 	LLFrameCallbackManager::initClass();
 }
diff --git a/indra/llcommon/llinstancetracker.h b/indra/llcommon/llinstancetracker.h
index 0f952f56ac..b290526754 100644
--- a/indra/llcommon/llinstancetracker.h
+++ b/indra/llcommon/llinstancetracker.h
@@ -102,6 +102,8 @@ protected:
     };
 };
 
+LL_COMMON_API void assert_main_thread();
+
 /// This mix-in class adds support for tracking all instances of the specified class parameter T
 /// The (optional) key associates a value of type KEY with a given instance of T, for quick lookup
 /// If KEY is not provided, then instances are stored in a simple set
@@ -116,7 +118,11 @@ class LLInstanceTracker : public LLInstanceTrackerBase
 		InstanceMap sMap;
 	};
 	static StaticData& getStatic() { return LLInstanceTrackerBase::getStatic<StaticData, MyT, T, TRACKED>(); }
-	static InstanceMap& getMap_() { return getStatic().sMap; }
+	static InstanceMap& getMap_() 
+	{
+		// assert_main_thread();   fwiw this class is not thread safe, and it used by multiple threads.  Bad things happen.
+		return getStatic().sMap; 
+	}
 
 public:
 	class instance_iter : public boost::iterator_facade<instance_iter, T, boost::forward_traversal_tag>
diff --git a/indra/llcommon/llthread.cpp b/indra/llcommon/llthread.cpp
index 6c117f7daf..60adeeaeb7 100644
--- a/indra/llcommon/llthread.cpp
+++ b/indra/llcommon/llthread.cpp
@@ -67,7 +67,8 @@ LL_COMMON_API void assert_main_thread()
 	static U32 s_thread_id = LLThread::currentID();
 	if (LLThread::currentID() != s_thread_id)
 	{
-		llerrs << "Illegal execution outside main thread." << llendl;
+		llwarns << "Illegal execution from thread id " << (S32) LLThread::currentID()
+			<< " outside main thread " << (S32) s_thread_id << llendl;
 	}
 }
 
diff --git a/indra/llcommon/llthread.h b/indra/llcommon/llthread.h
index 8c95b1c0e5..11594f276e 100644
--- a/indra/llcommon/llthread.h
+++ b/indra/llcommon/llthread.h
@@ -311,4 +311,6 @@ public:
 
 //============================================================================
 
+extern LL_COMMON_API void assert_main_thread();
+
 #endif // LL_LLTHREAD_H
-- 
cgit v1.2.3


From e2eca610459362eda50f6a5edfb9ed5269fd5e51 Mon Sep 17 00:00:00 2001
From: simon <none@none>
Date: Tue, 23 Apr 2013 16:31:20 -0700
Subject: Revert LLThreadSafeRefCount optimization; caps fetching was failing. 
 Reviewed by Kelly

---
 indra/llcommon/llthread.h | 68 ++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 67 insertions(+), 1 deletion(-)

(limited to 'indra/llcommon')

diff --git a/indra/llcommon/llthread.h b/indra/llcommon/llthread.h
index 11594f276e..a6eb14db9d 100644
--- a/indra/llcommon/llthread.h
+++ b/indra/llcommon/llthread.h
@@ -225,6 +225,71 @@ void LLThread::unlockData()
 
 // see llmemory.h for LLPointer<> definition
 
+#if (1)		// Old code - see comment below
+class LL_COMMON_API LLThreadSafeRefCount
+{
+public:
+	static void initThreadSafeRefCount(); // creates sMutex
+	static void cleanupThreadSafeRefCount(); // destroys sMutex
+	
+private:
+	static LLMutex* sMutex;
+
+protected:
+	virtual ~LLThreadSafeRefCount(); // use unref()
+	
+public:
+	LLThreadSafeRefCount();
+	LLThreadSafeRefCount(const LLThreadSafeRefCount&);
+	LLThreadSafeRefCount& operator=(const LLThreadSafeRefCount& ref) 
+	{
+		if (sMutex)
+		{
+			sMutex->lock();
+		}
+		mRef = 0;
+		if (sMutex)
+		{
+			sMutex->unlock();
+		}
+		return *this;
+	}
+
+
+	
+	void ref()
+	{
+		if (sMutex) sMutex->lock();
+		mRef++; 
+		if (sMutex) sMutex->unlock();
+	} 
+
+	S32 unref()
+	{
+		llassert(mRef >= 1);
+		if (sMutex) sMutex->lock();
+		S32 res = --mRef;
+		if (sMutex) sMutex->unlock();
+		if (0 == res) 
+		{
+			delete this; 
+			return 0;
+		}
+		return res;
+	}	
+	S32 getNumRefs() const
+	{
+		return mRef;
+	}
+
+private: 
+	S32	mRef; 
+};
+
+#else
+	// New code -  This was from https://bitbucket.org/lindenlab/viewer-cat/commits/b03bb43e4ead57f904cb3c1e9745dc8460de6efc
+	// and attempts 
+
 class LL_COMMON_API LLThreadSafeRefCount
 {
 public:
@@ -263,7 +328,7 @@ public:
 			// so that two threads who get into the if in parallel
 			// don't both attempt to the delete.
 			//
-			mRef--;
+			mRef--;			// Simon:  why not  if (mRef == 1) delete this; ?   There still seems to be a window where mRef could be modified
 			if (mRef == 0)
 				delete this; 			
 			if (sMutex) sMutex->unlock();
@@ -280,6 +345,7 @@ public:
 private: 
 	LLAtomic32< S32	> mRef; 
 };
+#endif // new code
 
 /**
  * intrusive pointer support for LLThreadSafeRefCount
-- 
cgit v1.2.3


From 87ba85eaabbfd5fd7ad8ca8136f4783b1d932264 Mon Sep 17 00:00:00 2001
From: simon <none@none>
Date: Wed, 24 Apr 2013 09:35:38 -0700
Subject: =?UTF-8?q?=C3=AF=C2=BB=C2=BFdiff=20-r=2059c7bed66dfd=20indra/llco?=
 =?UTF-8?q?mmon/lleventapi.h?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 indra/llcommon/lleventapi.h                     |  4 +-
 indra/llcommon/lleventtimer.h                   |  2 +-
 indra/llcommon/llfasttimer.cpp                  |  8 +---
 indra/llcommon/llfasttimer.h                    |  4 +-
 indra/llcommon/llinstancetracker.cpp            | 22 ---------
 indra/llcommon/llinstancetracker.h              | 58 ++++--------------------
 indra/llcommon/llleap.h                         |  2 +-
 indra/llcommon/llsingleton.cpp                  |  1 -
 indra/llcommon/llsingleton.h                    | 60 +++++--------------------
 indra/llcommon/tests/llinstancetracker_test.cpp |  6 +--
 10 files changed, 29 insertions(+), 138 deletions(-)

(limited to 'indra/llcommon')

diff --git a/indra/llcommon/lleventapi.h b/indra/llcommon/lleventapi.h
index 10c7e7a23f..5991fe8fd5 100644
--- a/indra/llcommon/lleventapi.h
+++ b/indra/llcommon/lleventapi.h
@@ -41,10 +41,10 @@
  * Deriving from LLInstanceTracker lets us enumerate instances.
  */
 class LL_COMMON_API LLEventAPI: public LLDispatchListener,
-                  public INSTANCE_TRACKER_KEYED(LLEventAPI, std::string)
+                  public LLInstanceTracker<LLEventAPI, std::string>
 {
     typedef LLDispatchListener lbase;
-    typedef INSTANCE_TRACKER_KEYED(LLEventAPI, std::string) ibase;
+    typedef LLInstanceTracker<LLEventAPI, std::string> ibase;
 
 public:
 
diff --git a/indra/llcommon/lleventtimer.h b/indra/llcommon/lleventtimer.h
index e55f851758..dc918121e1 100644
--- a/indra/llcommon/lleventtimer.h
+++ b/indra/llcommon/lleventtimer.h
@@ -33,7 +33,7 @@
 #include "lltimer.h"
 
 // class for scheduling a function to be called at a given frequency (approximate, inprecise)
-class LL_COMMON_API LLEventTimer : public INSTANCE_TRACKER(LLEventTimer)
+class LL_COMMON_API LLEventTimer : public LLInstanceTracker<LLEventTimer>
 {
 public:
 
diff --git a/indra/llcommon/llfasttimer.cpp b/indra/llcommon/llfasttimer.cpp
index 9b15804e97..51a9441cd5 100644
--- a/indra/llcommon/llfasttimer.cpp
+++ b/indra/llcommon/llfasttimer.cpp
@@ -107,17 +107,13 @@ class NamedTimerFactory : public LLSingleton<NamedTimerFactory>
 {
 public:
 	NamedTimerFactory()
-	:	mTimerRoot(NULL)
-	{}
-
-	/*virtual */ void initSingleton()
+	:	mTimerRoot(new LLFastTimer::NamedTimer("root"))
 	{
-		mTimerRoot = new LLFastTimer::NamedTimer("root");
 		mRootFrameState.setNamedTimer(mTimerRoot);
 		mTimerRoot->setFrameState(&mRootFrameState);
 		mTimerRoot->mParent = mTimerRoot;
 		mTimerRoot->setCollapsed(false);
-		mRootFrameState.mParent = &mRootFrameState;
+		mRootFrameState.mParent = &mRootFrameState;	
 	}
 
 	~NamedTimerFactory()
diff --git a/indra/llcommon/llfasttimer.h b/indra/llcommon/llfasttimer.h
index a6b34bdc69..a99a1d88af 100644
--- a/indra/llcommon/llfasttimer.h
+++ b/indra/llcommon/llfasttimer.h
@@ -63,7 +63,7 @@ public:
 
 	// stores a "named" timer instance to be reused via multiple LLFastTimer stack instances
 	class LL_COMMON_API NamedTimer
-	:	public LLInstanceTracker<NamedTimer, InstanceTrackType_NamedTimer >
+	:	public LLInstanceTracker<NamedTimer>
 	{
 		friend class DeclareTimer;
 	public:
@@ -139,7 +139,7 @@ public:
 
 	// used to statically declare a new named timer
 	class LL_COMMON_API DeclareTimer
-	:	public LLInstanceTracker< DeclareTimer, InstanceTrackType_DeclareTimer >
+	:	public LLInstanceTracker< DeclareTimer >
 	{
 		friend class LLFastTimer;
 	public:
diff --git a/indra/llcommon/llinstancetracker.cpp b/indra/llcommon/llinstancetracker.cpp
index 89430f82d7..247d0dc4fb 100644
--- a/indra/llcommon/llinstancetracker.cpp
+++ b/indra/llcommon/llinstancetracker.cpp
@@ -32,26 +32,4 @@
 // external library headers
 // other Linden headers
 
-static bool sInstanceTrackerData_initialized = false;
-static void* sInstanceTrackerData[ kInstanceTrackTypeCount ];
-
-
-void * & LLInstanceTrackerBase::getInstances(InstanceTrackType t)
-{
-	// std::map::insert() is just what we want here. You attempt to insert a
-	// (key, value) pair. If the specified key doesn't yet exist, it inserts
-	// the pair and returns a std::pair of (iterator, true). If the specified
-	// key DOES exist, insert() simply returns (iterator, false). One lookup
-	// handles both cases.
-	if (!sInstanceTrackerData_initialized)
-	{
-		for (S32 i = 0; i < (S32) kInstanceTrackTypeCount; i++)
-		{
-			sInstanceTrackerData[i] = NULL;
-		}
-		sInstanceTrackerData_initialized = true;
-	}
-
-	return sInstanceTrackerData[t];
-}
 
diff --git a/indra/llcommon/llinstancetracker.h b/indra/llcommon/llinstancetracker.h
index b290526754..361182380a 100644
--- a/indra/llcommon/llinstancetracker.h
+++ b/indra/llcommon/llinstancetracker.h
@@ -38,33 +38,6 @@
 #include <boost/iterator/transform_iterator.hpp>
 #include <boost/iterator/indirect_iterator.hpp>
 
-enum InstanceTrackType
-{
-	InstanceTrackType_LLEventAPI,
-	InstanceTrackType_LLEventTimer,
-	InstanceTrackType_NamedTimer,
-	InstanceTrackType_DeclareTimer,
-	InstanceTrackType_LLLeap,
-	InstanceTrackType_LLGLNamePool,
-	InstanceTrackType_LLConsole,
-	InstanceTrackType_LLFloater,
-	InstanceTrackType_LLFloaterWebContent,
-	InstanceTrackType_LLLayoutStack,
-	InstanceTrackType_LLNotificationContext,
-	InstanceTrackType_LLWindow,
-	InstanceTrackType_LLControlGroup,
-	InstanceTrackType_LLControlCache,
-	InstanceTrackType_LLMediaCtrl,
-	InstanceTrackType_LLNameListCtrl,
-	InstanceTrackType_LLToast,
-	InstanceTrackType_Keyed,	// for integ tests
-	InstanceTrackType_Unkeyed,	// for integ tests
-	kInstanceTrackTypeCount
-};
-
-#define INSTANCE_TRACKER(T)			LLInstanceTracker< T, InstanceTrackType_##T >
-#define INSTANCE_TRACKER_KEYED(T,K)	LLInstanceTracker< T, InstanceTrackType_##T, K >
-
 /**
  * Base class manages "class-static" data that must actually have singleton
  * semantics: one instance per process, rather than one instance per module as
@@ -73,22 +46,7 @@ enum InstanceTrackType
 class LL_COMMON_API LLInstanceTrackerBase
 {
 protected:
-	/// Get a process-unique void* pointer slot for the specified type_info
-	//static void * & getInstances(std::type_info const & info);
-	static void * & getInstances(InstanceTrackType t);
-
-	/// Find or create a STATICDATA instance for the specified TRACKED class.
-	/// STATICDATA must be default-constructible.
-	template<typename STATICDATA, class TRACKED, class INST, InstanceTrackType TRACKEDTYPE>
-	static STATICDATA& getStatic()
-	{
-		void *& instances = getInstances(TRACKEDTYPE);
-		if (! instances)
-		{
-			instances = new STATICDATA;
-		}
-		return *static_cast<STATICDATA*>(instances);
-	}
+
 
     /// It's not essential to derive your STATICDATA (for use with
     /// getStatic()) from StaticBase; it's just that both known
@@ -108,16 +66,16 @@ LL_COMMON_API void assert_main_thread();
 /// The (optional) key associates a value of type KEY with a given instance of T, for quick lookup
 /// If KEY is not provided, then instances are stored in a simple set
 /// @NOTE: see explicit specialization below for default KEY==T* case
-template<typename T, enum InstanceTrackType TRACKED, typename KEY = T*>
+template<typename T, typename KEY = T*>
 class LLInstanceTracker : public LLInstanceTrackerBase
 {
-	typedef LLInstanceTracker<T, TRACKED, KEY> MyT;
+	typedef LLInstanceTracker<T, KEY> self_t;
 	typedef typename std::map<KEY, T*> InstanceMap;
 	struct StaticData: public StaticBase
 	{
 		InstanceMap sMap;
 	};
-	static StaticData& getStatic() { return LLInstanceTrackerBase::getStatic<StaticData, MyT, T, TRACKED>(); }
+	static StaticData& getStatic() { static StaticData sData; return sData;}
 	static InstanceMap& getMap_() 
 	{
 		// assert_main_thread();   fwiw this class is not thread safe, and it used by multiple threads.  Bad things happen.
@@ -263,16 +221,16 @@ private:
 
 /// explicit specialization for default case where KEY is T*
 /// use a simple std::set<T*>
-template<typename T, enum InstanceTrackType TRACKED>
-class LLInstanceTracker<T, TRACKED, T*> : public LLInstanceTrackerBase
+template<typename T>
+class LLInstanceTracker<T, T*> : public LLInstanceTrackerBase
 {
-	typedef LLInstanceTracker<T, TRACKED, T*> MyT;
+	typedef LLInstanceTracker<T, T*> self_t;
 	typedef typename std::set<T*> InstanceSet;
 	struct StaticData: public StaticBase
 	{
 		InstanceSet sSet;
 	};
-	static StaticData& getStatic() { return LLInstanceTrackerBase::getStatic<StaticData, MyT, T, TRACKED>(); }
+	static StaticData& getStatic() { static StaticData sData; return sData; }
 	static InstanceSet& getSet_() { return getStatic().sSet; }
 
 public:
diff --git a/indra/llcommon/llleap.h b/indra/llcommon/llleap.h
index d4e138f4be..e33f25e530 100644
--- a/indra/llcommon/llleap.h
+++ b/indra/llcommon/llleap.h
@@ -29,7 +29,7 @@
  * LLLeap* pointer should be validated before use by
  * LLLeap::getInstance(LLLeap*) (see LLInstanceTracker).
  */
-class LL_COMMON_API LLLeap: public INSTANCE_TRACKER(LLLeap)
+class LL_COMMON_API LLLeap: public LLInstanceTracker<LLLeap>
 {
 public:
 
diff --git a/indra/llcommon/llsingleton.cpp b/indra/llcommon/llsingleton.cpp
index eb8e2c9456..9b49e52377 100644
--- a/indra/llcommon/llsingleton.cpp
+++ b/indra/llcommon/llsingleton.cpp
@@ -28,5 +28,4 @@
 
 #include "llsingleton.h"
 
-std::map<std::string, void *> * LLSingletonRegistry::sSingletonMap = NULL;
 
diff --git a/indra/llcommon/llsingleton.h b/indra/llcommon/llsingleton.h
index 49d99f2cd0..84afeb563e 100644
--- a/indra/llcommon/llsingleton.h
+++ b/indra/llcommon/llsingleton.h
@@ -30,38 +30,6 @@
 #include <typeinfo>
 #include <boost/noncopyable.hpp>
 
-/// @brief A global registry of all singletons to prevent duplicate allocations
-/// across shared library boundaries
-class LL_COMMON_API LLSingletonRegistry {
-	private:
-		typedef std::map<std::string, void *> TypeMap;
-		static TypeMap * sSingletonMap;
-
-		static void checkInit()
-		{
-			if(sSingletonMap == NULL)
-			{
-				sSingletonMap = new TypeMap();
-			}
-		}
-
-	public:
-		template<typename T> static void * & get()
-		{
-			std::string name(typeid(T).name());
-
-			checkInit();
-
-			// the first entry of the pair returned by insert will be either the existing
-			// iterator matching our key, or the newly inserted NULL initialized entry
-			// see "Insert element" in http://www.sgi.com/tech/stl/UniqueAssociativeContainer.html
-			TypeMap::iterator result =
-				sSingletonMap->insert(std::make_pair(name, (void*)NULL)).first;
-
-			return result->second;
-		}
-};
-
 // LLSingleton implements the getInstance() method part of the Singleton
 // pattern. It can't make the derived class constructors protected, though, so
 // you have to do that yourself.
@@ -93,7 +61,6 @@ class LLSingleton : private boost::noncopyable
 private:
 	typedef enum e_init_state
 	{
-		UNINITIALIZED,
 		CONSTRUCTING,
 		INITIALIZING,
 		INITIALIZED,
@@ -109,8 +76,11 @@ private:
 		
 		SingletonInstanceData()
 		:	mSingletonInstance(NULL),
-			mInitState(UNINITIALIZED)
-		{}
+			mInitState(CONSTRUCTING)
+		{
+			mSingletonInstance = new DERIVED_TYPE(); 
+			mInitState = INITIALIZING;
+		}
 
 		~SingletonInstanceData()
 		{
@@ -159,16 +129,8 @@ public:
 	static SingletonInstanceData& getData()
 	{
 		// this is static to cache the lookup results
-		static void * & registry = LLSingletonRegistry::get<DERIVED_TYPE>();
-
-		// *TODO - look into making this threadsafe
-		if(NULL == registry)
-		{
-			static SingletonInstanceData data;
-			registry = &data;
-		}
-
-		return *static_cast<SingletonInstanceData *>(registry);
+		static SingletonInstanceData sData;
+		return sData;
 	}
 
 	static DERIVED_TYPE* getInstance()
@@ -185,13 +147,11 @@ public:
 			llwarns << "Trying to access deleted singleton " << typeid(DERIVED_TYPE).name() << " creating new instance" << llendl;
 		}
 		
-		if (!data.mSingletonInstance) 
+		if (data.mInitState == INITIALIZING) 
 		{
-			data.mInitState = CONSTRUCTING;
-			data.mSingletonInstance = new DERIVED_TYPE(); 
-			data.mInitState = INITIALIZING;
+			// go ahead and flag ourselves as initialized so we can be reentrant during initialization
+			data.mInitState = INITIALIZED;
 			data.mSingletonInstance->initSingleton(); 
-			data.mInitState = INITIALIZED;	
 		}
 		
 		return data.mSingletonInstance;
diff --git a/indra/llcommon/tests/llinstancetracker_test.cpp b/indra/llcommon/tests/llinstancetracker_test.cpp
index b2d82d1843..e769c3e22c 100644
--- a/indra/llcommon/tests/llinstancetracker_test.cpp
+++ b/indra/llcommon/tests/llinstancetracker_test.cpp
@@ -48,16 +48,16 @@ struct Badness: public std::runtime_error
     Badness(const std::string& what): std::runtime_error(what) {}
 };
 
-struct Keyed: public INSTANCE_TRACKER_KEYED(Keyed, std::string)
+struct Keyed: public LLInstanceTracker<Keyed, std::string>
 {
     Keyed(const std::string& name):
-        INSTANCE_TRACKER_KEYED(Keyed, std::string)(name),
+        LLInstanceTracker<Keyed, std::string>(name),
         mName(name)
     {}
     std::string mName;
 };
 
-struct Unkeyed: public INSTANCE_TRACKER(Unkeyed)
+struct Unkeyed: public LLInstanceTracker<Unkeyed>
 {
     Unkeyed(const std::string& thrw="")
     {
-- 
cgit v1.2.3


From faf844ff996f205af6eb6b2ebd5290594da8d142 Mon Sep 17 00:00:00 2001
From: simon <none@none>
Date: Wed, 24 Apr 2013 10:59:25 -0700
Subject: Trivial change to note that earlier changeset 27742 (1c3262183eb5) is
 a re-work of the LLInstanceTracker code done by Richard.    The commit
 comment is cryptic

---
 indra/llcommon/llinstancetracker.cpp | 1 -
 1 file changed, 1 deletion(-)

(limited to 'indra/llcommon')

diff --git a/indra/llcommon/llinstancetracker.cpp b/indra/llcommon/llinstancetracker.cpp
index 247d0dc4fb..64a313b5ff 100644
--- a/indra/llcommon/llinstancetracker.cpp
+++ b/indra/llcommon/llinstancetracker.cpp
@@ -32,4 +32,3 @@
 // external library headers
 // other Linden headers
 
-
-- 
cgit v1.2.3


From b49f6e1e744e7650fbea77e5744343d223e962a3 Mon Sep 17 00:00:00 2001
From: simon <none@none>
Date: Thu, 25 Apr 2013 16:21:32 -0700
Subject: Clean up LLSingleton work - special case to re-create instance if
 it's been deleted.

---
 indra/llcommon/llsingleton.h | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

(limited to 'indra/llcommon')

diff --git a/indra/llcommon/llsingleton.h b/indra/llcommon/llsingleton.h
index 84afeb563e..550e3c0d20 100644
--- a/indra/llcommon/llsingleton.h
+++ b/indra/llcommon/llsingleton.h
@@ -145,7 +145,9 @@ public:
 		if (data.mInitState == DELETED)
 		{
 			llwarns << "Trying to access deleted singleton " << typeid(DERIVED_TYPE).name() << " creating new instance" << llendl;
-		}
+			data.mSingletonInstance = new DERIVED_TYPE(); 
+			data.mInitState = INITIALIZING;
+		}	// Fall into INITIALIZING case below 
 		
 		if (data.mInitState == INITIALIZING) 
 		{
-- 
cgit v1.2.3


From 39638b0de3734fea2d112161a3289b67f7594ba3 Mon Sep 17 00:00:00 2001
From: simon <none@none>
Date: Fri, 26 Apr 2013 15:54:03 -0700
Subject: Convert LLThreadSafeRefCount back to atomic ref counting.  Reviewed
 by Kelly

---
 indra/llcommon/llthread.h | 90 +++++------------------------------------------
 1 file changed, 9 insertions(+), 81 deletions(-)

(limited to 'indra/llcommon')

diff --git a/indra/llcommon/llthread.h b/indra/llcommon/llthread.h
index a6eb14db9d..f51d985b5f 100644
--- a/indra/llcommon/llthread.h
+++ b/indra/llcommon/llthread.h
@@ -225,7 +225,6 @@ void LLThread::unlockData()
 
 // see llmemory.h for LLPointer<> definition
 
-#if (1)		// Old code - see comment below
 class LL_COMMON_API LLThreadSafeRefCount
 {
 public:
@@ -243,99 +242,28 @@ public:
 	LLThreadSafeRefCount(const LLThreadSafeRefCount&);
 	LLThreadSafeRefCount& operator=(const LLThreadSafeRefCount& ref) 
 	{
-		if (sMutex)
-		{
-			sMutex->lock();
-		}
 		mRef = 0;
-		if (sMutex)
-		{
-			sMutex->unlock();
-		}
 		return *this;
 	}
 
-
-	
 	void ref()
 	{
-		if (sMutex) sMutex->lock();
 		mRef++; 
-		if (sMutex) sMutex->unlock();
 	} 
 
-	S32 unref()
+	void unref()
 	{
 		llassert(mRef >= 1);
-		if (sMutex) sMutex->lock();
-		S32 res = --mRef;
-		if (sMutex) sMutex->unlock();
-		if (0 == res) 
-		{
-			delete this; 
-			return 0;
+		if ((--mRef) == 0)		// See note in llapr.h on atomic decrement operator return value.  
+		{	
+			// If we hit zero, the caller should be the only smart pointer owning the object and we can delete it.
+			// It is technically possible for a vanilla pointer to mess this up, or another thread to
+			// jump in, find this object, create another smart pointer and end up dangling, but if
+			// the code is that bad and not thread-safe, it's trouble already.
+			delete this;
 		}
-		return res;
-	}	
-	S32 getNumRefs() const
-	{
-		return mRef;
 	}
 
-private: 
-	S32	mRef; 
-};
-
-#else
-	// New code -  This was from https://bitbucket.org/lindenlab/viewer-cat/commits/b03bb43e4ead57f904cb3c1e9745dc8460de6efc
-	// and attempts 
-
-class LL_COMMON_API LLThreadSafeRefCount
-{
-public:
-	static void initThreadSafeRefCount(); // creates sMutex
-	static void cleanupThreadSafeRefCount(); // destroys sMutex
-	
-private:
-	static LLMutex* sMutex;
-
-protected:
-	virtual ~LLThreadSafeRefCount(); // use unref()
-	
-public:
-	LLThreadSafeRefCount();
-	LLThreadSafeRefCount(const LLThreadSafeRefCount&);
-	LLThreadSafeRefCount& operator=(const LLThreadSafeRefCount& ref) 
-	{
-		mRef = 0;
-		return *this;
-	}
-
-	void ref()
-	{
-		mRef++; 
-	} 
-
-	S32 unref()
-	{
-		llassert(mRef >= 1);		
-		bool time_to_die = (mRef == 1);		
-		if (time_to_die)
-		{
-			if (sMutex) sMutex->lock();
-			// Looks redundant, but is very much not
-			// We need to check again once we've acquired the lock
-			// so that two threads who get into the if in parallel
-			// don't both attempt to the delete.
-			//
-			mRef--;			// Simon:  why not  if (mRef == 1) delete this; ?   There still seems to be a window where mRef could be modified
-			if (mRef == 0)
-				delete this; 			
-			if (sMutex) sMutex->unlock();
-			return 0;
-		}
-		return --mRef;		
-	}
 	S32 getNumRefs() const
 	{
 		const S32 currentVal = mRef.CurrentValue();
@@ -345,7 +273,7 @@ public:
 private: 
 	LLAtomic32< S32	> mRef; 
 };
-#endif // new code
+
 
 /**
  * intrusive pointer support for LLThreadSafeRefCount
-- 
cgit v1.2.3


From 348d4b66806cca07c91cab63f810d3d986e12377 Mon Sep 17 00:00:00 2001
From: simon <none@none>
Date: Wed, 1 May 2013 14:44:09 -0700
Subject: Manually pull in Richard's fixes for llcommon/llsingleton.h

---
 indra/llcommon/llsingleton.h | 101 +++++++++++++++++++++++++------------------
 1 file changed, 58 insertions(+), 43 deletions(-)

(limited to 'indra/llcommon')

diff --git a/indra/llcommon/llsingleton.h b/indra/llcommon/llsingleton.h
index 550e3c0d20..40002313f1 100644
--- a/indra/llcommon/llsingleton.h
+++ b/indra/llcommon/llsingleton.h
@@ -61,6 +61,7 @@ class LLSingleton : private boost::noncopyable
 private:
 	typedef enum e_init_state
 	{
+		UNINITIALIZED,
 		CONSTRUCTING,
 		INITIALIZING,
 		INITIALIZED,
@@ -68,23 +69,23 @@ private:
 	} EInitState;
 	
 	// stores pointer to singleton instance
-	// and tracks initialization state of singleton
-	struct SingletonInstanceData
+	struct SingletonLifetimeManager
 	{
-		EInitState		mInitState;
-		DERIVED_TYPE*	mSingletonInstance;
-		
-		SingletonInstanceData()
-		:	mSingletonInstance(NULL),
-			mInitState(CONSTRUCTING)
+		SingletonLifetimeManager()
+		{
+			construct();
+		}
+
+		static void construct()
 		{
-			mSingletonInstance = new DERIVED_TYPE(); 
-			mInitState = INITIALIZING;
+			sData.mInitState = CONSTRUCTING;
+			sData.mInstance = new DERIVED_TYPE(); 
+			sData.mInitState = INITIALIZING;
 		}
 
-		~SingletonInstanceData()
+		~SingletonLifetimeManager()
 		{
-			if (mInitState != DELETED)
+			if (sData.mInitState != DELETED)
 			{
 				deleteSingleton();
 			}
@@ -94,9 +95,8 @@ private:
 public:
 	virtual ~LLSingleton()
 	{
-		SingletonInstanceData& data = getData();
-		data.mSingletonInstance = NULL;
-		data.mInitState = DELETED;
+		sData.mInstance = NULL;
+		sData.mInitState = DELETED;
 	}
 
 	/**
@@ -121,42 +121,46 @@ public:
 	 */
 	static void deleteSingleton()
 	{
-		delete getData().mSingletonInstance;
-		getData().mSingletonInstance = NULL;
-		getData().mInitState = DELETED;
+		delete sData.mInstance;
+		sData.mInstance = NULL;
+		sData.mInitState = DELETED;
 	}
 
-	static SingletonInstanceData& getData()
-	{
-		// this is static to cache the lookup results
-		static SingletonInstanceData sData;
-		return sData;
-	}
 
 	static DERIVED_TYPE* getInstance()
 	{
-		SingletonInstanceData& data = getData();
+		static SingletonLifetimeManager sLifeTimeMgr;
 
-		if (data.mInitState == CONSTRUCTING)
+		switch (sData.mInitState)
 		{
+		case UNINITIALIZED:
+			// should never be uninitialized at this point
+			llassert(false);
+			return NULL;
+		case CONSTRUCTING:
 			llerrs << "Tried to access singleton " << typeid(DERIVED_TYPE).name() << " from singleton constructor!" << llendl;
-		}
-
-		if (data.mInitState == DELETED)
-		{
-			llwarns << "Trying to access deleted singleton " << typeid(DERIVED_TYPE).name() << " creating new instance" << llendl;
-			data.mSingletonInstance = new DERIVED_TYPE(); 
-			data.mInitState = INITIALIZING;
-		}	// Fall into INITIALIZING case below 
-		
-		if (data.mInitState == INITIALIZING) 
-		{
+			return NULL;
+		case INITIALIZING:
 			// go ahead and flag ourselves as initialized so we can be reentrant during initialization
-			data.mInitState = INITIALIZED;
-			data.mSingletonInstance->initSingleton(); 
+			sData.mInitState = INITIALIZED;	
+			sData.mInstance->initSingleton(); 
+			return sData.mInstance;
+		case INITIALIZED:
+			return sData.mInstance;
+		case DELETED:
+			llwarns << "Trying to access deleted singleton " << typeid(DERIVED_TYPE).name() << " creating new instance" << llendl;
+			SingletonLifetimeManager::construct();
+			sData.mInitState = INITIALIZED;	
+			sData.mInstance->initSingleton(); 
+			return sData.mInstance;
 		}
-		
-		return data.mSingletonInstance;
+
+		return NULL;
+	}
+
+	static DERIVED_TYPE* getIfExists()
+	{
+		return sData.mInstance;
 	}
 
 	// Reference version of getInstance()
@@ -170,18 +174,29 @@ public:
 	// Use this to avoid accessing singletons before the can safely be constructed
 	static bool instanceExists()
 	{
-		return getData().mInitState == INITIALIZED;
+		return sData.mInitState == INITIALIZED;
 	}
 	
 	// Has this singleton already been deleted?
 	// Use this to avoid accessing singletons from a static object's destructor
 	static bool destroyed()
 	{
-		return getData().mInitState == DELETED;
+		return sData.mInitState == DELETED;
 	}
 
 private:
+
 	virtual void initSingleton() {}
+
+	struct SingletonData
+	{
+		EInitState		mInitState;
+		DERIVED_TYPE*	mInstance;
+	};
+	static SingletonData sData;
 };
 
+template<typename T>
+typename LLSingleton<T>::SingletonData LLSingleton<T>::sData;
+
 #endif
-- 
cgit v1.2.3


From f111b5b1135ee31434acb81d5a3e63e4812e257f Mon Sep 17 00:00:00 2001
From: simon <none@none>
Date: Tue, 14 May 2013 09:24:58 -0700
Subject: Fix EOL characters

---
 indra/llcommon/llstringtable.h | 418 ++++++++++++++++++++---------------------
 1 file changed, 209 insertions(+), 209 deletions(-)

(limited to 'indra/llcommon')

diff --git a/indra/llcommon/llstringtable.h b/indra/llcommon/llstringtable.h
index 787a046741..ff09e71677 100755
--- a/indra/llcommon/llstringtable.h
+++ b/indra/llcommon/llstringtable.h
@@ -1,209 +1,209 @@
-/** 
- * @file llstringtable.h
- * @brief The LLStringTable class provides a _fast_ method for finding
- * unique copies of strings.
- *
- * $LicenseInfo:firstyear=2001&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_STRING_TABLE_H
-#define LL_STRING_TABLE_H
-
-#include "lldefs.h"
-#include "llformat.h"
-#include "llstl.h"
-#include <list>
-#include <set>
-
-#if LL_WINDOWS
-# if (_MSC_VER >= 1300 && _MSC_VER < 1400)
-#  define STRING_TABLE_HASH_MAP 1
-# endif
-#else
-//# define STRING_TABLE_HASH_MAP 1
-#endif
-
-const U32 MAX_STRINGS_LENGTH = 256;
-
-class LL_COMMON_API LLStringTableEntry
-{
-public:
-	LLStringTableEntry(const char *str);
-	~LLStringTableEntry();
-
-	void incCount()		{ mCount++; }
-	BOOL decCount()		{ return --mCount; }
-
-	char *mString;
-	S32  mCount;
-};
-
-class LL_COMMON_API LLStringTable
-{
-public:
-	LLStringTable(int tablesize);
-	~LLStringTable();
-
-	char *checkString(const char *str);
-	char *checkString(const std::string& str);
-	LLStringTableEntry *checkStringEntry(const char *str);
-	LLStringTableEntry *checkStringEntry(const std::string& str);
-
-	char *addString(const char *str);
-	char *addString(const std::string& str);
-	LLStringTableEntry *addStringEntry(const char *str);
-	LLStringTableEntry *addStringEntry(const std::string& str);
-	void  removeString(const char *str);
-
-	S32 mMaxEntries;
-	S32 mUniqueEntries;
-	
-#if STRING_TABLE_HASH_MAP
-#if LL_WINDOWS
-	typedef std::hash_multimap<U32, LLStringTableEntry *> string_hash_t;
-#else
-	typedef __gnu_cxx::hash_multimap<U32, LLStringTableEntry *> string_hash_t;
-#endif
-	string_hash_t mStringHash;
-#else
-	typedef std::list<LLStringTableEntry *> string_list_t;
-	typedef string_list_t * string_list_ptr_t;
-	string_list_ptr_t	*mStringList;
-#endif	
-};
-
-extern LL_COMMON_API LLStringTable gStringTable;
-
-//============================================================================
-
-// This class is designed to be used locally,
-// e.g. as a member of an LLXmlTree
-// Strings can be inserted only, then quickly looked up
-
-typedef const std::string* LLStdStringHandle;
-
-class LL_COMMON_API LLStdStringTable
-{
-public:
-	LLStdStringTable(S32 tablesize = 0)
-	{
-		if (tablesize == 0)
-		{
-			tablesize = 256; // default
-		}
-		// Make sure tablesize is power of 2
-		for (S32 i = 31; i>0; i--)
-		{
-			if (tablesize & (1<<i))
-			{
-				if (tablesize >= (3<<(i-1)))
-					tablesize = (1<<(i+1));
-				else
-					tablesize = (1<<i);
-				break;
-			}
-		}
-		mTableSize = tablesize;
-		mStringList = new string_set_t[tablesize];
-	}
-	~LLStdStringTable()
-	{
-		cleanup();
-		delete[] mStringList;
-	}
-	void cleanup()
-	{
-		// remove strings
-		for (S32 i = 0; i<mTableSize; i++)
-		{
-			string_set_t& stringset = mStringList[i];
-			for (string_set_t::iterator iter = stringset.begin(); iter != stringset.end(); iter++)
-			{
-				delete *iter;
-			}
-			stringset.clear();
-		}
-	}
-
-	LLStdStringHandle lookup(const std::string& s)
-	{
-		U32 hashval = makehash(s);
-		return lookup(hashval, s);
-	}
-	
-	LLStdStringHandle checkString(const std::string& s)
-	{
-		U32 hashval = makehash(s);
-		return lookup(hashval, s);
-	}
-
-	LLStdStringHandle insert(const std::string& s)
-	{
-		U32 hashval = makehash(s);
-		LLStdStringHandle result = lookup(hashval, s);
-		if (result == NULL)
-		{
-			result = new std::string(s);
-			mStringList[hashval].insert(result);
-		}
-		return result;
-	}
-	LLStdStringHandle addString(const std::string& s)
-	{
-		return insert(s);
-	}
-	
-private:
-	U32 makehash(const std::string& s)
-	{
-		S32 len = (S32)s.size();
-		const char* c = s.c_str();
-		U32 hashval = 0;
-		for (S32 i=0; i<len; i++)
-		{
-			hashval = ((hashval<<5) + hashval) + *c++;
-		}
-		return hashval & (mTableSize-1);
-	}
-	LLStdStringHandle lookup(U32 hashval, const std::string& s)
-	{
-		string_set_t& stringset = mStringList[hashval];
-		LLStdStringHandle handle = &s;
-		string_set_t::iterator iter = stringset.find(handle); // compares actual strings
-		if (iter != stringset.end())
-		{
-			return *iter;
-		}
-		else
-		{
-			return NULL;
-		}
-	}
-	
-private:
-	S32 mTableSize;
-	typedef std::set<LLStdStringHandle, compare_pointer_contents<std::string> > string_set_t;
-	string_set_t* mStringList; // [mTableSize]
-};
-
-
-#endif
+/** 
+ * @file llstringtable.h
+ * @brief The LLStringTable class provides a _fast_ method for finding
+ * unique copies of strings.
+ *
+ * $LicenseInfo:firstyear=2001&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_STRING_TABLE_H
+#define LL_STRING_TABLE_H
+
+#include "lldefs.h"
+#include "llformat.h"
+#include "llstl.h"
+#include <list>
+#include <set>
+
+#if LL_WINDOWS
+# if (_MSC_VER >= 1300 && _MSC_VER < 1400)
+#  define STRING_TABLE_HASH_MAP 1
+# endif
+#else
+//# define STRING_TABLE_HASH_MAP 1
+#endif
+
+const U32 MAX_STRINGS_LENGTH = 256;
+
+class LL_COMMON_API LLStringTableEntry
+{
+public:
+	LLStringTableEntry(const char *str);
+	~LLStringTableEntry();
+
+	void incCount()		{ mCount++; }
+	BOOL decCount()		{ return --mCount; }
+
+	char *mString;
+	S32  mCount;
+};
+
+class LL_COMMON_API LLStringTable
+{
+public:
+	LLStringTable(int tablesize);
+	~LLStringTable();
+
+	char *checkString(const char *str);
+	char *checkString(const std::string& str);
+	LLStringTableEntry *checkStringEntry(const char *str);
+	LLStringTableEntry *checkStringEntry(const std::string& str);
+
+	char *addString(const char *str);
+	char *addString(const std::string& str);
+	LLStringTableEntry *addStringEntry(const char *str);
+	LLStringTableEntry *addStringEntry(const std::string& str);
+	void  removeString(const char *str);
+
+	S32 mMaxEntries;
+	S32 mUniqueEntries;
+	
+#if STRING_TABLE_HASH_MAP
+#if LL_WINDOWS
+	typedef std::hash_multimap<U32, LLStringTableEntry *> string_hash_t;
+#else
+	typedef __gnu_cxx::hash_multimap<U32, LLStringTableEntry *> string_hash_t;
+#endif
+	string_hash_t mStringHash;
+#else
+	typedef std::list<LLStringTableEntry *> string_list_t;
+	typedef string_list_t * string_list_ptr_t;
+	string_list_ptr_t	*mStringList;
+#endif	
+};
+
+extern LL_COMMON_API LLStringTable gStringTable;
+
+//============================================================================
+
+// This class is designed to be used locally,
+// e.g. as a member of an LLXmlTree
+// Strings can be inserted only, then quickly looked up
+
+typedef const std::string* LLStdStringHandle;
+
+class LL_COMMON_API LLStdStringTable
+{
+public:
+	LLStdStringTable(S32 tablesize = 0)
+	{
+		if (tablesize == 0)
+		{
+			tablesize = 256; // default
+		}
+		// Make sure tablesize is power of 2
+		for (S32 i = 31; i>0; i--)
+		{
+			if (tablesize & (1<<i))
+			{
+				if (tablesize >= (3<<(i-1)))
+					tablesize = (1<<(i+1));
+				else
+					tablesize = (1<<i);
+				break;
+			}
+		}
+		mTableSize = tablesize;
+		mStringList = new string_set_t[tablesize];
+	}
+	~LLStdStringTable()
+	{
+		cleanup();
+		delete[] mStringList;
+	}
+	void cleanup()
+	{
+		// remove strings
+		for (S32 i = 0; i<mTableSize; i++)
+		{
+			string_set_t& stringset = mStringList[i];
+			for (string_set_t::iterator iter = stringset.begin(); iter != stringset.end(); iter++)
+			{
+				delete *iter;
+			}
+			stringset.clear();
+		}
+	}
+
+	LLStdStringHandle lookup(const std::string& s)
+	{
+		U32 hashval = makehash(s);
+		return lookup(hashval, s);
+	}
+	
+	LLStdStringHandle checkString(const std::string& s)
+	{
+		U32 hashval = makehash(s);
+		return lookup(hashval, s);
+	}
+
+	LLStdStringHandle insert(const std::string& s)
+	{
+		U32 hashval = makehash(s);
+		LLStdStringHandle result = lookup(hashval, s);
+		if (result == NULL)
+		{
+			result = new std::string(s);
+			mStringList[hashval].insert(result);
+		}
+		return result;
+	}
+	LLStdStringHandle addString(const std::string& s)
+	{
+		return insert(s);
+	}
+	
+private:
+	U32 makehash(const std::string& s)
+	{
+		S32 len = (S32)s.size();
+		const char* c = s.c_str();
+		U32 hashval = 0;
+		for (S32 i=0; i<len; i++)
+		{
+			hashval = ((hashval<<5) + hashval) + *c++;
+		}
+		return hashval & (mTableSize-1);
+	}
+	LLStdStringHandle lookup(U32 hashval, const std::string& s)
+	{
+		string_set_t& stringset = mStringList[hashval];
+		LLStdStringHandle handle = &s;
+		string_set_t::iterator iter = stringset.find(handle); // compares actual strings
+		if (iter != stringset.end())
+		{
+			return *iter;
+		}
+		else
+		{
+			return NULL;
+		}
+	}
+	
+private:
+	S32 mTableSize;
+	typedef std::set<LLStdStringHandle, compare_pointer_contents<std::string> > string_set_t;
+	string_set_t* mStringList; // [mTableSize]
+};
+
+
+#endif
-- 
cgit v1.2.3


From 8a16b55bf8a87d29c116d9061d9701e8b844cc7b Mon Sep 17 00:00:00 2001
From: simon <none@none>
Date: Tue, 21 May 2013 09:11:50 -0700
Subject: MAINT-2711 : Add missing LSL constants for llGetObjectDetails() to
 the viewer. Reviewed by Kelly

---
 indra/llcommon/lllslconstants.h | 18 ++++++++++++++++++
 1 file changed, 18 insertions(+)

(limited to 'indra/llcommon')

diff --git a/indra/llcommon/lllslconstants.h b/indra/llcommon/lllslconstants.h
index 9f32598e61..83fa5bc249 100755
--- a/indra/llcommon/lllslconstants.h
+++ b/indra/llcommon/lllslconstants.h
@@ -179,6 +179,24 @@ const S32 OBJECT_VELOCITY = 5;
 const S32 OBJECT_OWNER = 6;
 const S32 OBJECT_GROUP = 7;
 const S32 OBJECT_CREATOR = 8;
+const S32 OBJECT_RUNNING_SCRIPT_COUNT = 9;
+const S32 OBJECT_TOTAL_SCRIPT_COUNT = 10;
+const S32 OBJECT_SCRIPT_MEMORY = 11;
+const S32 OBJECT_SCRIPT_TIME = 12;
+const S32 OBJECT_PRIM_EQUIVALENCE = 13;
+const S32 OBJECT_SERVER_COST = 14;
+const S32 OBJECT_STREAMING_COST = 15;
+const S32 OBJECT_PHYSICS_COST = 16;
+const S32 OBJECT_CHARACTER_TIME = 17;
+const S32 OBJECT_ROOT = 18;
+const S32 OBJECT_ATTACHED_POINT = 19;
+const S32 OBJECT_PATHFINDING_TYPE = 20;
+const S32 OBJECT_PHYSICS = 21;
+const S32 OBJECT_PHANTOM = 22;
+const S32 OBJECT_TEMP_ON_REZ = 23;
+const S32 OBJECT_RENDER_WEIGHT = 24;
+const S32 OBJECT_ATTACHMENT_GEOMETRY_BYTES = 25;
+const S32 OBJECT_ATTACHMENT_SURFACE_AREA = 26;
 
 // llTextBox() magic token string - yes this is a hack.  sue me.
 char const* const TEXTBOX_MAGIC_TOKEN = "!!llTextBox!!";
-- 
cgit v1.2.3