mutex.cpp 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. // ======================================================================== //
  2. // Copyright 2009-2017 Intel Corporation //
  3. // //
  4. // Licensed under the Apache License, Version 2.0 (the "License"); //
  5. // you may not use this file except in compliance with the License. //
  6. // You may obtain a copy of the License at //
  7. // //
  8. // http://www.apache.org/licenses/LICENSE-2.0 //
  9. // //
  10. // Unless required by applicable law or agreed to in writing, software //
  11. // distributed under the License is distributed on an "AS IS" BASIS, //
  12. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. //
  13. // See the License for the specific language governing permissions and //
  14. // limitations under the License. //
  15. // ======================================================================== //
  16. #include "mutex.h"
  17. #include "regression.h"
  18. #include "../algorithms/parallel_for.h"
  19. #if defined(__WIN32__) && !defined(PTHREADS_WIN32)
  20. #define WIN32_LEAN_AND_MEAN
  21. #include <windows.h>
  22. namespace embree
  23. {
  24. MutexSys::MutexSys( void ) { mutex = new CRITICAL_SECTION; InitializeCriticalSection((CRITICAL_SECTION*)mutex); }
  25. MutexSys::~MutexSys( void ) { DeleteCriticalSection((CRITICAL_SECTION*)mutex); delete (CRITICAL_SECTION*)mutex; }
  26. void MutexSys::lock( void ) { EnterCriticalSection((CRITICAL_SECTION*)mutex); }
  27. bool MutexSys::try_lock( void ) { return TryEnterCriticalSection((CRITICAL_SECTION*)mutex) != 0; }
  28. void MutexSys::unlock( void ) { LeaveCriticalSection((CRITICAL_SECTION*)mutex); }
  29. }
  30. #endif
  31. #if defined(__UNIX__) || defined(PTHREADS_WIN32)
  32. #include <pthread.h>
  33. namespace embree
  34. {
  35. /*! system mutex using pthreads */
  36. MutexSys::MutexSys( void )
  37. {
  38. mutex = new pthread_mutex_t;
  39. if (pthread_mutex_init((pthread_mutex_t*)mutex, nullptr) != 0)
  40. THROW_RUNTIME_ERROR("pthread_mutex_init failed");
  41. }
  42. MutexSys::~MutexSys( void )
  43. {
  44. bool failed = pthread_mutex_destroy((pthread_mutex_t*)mutex) != 0;
  45. delete (pthread_mutex_t*)mutex;
  46. if (failed) THROW_RUNTIME_ERROR("pthread_mutex_destroy failed");
  47. }
  48. void MutexSys::lock( void )
  49. {
  50. if (pthread_mutex_lock((pthread_mutex_t*)mutex) != 0)
  51. THROW_RUNTIME_ERROR("pthread_mutex_lock failed");
  52. }
  53. bool MutexSys::try_lock( void ) {
  54. return pthread_mutex_trylock((pthread_mutex_t*)mutex) == 0;
  55. }
  56. void MutexSys::unlock( void )
  57. {
  58. if (pthread_mutex_unlock((pthread_mutex_t*)mutex) != 0)
  59. THROW_RUNTIME_ERROR("pthread_mutex_unlock failed");
  60. }
  61. };
  62. #endif
  63. namespace embree
  64. {
  65. template<typename Mutex>
  66. struct mutex_regression_test : public RegressionTest
  67. {
  68. Mutex mutex;
  69. static const size_t N = 100;
  70. static const size_t M = 10000;
  71. mutex_regression_test(const char* name) : RegressionTest(name) {
  72. registerRegressionTest(this);
  73. }
  74. bool run ()
  75. {
  76. size_t counter = 0;
  77. parallel_for(N, [&] (const size_t i) {
  78. for (size_t i=0; i<M; i++)
  79. {
  80. mutex.lock();
  81. counter++;
  82. mutex.unlock();
  83. }
  84. });
  85. return counter == N*M;
  86. }
  87. };
  88. mutex_regression_test<MutexSys> mutex_sys_regression("sys_mutex_regression_test");
  89. mutex_regression_test<SpinLock> mutex_atomic_regression("atomic_mutex_regression_test");
  90. }