GCC Code Coverage Report


Directory: cvmfs/
File: cvmfs/fence.h
Date: 2025-06-22 02:36:02
Exec Total Coverage
Lines: 17 19 89.5%
Branches: 2 4 50.0%

Line Branch Exec Source
1 /**
2 * This file is part of the CernVM File System.
3 */
4
5 #ifndef CVMFS_FENCE_H_
6 #define CVMFS_FENCE_H_
7
8 #include "gtest/gtest_prod.h"
9 #include "util/atomic.h"
10 #include "util/posix.h"
11 #include "util/single_copy.h"
12
13 #ifdef CVMFS_NAMESPACE_GUARD
14 namespace CVMFS_NAMESPACE_GUARD {
15 #endif
16
17 /**
18 * A Fence can be used to protect critical regions where blocking is a very
19 * rare operation. When the Fence is not blocked, entering and leaving a
20 * critical region requires only a 1-2 atomic operations. In order to block
21 * the fence, no new threads can enter a critical region. When all entered
22 * regions are left, the fence is blocked. Waiting is done through slow busy
23 * wait.
24 */
25 class Fence : public SingleCopy {
26 FRIEND_TEST(T_Fence, Basics);
27
28 public:
29 14 Fence() {
30 14 atomic_init64(&counter_);
31 14 atomic_init32(&blocking_);
32 14 }
33
34 28 void Enter() {
35
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 28 times.
28 while (atomic_read32(&blocking_)) {
36 SafeSleepMs(kBusyWaitBackoffMs);
37 }
38 28 atomic_inc64(&counter_);
39 28 }
40
41 28 void Leave() { atomic_dec64(&counter_); }
42
43 28 void Close() { atomic_cas32(&blocking_, 0, 1); }
44
45 /**
46 * Close and let live critical regions exit
47 */
48 14 void Drain() {
49 14 Close();
50
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 14 times.
14 while (atomic_read64(&counter_) > 0) {
51 SafeSleepMs(kBusyWaitBackoffMs);
52 }
53 14 }
54
55 28 void Open() { atomic_cas32(&blocking_, 1, 0); }
56
57 private:
58 static const unsigned kBusyWaitBackoffMs = 100;
59
60 /**
61 * Number of active critical regions.
62 */
63 atomic_int64 counter_;
64
65 /**
66 * A boolean that indicates if the fence is blocked.
67 */
68 atomic_int32 blocking_;
69 };
70
71
72 /**
73 * RAII wrapper in case an entire function or code block should be protected
74 * by a fence.
75 */
76 class FenceGuard {
77 public:
78 14 explicit FenceGuard(Fence *fence) : fence_(fence) { fence_->Enter(); }
79 14 ~FenceGuard() { fence_->Leave(); }
80
81 private:
82 Fence *fence_;
83 };
84
85 #ifdef CVMFS_NAMESPACE_GUARD
86 } // namespace CVMFS_NAMESPACE_GUARD
87 #endif
88
89 #endif // CVMFS_FENCE_H_
90