tls.cpp 3.3 KB

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