From a7efdf89c23c8ad56791ec63cbb93a2c5a541df3 Mon Sep 17 00:00:00 2001 From: coppro Date: Thu, 18 Oct 2007 23:55:24 +0000 Subject: [PATCH] Added some stuff for platforms without TLS git-svn-id: svn://svn.code.sf.net/p/magicseteditor/code/trunk@767 0fc631ac-6414-0410-93d0-97cfa31319b6 --- src/util/dynamic_arg.hpp | 128 ++++++++++++++++++++++++++++----------- 1 file changed, 91 insertions(+), 37 deletions(-) diff --git a/src/util/dynamic_arg.hpp b/src/util/dynamic_arg.hpp index baef5648..97562ccd 100644 --- a/src/util/dynamic_arg.hpp +++ b/src/util/dynamic_arg.hpp @@ -16,53 +16,107 @@ // ----------------------------------------------------------------------------- : Includes #include +#include // ----------------------------------------------------------------------------- : Dynamic argument #ifdef _MSC_VER # define THREAD_LOCAL __declspec(thread) -#else +# define HAVE_TLS 1 +#elseif defined __linux__ # define THREAD_LOCAL __thread +# define HAVE_TLS 1 +#else +# define HAVE_TLS 0 #endif -/// Declare a dynamic argument. -/** The value of the argument can be got with: name() - * To change the value use WITH_DYNAMIC_ARG(name, newValue) - * To be used in a header file. Use IMPLEMENT_DYN_ARG in a source file - */ -#define DECLARE_DYNAMIC_ARG(Type, name) \ - extern THREAD_LOCAL Type name##_private; \ - inline Type name() { return name##_private; } \ - class name##_changer { \ - public: \ - inline name##_changer(Type const& newValue) \ - : oldValue(name##_private) { \ - name##_private = newValue; \ - } \ - inline ~name##_changer() { \ - name##_private = oldValue; \ - } \ - private: \ - Type oldValue; \ - } +#if HAVE_TLS -/// Implementation of a dynamic argument -#define IMPLEMENT_DYNAMIC_ARG(Type, name, initial) \ - THREAD_LOCAL Type name##_private = initial; + /// Declare a dynamic argument. + /** The value of the argument can be got with: name() + * To change the value use WITH_DYNAMIC_ARG(name, newValue) + * To be used in a header file. Use IMPLEMENT_DYN_ARG in a source file + */ + #define DECLARE_DYNAMIC_ARG(Type, name) \ + extern THREAD_LOCAL Type name##_private; \ + inline Type name() { return name##_private; } \ + class name##_changer { \ + public: \ + inline name##_changer(Type const& newValue) \ + : oldValue(name##_private) { \ + name##_private = newValue; \ + } \ + inline ~name##_changer() { \ + name##_private = oldValue; \ + } \ + private: \ + Type oldValue; \ + } + + /// Implementation of a dynamic argument + #define IMPLEMENT_DYNAMIC_ARG(Type, name, initial) \ + THREAD_LOCAL Type name##_private = initial; -/// Locally change the value of a dynamic argument -/** Usage: - * @code - * // here name() == old value - * { - * WITH_DYNAMIC_ARG(name, newValue); - * // here name() == newValue - * } - * // here name() == old value - * @endcode - */ -#define WITH_DYNAMIC_ARG(name, value) \ - name##_changer name##_dummmy(value) + /// Locally change the value of a dynamic argument + /** Usage: + * @code + * // here name() == old value + * { + * WITH_DYNAMIC_ARG(name, newValue); + * // here name() == newValue + * } + * // here name() == old value + * @endcode + */ + #define WITH_DYNAMIC_ARG(name, value) \ + name##_changer name##_dummmy(value) + +#else + + template struct ThreadLocalObject { + map objects; + T def; + wxCriticalSection container_access; + + inline T operator () () { + wxCriticalSectionLocker lock(container_access); + T*& p = objects[wxThread::GetCurrentId()]; + if (!p) { + p = new T(def); + } + return *objects[wxThread::GetCurrentId()]; + } + + inline void store (T value) { + wxCriticalSectionLocker lock(container_access); + T*& p = objects[wxThread::GetCurrentId()]; + if (!p) { + p = new T(def); + } + *objects[wxThread::GetCurrentId()] = value; + } + + ThreadLocalObject (T def) + : def(def) + {} + + ~ThreadLocalObject () { + for (typename map::iterator i = objects.begin(); i != objects.end(); ++i) { + delete *i; + } + } + }; + + #define DECLARE_DYNAMIC_ARG(Type, name) \ + extern ThreadLocalObject name; + + #define IMPLEMENT_DYNAMIC_ARG(Type, name, initial) \ + ThreadLocalObject name (initial); + + #define WITH_DYNAMIC_ARG(name, value) \ + name.store(value); + +#endif // ----------------------------------------------------------------------------- : EOF #endif