SkSpinlock.h 1.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647
  1. /*
  2. * Copyright 2015 Google Inc.
  3. *
  4. * Use of this source code is governed by a BSD-style license that can be
  5. * found in the LICENSE file.
  6. */
  7. #ifndef SkSpinlock_DEFINED
  8. #define SkSpinlock_DEFINED
  9. #include "SkTypes.h"
  10. #include <atomic>
  11. class SkSpinlock {
  12. public:
  13. constexpr SkSpinlock() = default;
  14. void acquire() {
  15. // To act as a mutex, we need an acquire barrier when we acquire the lock.
  16. if (fLocked.exchange(true, std::memory_order_acquire)) {
  17. // Lock was contended. Fall back to an out-of-line spin loop.
  18. this->contendedAcquire();
  19. }
  20. }
  21. // Acquire the lock or fail (quickly). Lets the caller decide to do something other than wait.
  22. bool tryAcquire() {
  23. // To act as a mutex, we need an acquire barrier when we acquire the lock.
  24. if (fLocked.exchange(true, std::memory_order_acquire)) {
  25. // Lock was contended. Let the caller decide what to do.
  26. return false;
  27. }
  28. return true;
  29. }
  30. void release() {
  31. // To act as a mutex, we need a release barrier when we release the lock.
  32. fLocked.store(false, std::memory_order_release);
  33. }
  34. private:
  35. SK_API void contendedAcquire();
  36. std::atomic<bool> fLocked{false};
  37. };
  38. #endif//SkSpinlock_DEFINED