/src/node/deps/v8/include/cppgc/internal/atomic-entry-flag.h
Line | Count | Source (jump to first uncovered line) |
1 | | // Copyright 2020 the V8 project authors. All rights reserved. |
2 | | // Use of this source code is governed by a BSD-style license that can be |
3 | | // found in the LICENSE file. |
4 | | |
5 | | #ifndef INCLUDE_CPPGC_INTERNAL_ATOMIC_ENTRY_FLAG_H_ |
6 | | #define INCLUDE_CPPGC_INTERNAL_ATOMIC_ENTRY_FLAG_H_ |
7 | | |
8 | | #include <atomic> |
9 | | |
10 | | namespace cppgc { |
11 | | namespace internal { |
12 | | |
13 | | // A flag which provides a fast check whether a scope may be entered on the |
14 | | // current thread, without needing to access thread-local storage or mutex. Can |
15 | | // have false positives (i.e., spuriously report that it might be entered), so |
16 | | // it is expected that this will be used in tandem with a precise check that the |
17 | | // scope is in fact entered on that thread. |
18 | | // |
19 | | // Example: |
20 | | // g_frobnicating_flag.MightBeEntered() && |
21 | | // ThreadLocalFrobnicator().IsFrobnicating() |
22 | | // |
23 | | // Relaxed atomic operations are sufficient, since: |
24 | | // - all accesses remain atomic |
25 | | // - each thread must observe its own operations in order |
26 | | // - no thread ever exits the flag more times than it enters (if used correctly) |
27 | | // And so if a thread observes zero, it must be because it has observed an equal |
28 | | // number of exits as entries. |
29 | | class AtomicEntryFlag final { |
30 | | public: |
31 | 0 | void Enter() { entries_.fetch_add(1, std::memory_order_relaxed); } |
32 | 0 | void Exit() { entries_.fetch_sub(1, std::memory_order_relaxed); } |
33 | | |
34 | | // Returns false only if the current thread is not between a call to Enter |
35 | | // and a call to Exit. Returns true if this thread or another thread may |
36 | | // currently be in the scope guarded by this flag. |
37 | 0 | bool MightBeEntered() const { |
38 | 0 | return entries_.load(std::memory_order_relaxed) != 0; |
39 | 0 | } |
40 | | |
41 | | private: |
42 | | std::atomic_int entries_{0}; |
43 | | }; |
44 | | |
45 | | } // namespace internal |
46 | | } // namespace cppgc |
47 | | |
48 | | #endif // INCLUDE_CPPGC_INTERNAL_ATOMIC_ENTRY_FLAG_H_ |