Flutter Engine
The Flutter Engine
SkSharedMutex.h
Go to the documentation of this file.
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 SkSharedLock_DEFINED
9#define SkSharedLock_DEFINED
10
14
15#ifdef SK_DEBUG
17 #include <memory>
18#endif // SK_DEBUG
19
20// There are two shared lock implementations one debug the other is high performance. They implement
21// an interface similar to pthread's rwlocks.
22// This is a shared lock implementation similar to pthreads rwlocks. The high performance
23// implementation is cribbed from Preshing's article:
24// http://preshing.com/20150316/semaphores-are-surprisingly-versatile/
25//
26// This lock does not obey strict queue ordering. It will always alternate between readers and
27// a single writer.
28class SK_CAPABILITY("mutex") SkSharedMutex {
29public:
30 SkSharedMutex();
31 ~SkSharedMutex();
32 // Acquire lock for exclusive use.
33 void acquire() SK_ACQUIRE();
34
35 // Release lock for exclusive use.
36 void release() SK_RELEASE_CAPABILITY();
37
38 // Fail if exclusive is not held.
39 void assertHeld() const SK_ASSERT_CAPABILITY(this);
40
41 // Acquire lock for shared use.
42 void acquireShared() SK_ACQUIRE_SHARED();
43
44 // Release lock for shared use.
45 void releaseShared() SK_RELEASE_SHARED_CAPABILITY();
46
47 // Fail if shared lock not held.
48 void assertHeldShared() const SK_ASSERT_SHARED_CAPABILITY(this);
49
50private:
51#ifdef SK_DEBUG
52 class ThreadIDSet;
53 std::unique_ptr<ThreadIDSet> fCurrentShared;
54 std::unique_ptr<ThreadIDSet> fWaitingExclusive;
55 std::unique_ptr<ThreadIDSet> fWaitingShared;
56 int fSharedQueueSelect{0};
57 mutable SkMutex fMu;
58 SkSemaphore fSharedQueue[2];
59 SkSemaphore fExclusiveQueue;
60#else
61 std::atomic<int32_t> fQueueCounts;
62 SkSemaphore fSharedQueue;
63 SkSemaphore fExclusiveQueue;
64#endif // SK_DEBUG
65};
66
67#ifndef SK_DEBUG
68inline void SkSharedMutex::assertHeld() const {}
69inline void SkSharedMutex::assertHeldShared() const {}
70#endif // SK_DEBUG
71
73public:
74 explicit SkAutoSharedMutexExclusive(SkSharedMutex& lock) SK_ACQUIRE(lock)
75 : fLock(lock) {
76 lock.acquire();
77 }
79
80private:
81 SkSharedMutex& fLock;
82};
83
85public:
86 explicit SkAutoSharedMutexShared(SkSharedMutex& lock) SK_ACQUIRE_SHARED(lock)
87 : fLock(lock) {
88 lock.acquireShared();
89 }
90
91 // You would think this should be SK_RELEASE_SHARED_CAPABILITY, but SK_SCOPED_CAPABILITY
92 // doesn't fully understand the difference between shared and exclusive.
93 // Please review https://reviews.llvm.org/D52578 for more information.
94 ~SkAutoSharedMutexShared() SK_RELEASE_CAPABILITY() { fLock.releaseShared(); }
95
96private:
97 SkSharedMutex& fLock;
98};
99
100#endif // SkSharedLock_DEFINED
class SK_CAPABILITY("mutex") SkSharedMutex
Definition: SkSharedMutex.h:28
#define SK_SCOPED_CAPABILITY
#define SK_RELEASE_CAPABILITY(...)
#define SK_ASSERT_SHARED_CAPABILITY(x)
#define SK_RELEASE_SHARED_CAPABILITY(...)
#define SK_ACQUIRE(...)
#define SK_ACQUIRE_SHARED(...)
#define SK_ASSERT_CAPABILITY(x)
~SkAutoSharedMutexExclusive() SK_RELEASE_CAPABILITY()
Definition: SkSharedMutex.h:78
SkAutoSharedMutexExclusive(SkSharedMutex &lock) SK_ACQUIRE(lock)
Definition: SkSharedMutex.h:74
SkAutoSharedMutexShared(SkSharedMutex &lock) SK_ACQUIRE_SHARED(lock)
Definition: SkSharedMutex.h:86
~SkAutoSharedMutexShared() SK_RELEASE_CAPABILITY()
Definition: SkSharedMutex.h:94