RWMutex.hpp 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. //===----------------------------------------------------------------------===//
  2. //
  3. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  4. // See https://llvm.org/LICENSE.txt for license information.
  5. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  6. //
  7. //
  8. // Abstract interface to shared reader/writer log, hiding platform and
  9. // configuration differences.
  10. //
  11. //===----------------------------------------------------------------------===//
  12. #ifndef __RWMUTEX_HPP__
  13. #define __RWMUTEX_HPP__
  14. #if defined(_WIN32)
  15. #include <windows.h>
  16. #elif !defined(_LIBUNWIND_HAS_NO_THREADS)
  17. #include <pthread.h>
  18. #if defined(__ELF__) && defined(_LIBUNWIND_LINK_PTHREAD_LIB)
  19. #pragma comment(lib, "pthread")
  20. #endif
  21. #endif
  22. namespace libunwind {
  23. #if defined(_LIBUNWIND_HAS_NO_THREADS)
  24. class _LIBUNWIND_HIDDEN RWMutex {
  25. public:
  26. bool lock_shared() { return true; }
  27. bool unlock_shared() { return true; }
  28. bool lock() { return true; }
  29. bool unlock() { return true; }
  30. };
  31. #elif defined(_WIN32)
  32. class _LIBUNWIND_HIDDEN RWMutex {
  33. public:
  34. bool lock_shared() {
  35. AcquireSRWLockShared(&_lock);
  36. return true;
  37. }
  38. bool unlock_shared() {
  39. ReleaseSRWLockShared(&_lock);
  40. return true;
  41. }
  42. bool lock() {
  43. AcquireSRWLockExclusive(&_lock);
  44. return true;
  45. }
  46. bool unlock() {
  47. ReleaseSRWLockExclusive(&_lock);
  48. return true;
  49. }
  50. private:
  51. SRWLOCK _lock = SRWLOCK_INIT;
  52. };
  53. #elif !defined(LIBUNWIND_USE_WEAK_PTHREAD)
  54. class _LIBUNWIND_HIDDEN RWMutex {
  55. public:
  56. bool lock_shared() { return pthread_rwlock_rdlock(&_lock) == 0; }
  57. bool unlock_shared() { return pthread_rwlock_unlock(&_lock) == 0; }
  58. bool lock() { return pthread_rwlock_wrlock(&_lock) == 0; }
  59. bool unlock() { return pthread_rwlock_unlock(&_lock) == 0; }
  60. private:
  61. pthread_rwlock_t _lock = PTHREAD_RWLOCK_INITIALIZER;
  62. };
  63. #else
  64. extern "C" int __attribute__((weak))
  65. pthread_create(pthread_t *thread, const pthread_attr_t *attr,
  66. void *(*start_routine)(void *), void *arg);
  67. extern "C" int __attribute__((weak))
  68. pthread_rwlock_rdlock(pthread_rwlock_t *lock);
  69. extern "C" int __attribute__((weak))
  70. pthread_rwlock_wrlock(pthread_rwlock_t *lock);
  71. extern "C" int __attribute__((weak))
  72. pthread_rwlock_unlock(pthread_rwlock_t *lock);
  73. // Calls to the locking functions are gated on pthread_create, and not the
  74. // functions themselves, because the data structure should only be locked if
  75. // another thread has been created. This is what similar libraries do.
  76. class _LIBUNWIND_HIDDEN RWMutex {
  77. public:
  78. bool lock_shared() {
  79. return !pthread_create || (pthread_rwlock_rdlock(&_lock) == 0);
  80. }
  81. bool unlock_shared() {
  82. return !pthread_create || (pthread_rwlock_unlock(&_lock) == 0);
  83. }
  84. bool lock() {
  85. return !pthread_create || (pthread_rwlock_wrlock(&_lock) == 0);
  86. }
  87. bool unlock() {
  88. return !pthread_create || (pthread_rwlock_unlock(&_lock) == 0);
  89. }
  90. private:
  91. pthread_rwlock_t _lock = PTHREAD_RWLOCK_INITIALIZER;
  92. };
  93. #endif
  94. } // namespace libunwind
  95. #endif // __RWMUTEX_HPP__