Line data Source code
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 :
8 : #ifndef SkSpinlock_DEFINED
9 : #define SkSpinlock_DEFINED
10 :
11 : #include "SkTypes.h"
12 : #include <atomic>
13 :
14 : class SkSpinlock {
15 : public:
16 3 : constexpr SkSpinlock() = default;
17 :
18 47 : void acquire() {
19 : // To act as a mutex, we need an acquire barrier when we acquire the lock.
20 47 : if (fLocked.exchange(true, std::memory_order_acquire)) {
21 : // Lock was contended. Fall back to an out-of-line spin loop.
22 0 : this->contendedAcquire();
23 : }
24 47 : }
25 :
26 : // Acquire the lock or fail (quickly). Lets the caller decide to do something other than wait.
27 0 : bool tryAcquire() {
28 : // To act as a mutex, we need an acquire barrier when we acquire the lock.
29 0 : if (fLocked.exchange(true, std::memory_order_acquire)) {
30 : // Lock was contended. Let the caller decide what to do.
31 0 : return false;
32 : }
33 0 : return true;
34 : }
35 :
36 47 : void release() {
37 : // To act as a mutex, we need a release barrier when we release the lock.
38 47 : fLocked.store(false, std::memory_order_release);
39 47 : }
40 :
41 : private:
42 : SK_API void contendedAcquire();
43 :
44 : std::atomic<bool> fLocked{false};
45 : };
46 :
47 : #endif//SkSpinlock_DEFINED
|