]> git.saurik.com Git - wxWidgets.git/blob - tests/benchmarks/tls.cpp
adding a app-defined event seems to quit inner eventloops like eg the popup of the...
[wxWidgets.git] / tests / benchmarks / tls.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: tests/benchmarks/strings.cpp
3 // Purpose: String-related benchmarks
4 // Author: Vadim Zeitlin
5 // Created: 2008-07-19
6 // RCS-ID: $Id$
7 // Copyright: (c) 2008 Vadim Zeitlin <vadim@wxwidgets.org>
8 // Licence: wxWindows licence
9 /////////////////////////////////////////////////////////////////////////////
10
11 #include "bench.h"
12
13 #include "wx/tls.h"
14
15 #if defined(__UNIX__)
16 #define HAVE_PTHREAD
17 #include <pthread.h>
18 #elif defined(__WIN32__)
19 #define HAVE_WIN32_THREAD
20 #include "wx/msw/wrapwin.h"
21 #endif
22
23 #if wxCHECK_GCC_VERSION(3, 3)
24 #define HAVE_COMPILER_THREAD
25 #define wxTHREAD_SPECIFIC __thread
26 #elif wxCHECK_VISUALC_VERSION(7)
27 #define HAVE_COMPILER_THREAD
28 #define wxTHREAD_SPECIFIC __declspec(thread)
29 #endif
30
31 // uncomment this to also test Boost version (you will also need to link with
32 // libboost_threads)
33 //#define HAVE_BOOST_THREAD
34 #ifdef HAVE_BOOST_THREAD
35 #include <boost/thread/tss.hpp>
36 #endif
37
38
39 static const int NUM_ITER = 1000;
40
41 // this is just a baseline
42 BENCHMARK_FUNC(DummyTLS)
43 {
44 static int s_global = 0;
45
46 for ( int n = 0; n < NUM_ITER; n++ )
47 {
48 if ( n % 2 )
49 s_global = 0;
50 else
51 s_global = n;
52 }
53
54 return !s_global;
55 }
56
57 #ifdef HAVE_COMPILER_THREAD
58
59 BENCHMARK_FUNC(CompilerTLS)
60 {
61 static wxTHREAD_SPECIFIC int s_global = 0;
62
63 for ( int n = 0; n < NUM_ITER; n++ )
64 {
65 if ( n % 2 )
66 s_global = 0;
67 else
68 s_global = n;
69 }
70
71 return !s_global;
72 }
73
74 #endif // HAVE_COMPILER_THREAD
75
76 #ifdef HAVE_PTHREAD
77
78 class PthreadKey
79 {
80 public:
81 PthreadKey()
82 {
83 pthread_key_create(&m_key, NULL);
84 }
85
86 ~PthreadKey()
87 {
88 pthread_key_delete(m_key);
89 }
90
91 operator pthread_key_t() const { return m_key; }
92
93 private:
94 pthread_key_t m_key;
95
96 DECLARE_NO_COPY_CLASS(PthreadKey)
97 };
98
99 BENCHMARK_FUNC(PosixTLS)
100 {
101 static PthreadKey s_key;
102
103 for ( int n = 0; n < NUM_ITER; n++ )
104 {
105 if ( n % 2 )
106 pthread_setspecific(s_key, 0);
107 else
108 pthread_setspecific(s_key, &n);
109 }
110
111 return !pthread_getspecific(s_key);
112 }
113
114 #endif // HAVE_PTHREAD
115
116 #ifdef HAVE_WIN32_THREAD
117
118 class TlsSlot
119 {
120 public:
121 TlsSlot()
122 {
123 m_slot = ::TlsAlloc();
124 }
125
126 ~TlsSlot()
127 {
128 ::TlsFree(m_slot);
129 }
130
131 operator DWORD() const { return m_slot; }
132
133 private:
134 DWORD m_slot;
135
136 DECLARE_NO_COPY_CLASS(TlsSlot)
137 };
138
139 BENCHMARK_FUNC(Win32TLS)
140 {
141 static TlsSlot s_slot;
142
143 for ( int n = 0; n < NUM_ITER; n++ )
144 {
145 if ( n % 2 )
146 ::TlsSetValue(s_slot, 0);
147 else
148 ::TlsSetValue(s_slot, &n);
149 }
150
151 return !::TlsGetValue(s_slot);
152 }
153
154 #endif // HAVE_WIN32_THREAD
155
156 #ifdef HAVE_BOOST_THREAD
157
158 BENCHMARK_FUNC(BoostTLS)
159 {
160 static boost::thread_specific_ptr<int> s_ptr;
161 if ( !s_ptr.get() )
162 s_ptr.reset(new int(0));
163
164 for ( int n = 0; n < NUM_ITER; n++ )
165 {
166 if ( n % 2 )
167 *s_ptr = 0;
168 else
169 *s_ptr = n;
170 }
171
172 return !*s_ptr;
173 }
174
175 #endif // HAVE_BOOST_THREAD
176
177 BENCHMARK_FUNC(wxTLS)
178 {
179 static wxTLS_TYPE(int) s_globalVar;
180 #define s_global wxTLS_VALUE(s_globalVar)
181
182 for ( int n = 0; n < NUM_ITER; n++ )
183 {
184 if ( n % 2 )
185 s_global = 0;
186 else
187 s_global = n;
188 }
189
190 return !s_global;
191 }