36TEST(ThreadTest, CanCreateMutex) {
45TEST(ThreadTest, CanCreateMutexLock) {
53TEST(ThreadTest, CanCreateRWMutex) {
62 [[maybe_unused]]
int b = f.a;
66TEST(ThreadTest, CanCreateRWMutexLock) {
78 [[maybe_unused]]
int b = f.a;
90TEST(ConditionVariableTest, WaitUntil) {
93 for (
size_t i = 0;
i < 2; ++
i) {
97 std::chrono::high_resolution_clock::now() +
98 std::chrono::milliseconds{10},
100 test.rando_ivar = 12;
105 ASSERT_FALSE(result);
110 ASSERT_EQ(test.rando_ivar, 12u);
113TEST(ConditionVariableTest, WaitFor) {
116 for (
size_t i = 0;
i < 2; ++
i) {
119 test.
mutex, std::chrono::milliseconds{10},
121 test.rando_ivar = 12;
126 ASSERT_FALSE(result);
131 ASSERT_EQ(test.rando_ivar, 12u);
134TEST(ConditionVariableTest, WaitForever) {
137 for (
size_t i = 0;
i < 2; ++
i) {
140 test.rando_ivar = 12;
148 ASSERT_EQ(test.rando_ivar, 12u);
151TEST(ConditionVariableTest, TestsCriticalSectionAfterWaitForUntil) {
152 std::vector<std::thread> threads;
159 std::condition_variable start_cv;
160 std::mutex start_mtx;
162 auto start_predicate = [&
start]() {
return start; };
163 auto thread_main = [&]() {
165 std::unique_lock start_lock(start_mtx);
166 start_cv.wait(start_lock, start_predicate);
170 cv.
WaitFor(mtx, std::chrono::milliseconds{0u}, []() {
return true; });
172 std::this_thread::sleep_for(std::chrono::milliseconds{100u});
179 threads.emplace_back(thread_main);
184 std::scoped_lock start_lock(start_mtx);
187 start_cv.notify_all();
197TEST(ConditionVariableTest, TestsCriticalSectionAfterWait) {
198 std::vector<std::thread> threads;
205 std::condition_variable start_cv;
206 std::mutex start_mtx;
208 auto start_predicate = [&
start]() {
return start; };
209 auto thread_main = [&]() {
211 std::unique_lock start_lock(start_mtx);
212 start_cv.wait(start_lock, start_predicate);
216 cv.
Wait(mtx, []() {
return true; });
218 std::this_thread::sleep_for(std::chrono::milliseconds{100u});
225 threads.emplace_back(thread_main);
230 std::scoped_lock start_lock(start_mtx);
233 start_cv.notify_all();
243TEST(BaseTest, NoExceptionPromiseValue) {
247 ASSERT_EQ(future.get(), 123);
250TEST(BaseTest, NoExceptionPromiseEmpty) {
251 auto wrapper = std::make_shared<NoExceptionPromise<int>>();
252 std::future future = wrapper->get_future();
259TEST(BaseTest, CanUseTypedMasks) {
262 ASSERT_EQ(
static_cast<uint32_t
>(mask), 0u);
268 ASSERT_EQ(
static_cast<uint32_t
>(mask), 1u);
275 ASSERT_EQ(
static_cast<uint32_t
>(mask), 1u);
281 MyMask mask(std::move(mask2));
282 ASSERT_EQ(
static_cast<uint32_t
>(mask), 1u);
296 ASSERT_EQ(
static_cast<uint32_t
>(m1 & m2), 0u);
297 ASSERT_FALSE(m1 & m2);
303 ASSERT_EQ(
static_cast<uint32_t
>(m1 | m2), ((1u << 0u) | (1u << 1u)));
304 ASSERT_TRUE(m1 | m2);
310 ASSERT_EQ(
static_cast<uint32_t
>(m1 ^ m2), ((1u << 0u) ^ (1u << 1u)));
311 ASSERT_TRUE(m1 ^ m2);
316 ASSERT_EQ(
static_cast<uint32_t
>(~m1), (~(1u << 0u)));
426 ASSERT_FALSE(
x == m);
439 ASSERT_FALSE(
x >= m);
A condition variable exactly similar to the one in libcxx with two major differences:
bool WaitFor(Mutex &mutex, const std::chrono::duration< Representation, Period > &duration, const Predicate &should_stop_waiting) IPLR_REQUIRES(mutex)
Atomically unlocks the mutex and waits on the condition variable for a designated duration....
bool WaitUntil(Mutex &mutex, const std::chrono::time_point< Clock, Duration > &time_point, const Predicate &should_stop_waiting) IPLR_REQUIRES(mutex)
Atomically unlocks the mutex and waits on the condition variable up to a specified time point....
void Wait(Mutex &mutex, const Predicate &should_stop_waiting) IPLR_REQUIRES(mutex)
Atomically unlocks the mutex and waits on the condition variable indefinitely till the predicate dete...
std::future< T > get_future()
void set_value(const T &value)
static constexpr uint64_t kThreadCount
#define IMPELLER_ENUM_IS_MASK(enum_name)
Declare this in the "impeller" namespace to make the enum maskable.
TEST(FrameTimingsRecorderTest, RecordVsync)
Mask< MyMaskBits > MyMask
uint32_t rando_ivar IPLR_GUARDED_BY(mutex)=0
int a IPLR_GUARDED_BY(mtx)
int a IPLR_GUARDED_BY(mtx)
#define IPLR_REQUIRES(...)