5 #include "flutter/testing/testing.h"
36 TEST(ThreadTest, CanCreateMutex) {
45 TEST(ThreadTest, CanCreateMutexLock) {
53 TEST(ThreadTest, CanCreateRWMutex) {
62 [[maybe_unused]]
int b = f.a;
66 TEST(ThreadTest, CanCreateRWMutexLock) {
78 [[maybe_unused]]
int b = f.a;
84 TEST(StringsTest, CanSPrintF) {
85 ASSERT_EQ(
SPrintF(
"%sx%d",
"Hello", 12),
"Hellox12");
87 ASSERT_EQ(
SPrintF(
"Hello"),
"Hello");
88 ASSERT_EQ(
SPrintF(
"%sx%.2f",
"Hello", 12.122222),
"Hellox12.12");
97 TEST(ConditionVariableTest, WaitUntil) {
100 for (
size_t i = 0; i < 2; ++i) {
104 std::chrono::high_resolution_clock::now() +
105 std::chrono::milliseconds{10},
107 test.rando_ivar = 12;
112 ASSERT_FALSE(result);
117 ASSERT_EQ(test.rando_ivar, 12u);
120 TEST(ConditionVariableTest, WaitFor) {
123 for (
size_t i = 0; i < 2; ++i) {
126 test.
mutex, std::chrono::milliseconds{10},
128 test.rando_ivar = 12;
133 ASSERT_FALSE(result);
138 ASSERT_EQ(test.rando_ivar, 12u);
141 TEST(ConditionVariableTest, WaitForever) {
144 for (
size_t i = 0; i < 2; ++i) {
147 test.rando_ivar = 12;
155 ASSERT_EQ(test.rando_ivar, 12u);
158 TEST(ConditionVariableTest, TestsCriticalSectionAfterWaitForUntil) {
159 std::vector<std::thread> threads;
160 const auto kThreadCount = 10u;
166 std::condition_variable start_cv;
167 std::mutex start_mtx;
169 auto start_predicate = [&
start]() {
return start; };
170 auto thread_main = [&]() {
172 std::unique_lock start_lock(start_mtx);
173 start_cv.wait(start_lock, start_predicate);
177 cv.
WaitFor(mtx, std::chrono::milliseconds{0u}, []() {
return true; });
179 std::this_thread::sleep_for(std::chrono::milliseconds{100u});
184 for (
size_t i = 0; i < kThreadCount; i++) {
185 threads.emplace_back(thread_main);
190 std::scoped_lock start_lock(start_mtx);
193 start_cv.notify_all();
196 ASSERT_EQ(threads.size(), kThreadCount);
197 for (
size_t i = 0; i < kThreadCount; i++) {
200 ASSERT_EQ(sum, kThreadCount);
203 TEST(ConditionVariableTest, TestsCriticalSectionAfterWait) {
204 std::vector<std::thread> threads;
205 const auto kThreadCount = 10u;
211 std::condition_variable start_cv;
212 std::mutex start_mtx;
214 auto start_predicate = [&
start]() {
return start; };
215 auto thread_main = [&]() {
217 std::unique_lock start_lock(start_mtx);
218 start_cv.wait(start_lock, start_predicate);
222 cv.
Wait(mtx, []() {
return true; });
224 std::this_thread::sleep_for(std::chrono::milliseconds{100u});
229 for (
size_t i = 0; i < kThreadCount; i++) {
230 threads.emplace_back(thread_main);
235 std::scoped_lock start_lock(start_mtx);
238 start_cv.notify_all();
241 ASSERT_EQ(threads.size(), kThreadCount);
242 for (
size_t i = 0; i < kThreadCount; i++) {
245 ASSERT_EQ(sum, kThreadCount);
248 TEST(BaseTest, NoExceptionPromiseValue) {
252 ASSERT_EQ(future.get(), 123);
255 TEST(BaseTest, NoExceptionPromiseEmpty) {
256 auto wrapper = std::make_shared<NoExceptionPromise<int>>();
257 std::future future = wrapper->get_future();
264 TEST(BaseTest, CanUseTypedMasks) {
267 ASSERT_EQ(
static_cast<uint32_t
>(mask), 0u);
273 ASSERT_EQ(
static_cast<uint32_t
>(mask), 1u);
280 ASSERT_EQ(
static_cast<uint32_t
>(mask), 1u);
286 MyMask mask(std::move(mask2));
287 ASSERT_EQ(
static_cast<uint32_t
>(mask), 1u);
301 ASSERT_EQ(
static_cast<uint32_t
>(m1 & m2), 0u);
302 ASSERT_FALSE(m1 & m2);
308 ASSERT_EQ(
static_cast<uint32_t
>(m1 | m2), ((1u << 0u) | (1u << 1u)));
309 ASSERT_TRUE(m1 | m2);
315 ASSERT_EQ(
static_cast<uint32_t
>(m1 ^ m2), ((1u << 0u) ^ (1u << 1u)));
316 ASSERT_TRUE(m1 ^ m2);
321 ASSERT_EQ(
static_cast<uint32_t
>(~m1), (~(1u << 0u)));
431 ASSERT_FALSE(
x == m);
444 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...
void set_value(const T &value)
std::future< T > get_future()
TEST(AllocationSizeTest, CanCreateTypedAllocations)
std::string SPrintF(const char *format,...)
IMPELLER_ENUM_IS_MASK(MyMaskBits)
uint32_t rando_ivar IPLR_GUARDED_BY(mutex)=0
int a IPLR_GUARDED_BY(mtx)
int a IPLR_GUARDED_BY(mtx)
#define IPLR_REQUIRES(...)