Commit a2745bc3 authored by coppro's avatar coppro

Added some stuff for platforms without TLS

parent 4e62cf02
...@@ -16,53 +16,107 @@ ...@@ -16,53 +16,107 @@
// ----------------------------------------------------------------------------- : Includes // ----------------------------------------------------------------------------- : Includes
#include <util/prec.hpp> #include <util/prec.hpp>
#include <wx/thread.h>
// ----------------------------------------------------------------------------- : Dynamic argument // ----------------------------------------------------------------------------- : Dynamic argument
#ifdef _MSC_VER #ifdef _MSC_VER
# define THREAD_LOCAL __declspec(thread) # define THREAD_LOCAL __declspec(thread)
#else # define HAVE_TLS 1
#elseif defined __linux__
# define THREAD_LOCAL __thread # define THREAD_LOCAL __thread
# define HAVE_TLS 1
#else
# define HAVE_TLS 0
#endif #endif
/// Declare a dynamic argument. #if HAVE_TLS
/** The value of the argument can be got with: name()
* To change the value use WITH_DYNAMIC_ARG(name, newValue) /// Declare a dynamic argument.
* To be used in a header file. Use IMPLEMENT_DYN_ARG in a source file /** The value of the argument can be got with: name()
*/ * To change the value use WITH_DYNAMIC_ARG(name, newValue)
#define DECLARE_DYNAMIC_ARG(Type, name) \ * To be used in a header file. Use IMPLEMENT_DYN_ARG in a source file
extern THREAD_LOCAL Type name##_private; \ */
inline Type name() { return name##_private; } \ #define DECLARE_DYNAMIC_ARG(Type, name) \
class name##_changer { \ extern THREAD_LOCAL Type name##_private; \
public: \ inline Type name() { return name##_private; } \
inline name##_changer(Type const& newValue) \ class name##_changer { \
: oldValue(name##_private) { \ public: \
name##_private = newValue; \ inline name##_changer(Type const& newValue) \
} \ : oldValue(name##_private) { \
inline ~name##_changer() { \ name##_private = newValue; \
name##_private = oldValue; \ } \
} \ inline ~name##_changer() { \
private: \ name##_private = oldValue; \
Type oldValue; \ } \
} private: \
Type oldValue; \
/// Implementation of a dynamic argument }
#define IMPLEMENT_DYNAMIC_ARG(Type, name, initial) \
THREAD_LOCAL Type name##_private = initial; /// Implementation of a dynamic argument
#define IMPLEMENT_DYNAMIC_ARG(Type, name, initial) \
/// Locally change the value of a dynamic argument THREAD_LOCAL Type name##_private = initial;
/** Usage:
* @code /// Locally change the value of a dynamic argument
* // here name() == old value /** Usage:
* { * @code
* WITH_DYNAMIC_ARG(name, newValue); * // here name() == old value
* // here name() == newValue * {
* } * WITH_DYNAMIC_ARG(name, newValue);
* // here name() == old value * // here name() == newValue
* @endcode * }
*/ * // here name() == old value
#define WITH_DYNAMIC_ARG(name, value) \ * @endcode
name##_changer name##_dummmy(value) */
#define WITH_DYNAMIC_ARG(name, value) \
name##_changer name##_dummmy(value)
#else
template <typename T> struct ThreadLocalObject {
map<int,T*> 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<int,T*>::iterator i = objects.begin(); i != objects.end(); ++i) {
delete *i;
}
}
};
#define DECLARE_DYNAMIC_ARG(Type, name) \
extern ThreadLocalObject<Type> name;
#define IMPLEMENT_DYNAMIC_ARG(Type, name, initial) \
ThreadLocalObject<Type> name (initial);
#define WITH_DYNAMIC_ARG(name, value) \
name.store(value);
#endif
// ----------------------------------------------------------------------------- : EOF // ----------------------------------------------------------------------------- : EOF
#endif #endif
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment