+/////////////////////////////////////////////////////////////////////////////
+// Name:        tests/benchmarks/strings.cpp
+// Purpose:     String-related benchmarks
+// Author:      Vadim Zeitlin
+// Created:     2008-07-19
+// RCS-ID:      $Id$
+// Copyright:   (c) 2008 Vadim Zeitlin <vadim@wxwidgets.org>
+// Licence:     wxWindows license
+/////////////////////////////////////////////////////////////////////////////
+
+#include "bench.h"
+
+#ifdef __UNIX__
+    #define HAVE_PTHREAD
+    #include <pthread.h>
+#endif
+
+#if wxCHECK_GCC_VERSION(3, 3)
+    #define HAVE_COMPILER_THREAD
+    #define wxTHREAD_SPECIFIC __thread
+#endif
+
+// uncomment this to also test Boost version (you will also need to link with
+// libboost_threads)
+//#define HAVE_BOOST_THREAD
+#ifdef HAVE_BOOST_THREAD
+    #include <boost/thread/tss.hpp>
+#endif
+
+
+static const int NUM_ITER = 1000;
+
+// this is just a baseline
+BENCHMARK_FUNC(DummyTLS)
+{
+    static int s_global = 0;
+
+    for ( int n = 0; n < NUM_ITER; n++ )
+    {
+        if ( n % 2 )
+            s_global = 0;
+        else
+            s_global = n;
+    }
+
+    return !s_global;
+}
+
+#ifdef HAVE_COMPILER_THREAD
+
+BENCHMARK_FUNC(CompilerTLS)
+{
+    static wxTHREAD_SPECIFIC int s_global = 0;
+
+    for ( int n = 0; n < NUM_ITER; n++ )
+    {
+        if ( n % 2 )
+            s_global = 0;
+        else
+            s_global = n;
+    }
+
+    return !s_global;
+}
+
+#endif // HAVE_COMPILER_THREAD
+
+#ifdef HAVE_PTHREAD
+
+class PthreadKey
+{
+public:
+    PthreadKey()
+    {
+        pthread_key_create(&m_key, NULL);
+    }
+
+    ~PthreadKey()
+    {
+        pthread_key_delete(m_key);
+    }
+
+    operator pthread_key_t() const { return m_key; }
+
+private:
+    pthread_key_t m_key;
+
+    DECLARE_NO_COPY_CLASS(PthreadKey)
+};
+
+BENCHMARK_FUNC(PosixTLS)
+{
+    static PthreadKey s_key;
+
+    for ( int n = 0; n < NUM_ITER; n++ )
+    {
+        if ( n % 2 )
+            pthread_setspecific(s_key, 0);
+        else
+            pthread_setspecific(s_key, &n);
+    }
+
+    return !pthread_getspecific(s_key);
+}
+
+#endif // HAVE_PTHREAD
+
+#ifdef HAVE_BOOST_THREAD
+
+BENCHMARK_FUNC(BoostTLS)
+{
+    static boost::thread_specific_ptr<int> s_ptr;
+    if ( !s_ptr.get() )
+        s_ptr.reset(new int(0));
+
+    for ( int n = 0; n < NUM_ITER; n++ )
+    {
+        if ( n % 2 )
+            *s_ptr = 0;
+        else
+            *s_ptr = n;
+    }
+
+    return !*s_ptr;
+}
+
+#endif // HAVE_BOOST_THREAD