-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathTS_latch.cpp
92 lines (77 loc) · 1.87 KB
/
TS_latch.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
/**
* @Filename: TS_latch.cpp
* @Author: Ben Sokol <Ben>
* @Email: [email protected]
* @Created: February 19th, 2019 [12:28pm]
* @Modified: November 1st, 2019 [7:13pm]
* @Version: 1.0.0
*
* Copyright (C) 2019 by Ben Sokol. All Rights Reserved.
*/
#include <condition_variable>
#include <shared_mutex>
#include "TS_latch.hpp"
namespace TS {
Latch::Latch(size_t aCount) : mThreshold(aCount), mCount(aCount) {
if (aCount == 0) {
throw std::invalid_argument("aCount must be greater than zero.");
}
}
Latch::~Latch() {
mCond.notify_all();
}
void Latch::clear_and_reset(size_t newThreshold) {
std::shared_lock<TS_LATCH_mutex_type> lck(mMtx);
if (newThreshold == 0) {
throw std::invalid_argument("newThreshold must be greater than zero.");
}
mCond.notify_all();
mThreshold = newThreshold;
mCount = newThreshold;
}
void Latch::reset(size_t newThreshold) {
std::shared_lock<TS_LATCH_mutex_type> lck(mMtx);
if (newThreshold == 0) {
throw std::invalid_argument("newThreshold must be greater than zero.");
}
mThreshold = newThreshold;
mCount = newThreshold;
}
void Latch::count_down_and_wait(size_t n) {
std::shared_lock<TS_LATCH_mutex_type> lck(mMtx);
if (n > mCount) {
mCount = 0;
}
else {
mCount = mCount - n;
}
if (mCount == 0) {
mCond.notify_all();
}
else {
mCond.wait(lck);
}
}
void Latch::count_down(size_t n) {
std::shared_lock<TS_LATCH_mutex_type> lck(mMtx);
if (n > mCount) {
mCount = 0;
}
else {
mCount = mCount - n;
}
if (mCount == 0) {
mCond.notify_all();
}
}
size_t Latch::get_count() const noexcept {
return mCount;
}
void Latch::wait() {
std::shared_lock<TS_LATCH_mutex_type> lck(mMtx);
if (mCount == 0) {
return;
}
mCond.wait(lck);
}
} // namespace TS