xref: /aosp_15_r20/external/abseil-cpp/absl/synchronization/mutex_test.cc (revision 9356374a3709195abf420251b3e825997ff56c0f)
1*9356374aSAndroid Build Coastguard Worker // Copyright 2017 The Abseil Authors.
2*9356374aSAndroid Build Coastguard Worker //
3*9356374aSAndroid Build Coastguard Worker // Licensed under the Apache License, Version 2.0 (the "License");
4*9356374aSAndroid Build Coastguard Worker // you may not use this file except in compliance with the License.
5*9356374aSAndroid Build Coastguard Worker // You may obtain a copy of the License at
6*9356374aSAndroid Build Coastguard Worker //
7*9356374aSAndroid Build Coastguard Worker //      https://www.apache.org/licenses/LICENSE-2.0
8*9356374aSAndroid Build Coastguard Worker //
9*9356374aSAndroid Build Coastguard Worker // Unless required by applicable law or agreed to in writing, software
10*9356374aSAndroid Build Coastguard Worker // distributed under the License is distributed on an "AS IS" BASIS,
11*9356374aSAndroid Build Coastguard Worker // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12*9356374aSAndroid Build Coastguard Worker // See the License for the specific language governing permissions and
13*9356374aSAndroid Build Coastguard Worker // limitations under the License.
14*9356374aSAndroid Build Coastguard Worker 
15*9356374aSAndroid Build Coastguard Worker #include "absl/synchronization/mutex.h"
16*9356374aSAndroid Build Coastguard Worker 
17*9356374aSAndroid Build Coastguard Worker #ifdef _WIN32
18*9356374aSAndroid Build Coastguard Worker #include <windows.h>
19*9356374aSAndroid Build Coastguard Worker #endif
20*9356374aSAndroid Build Coastguard Worker 
21*9356374aSAndroid Build Coastguard Worker #include <algorithm>
22*9356374aSAndroid Build Coastguard Worker #include <atomic>
23*9356374aSAndroid Build Coastguard Worker #include <cstdlib>
24*9356374aSAndroid Build Coastguard Worker #include <functional>
25*9356374aSAndroid Build Coastguard Worker #include <memory>
26*9356374aSAndroid Build Coastguard Worker #include <random>
27*9356374aSAndroid Build Coastguard Worker #include <string>
28*9356374aSAndroid Build Coastguard Worker #include <thread>  // NOLINT(build/c++11)
29*9356374aSAndroid Build Coastguard Worker #include <type_traits>
30*9356374aSAndroid Build Coastguard Worker #include <vector>
31*9356374aSAndroid Build Coastguard Worker 
32*9356374aSAndroid Build Coastguard Worker #include "gtest/gtest.h"
33*9356374aSAndroid Build Coastguard Worker #include "absl/base/attributes.h"
34*9356374aSAndroid Build Coastguard Worker #include "absl/base/config.h"
35*9356374aSAndroid Build Coastguard Worker #include "absl/base/internal/sysinfo.h"
36*9356374aSAndroid Build Coastguard Worker #include "absl/log/check.h"
37*9356374aSAndroid Build Coastguard Worker #include "absl/log/log.h"
38*9356374aSAndroid Build Coastguard Worker #include "absl/memory/memory.h"
39*9356374aSAndroid Build Coastguard Worker #include "absl/synchronization/internal/create_thread_identity.h"
40*9356374aSAndroid Build Coastguard Worker #include "absl/synchronization/internal/thread_pool.h"
41*9356374aSAndroid Build Coastguard Worker #include "absl/time/clock.h"
42*9356374aSAndroid Build Coastguard Worker #include "absl/time/time.h"
43*9356374aSAndroid Build Coastguard Worker 
44*9356374aSAndroid Build Coastguard Worker #ifdef ABSL_HAVE_PTHREAD_GETSCHEDPARAM
45*9356374aSAndroid Build Coastguard Worker #include <pthread.h>
46*9356374aSAndroid Build Coastguard Worker #include <string.h>
47*9356374aSAndroid Build Coastguard Worker #endif
48*9356374aSAndroid Build Coastguard Worker 
49*9356374aSAndroid Build Coastguard Worker namespace {
50*9356374aSAndroid Build Coastguard Worker 
51*9356374aSAndroid Build Coastguard Worker // TODO(dmauro): Replace with a commandline flag.
52*9356374aSAndroid Build Coastguard Worker static constexpr bool kExtendedTest = false;
53*9356374aSAndroid Build Coastguard Worker 
CreatePool(int threads)54*9356374aSAndroid Build Coastguard Worker std::unique_ptr<absl::synchronization_internal::ThreadPool> CreatePool(
55*9356374aSAndroid Build Coastguard Worker     int threads) {
56*9356374aSAndroid Build Coastguard Worker   return absl::make_unique<absl::synchronization_internal::ThreadPool>(threads);
57*9356374aSAndroid Build Coastguard Worker }
58*9356374aSAndroid Build Coastguard Worker 
59*9356374aSAndroid Build Coastguard Worker std::unique_ptr<absl::synchronization_internal::ThreadPool>
CreateDefaultPool()60*9356374aSAndroid Build Coastguard Worker CreateDefaultPool() {
61*9356374aSAndroid Build Coastguard Worker   return CreatePool(kExtendedTest ? 32 : 10);
62*9356374aSAndroid Build Coastguard Worker }
63*9356374aSAndroid Build Coastguard Worker 
64*9356374aSAndroid Build Coastguard Worker // Hack to schedule a function to run on a thread pool thread after a
65*9356374aSAndroid Build Coastguard Worker // duration has elapsed.
ScheduleAfter(absl::synchronization_internal::ThreadPool * tp,absl::Duration after,const std::function<void ()> & func)66*9356374aSAndroid Build Coastguard Worker static void ScheduleAfter(absl::synchronization_internal::ThreadPool *tp,
67*9356374aSAndroid Build Coastguard Worker                           absl::Duration after,
68*9356374aSAndroid Build Coastguard Worker                           const std::function<void()> &func) {
69*9356374aSAndroid Build Coastguard Worker   tp->Schedule([func, after] {
70*9356374aSAndroid Build Coastguard Worker     absl::SleepFor(after);
71*9356374aSAndroid Build Coastguard Worker     func();
72*9356374aSAndroid Build Coastguard Worker   });
73*9356374aSAndroid Build Coastguard Worker }
74*9356374aSAndroid Build Coastguard Worker 
75*9356374aSAndroid Build Coastguard Worker struct ScopedInvariantDebugging {
ScopedInvariantDebugging__anon8f30ae2e0111::ScopedInvariantDebugging76*9356374aSAndroid Build Coastguard Worker   ScopedInvariantDebugging() { absl::EnableMutexInvariantDebugging(true); }
~ScopedInvariantDebugging__anon8f30ae2e0111::ScopedInvariantDebugging77*9356374aSAndroid Build Coastguard Worker   ~ScopedInvariantDebugging() { absl::EnableMutexInvariantDebugging(false); }
78*9356374aSAndroid Build Coastguard Worker };
79*9356374aSAndroid Build Coastguard Worker 
80*9356374aSAndroid Build Coastguard Worker struct TestContext {
81*9356374aSAndroid Build Coastguard Worker   int iterations;
82*9356374aSAndroid Build Coastguard Worker   int threads;
83*9356374aSAndroid Build Coastguard Worker   int g0;  // global 0
84*9356374aSAndroid Build Coastguard Worker   int g1;  // global 1
85*9356374aSAndroid Build Coastguard Worker   absl::Mutex mu;
86*9356374aSAndroid Build Coastguard Worker   absl::CondVar cv;
87*9356374aSAndroid Build Coastguard Worker };
88*9356374aSAndroid Build Coastguard Worker 
89*9356374aSAndroid Build Coastguard Worker // To test whether the invariant check call occurs
90*9356374aSAndroid Build Coastguard Worker static std::atomic<bool> invariant_checked;
91*9356374aSAndroid Build Coastguard Worker 
GetInvariantChecked()92*9356374aSAndroid Build Coastguard Worker static bool GetInvariantChecked() {
93*9356374aSAndroid Build Coastguard Worker   return invariant_checked.load(std::memory_order_relaxed);
94*9356374aSAndroid Build Coastguard Worker }
95*9356374aSAndroid Build Coastguard Worker 
SetInvariantChecked(bool new_value)96*9356374aSAndroid Build Coastguard Worker static void SetInvariantChecked(bool new_value) {
97*9356374aSAndroid Build Coastguard Worker   invariant_checked.store(new_value, std::memory_order_relaxed);
98*9356374aSAndroid Build Coastguard Worker }
99*9356374aSAndroid Build Coastguard Worker 
CheckSumG0G1(void * v)100*9356374aSAndroid Build Coastguard Worker static void CheckSumG0G1(void *v) {
101*9356374aSAndroid Build Coastguard Worker   TestContext *cxt = static_cast<TestContext *>(v);
102*9356374aSAndroid Build Coastguard Worker   CHECK_EQ(cxt->g0, -cxt->g1) << "Error in CheckSumG0G1";
103*9356374aSAndroid Build Coastguard Worker   SetInvariantChecked(true);
104*9356374aSAndroid Build Coastguard Worker }
105*9356374aSAndroid Build Coastguard Worker 
TestMu(TestContext * cxt,int c)106*9356374aSAndroid Build Coastguard Worker static void TestMu(TestContext *cxt, int c) {
107*9356374aSAndroid Build Coastguard Worker   for (int i = 0; i != cxt->iterations; i++) {
108*9356374aSAndroid Build Coastguard Worker     absl::MutexLock l(&cxt->mu);
109*9356374aSAndroid Build Coastguard Worker     int a = cxt->g0 + 1;
110*9356374aSAndroid Build Coastguard Worker     cxt->g0 = a;
111*9356374aSAndroid Build Coastguard Worker     cxt->g1--;
112*9356374aSAndroid Build Coastguard Worker   }
113*9356374aSAndroid Build Coastguard Worker }
114*9356374aSAndroid Build Coastguard Worker 
TestTry(TestContext * cxt,int c)115*9356374aSAndroid Build Coastguard Worker static void TestTry(TestContext *cxt, int c) {
116*9356374aSAndroid Build Coastguard Worker   for (int i = 0; i != cxt->iterations; i++) {
117*9356374aSAndroid Build Coastguard Worker     do {
118*9356374aSAndroid Build Coastguard Worker       std::this_thread::yield();
119*9356374aSAndroid Build Coastguard Worker     } while (!cxt->mu.TryLock());
120*9356374aSAndroid Build Coastguard Worker     int a = cxt->g0 + 1;
121*9356374aSAndroid Build Coastguard Worker     cxt->g0 = a;
122*9356374aSAndroid Build Coastguard Worker     cxt->g1--;
123*9356374aSAndroid Build Coastguard Worker     cxt->mu.Unlock();
124*9356374aSAndroid Build Coastguard Worker   }
125*9356374aSAndroid Build Coastguard Worker }
126*9356374aSAndroid Build Coastguard Worker 
TestR20ms(TestContext * cxt,int c)127*9356374aSAndroid Build Coastguard Worker static void TestR20ms(TestContext *cxt, int c) {
128*9356374aSAndroid Build Coastguard Worker   for (int i = 0; i != cxt->iterations; i++) {
129*9356374aSAndroid Build Coastguard Worker     absl::ReaderMutexLock l(&cxt->mu);
130*9356374aSAndroid Build Coastguard Worker     absl::SleepFor(absl::Milliseconds(20));
131*9356374aSAndroid Build Coastguard Worker     cxt->mu.AssertReaderHeld();
132*9356374aSAndroid Build Coastguard Worker   }
133*9356374aSAndroid Build Coastguard Worker }
134*9356374aSAndroid Build Coastguard Worker 
TestRW(TestContext * cxt,int c)135*9356374aSAndroid Build Coastguard Worker static void TestRW(TestContext *cxt, int c) {
136*9356374aSAndroid Build Coastguard Worker   if ((c & 1) == 0) {
137*9356374aSAndroid Build Coastguard Worker     for (int i = 0; i != cxt->iterations; i++) {
138*9356374aSAndroid Build Coastguard Worker       absl::WriterMutexLock l(&cxt->mu);
139*9356374aSAndroid Build Coastguard Worker       cxt->g0++;
140*9356374aSAndroid Build Coastguard Worker       cxt->g1--;
141*9356374aSAndroid Build Coastguard Worker       cxt->mu.AssertHeld();
142*9356374aSAndroid Build Coastguard Worker       cxt->mu.AssertReaderHeld();
143*9356374aSAndroid Build Coastguard Worker     }
144*9356374aSAndroid Build Coastguard Worker   } else {
145*9356374aSAndroid Build Coastguard Worker     for (int i = 0; i != cxt->iterations; i++) {
146*9356374aSAndroid Build Coastguard Worker       absl::ReaderMutexLock l(&cxt->mu);
147*9356374aSAndroid Build Coastguard Worker       CHECK_EQ(cxt->g0, -cxt->g1) << "Error in TestRW";
148*9356374aSAndroid Build Coastguard Worker       cxt->mu.AssertReaderHeld();
149*9356374aSAndroid Build Coastguard Worker     }
150*9356374aSAndroid Build Coastguard Worker   }
151*9356374aSAndroid Build Coastguard Worker }
152*9356374aSAndroid Build Coastguard Worker 
153*9356374aSAndroid Build Coastguard Worker struct MyContext {
154*9356374aSAndroid Build Coastguard Worker   int target;
155*9356374aSAndroid Build Coastguard Worker   TestContext *cxt;
156*9356374aSAndroid Build Coastguard Worker   bool MyTurn();
157*9356374aSAndroid Build Coastguard Worker };
158*9356374aSAndroid Build Coastguard Worker 
MyTurn()159*9356374aSAndroid Build Coastguard Worker bool MyContext::MyTurn() {
160*9356374aSAndroid Build Coastguard Worker   TestContext *cxt = this->cxt;
161*9356374aSAndroid Build Coastguard Worker   return cxt->g0 == this->target || cxt->g0 == cxt->iterations;
162*9356374aSAndroid Build Coastguard Worker }
163*9356374aSAndroid Build Coastguard Worker 
TestAwait(TestContext * cxt,int c)164*9356374aSAndroid Build Coastguard Worker static void TestAwait(TestContext *cxt, int c) {
165*9356374aSAndroid Build Coastguard Worker   MyContext mc;
166*9356374aSAndroid Build Coastguard Worker   mc.target = c;
167*9356374aSAndroid Build Coastguard Worker   mc.cxt = cxt;
168*9356374aSAndroid Build Coastguard Worker   absl::MutexLock l(&cxt->mu);
169*9356374aSAndroid Build Coastguard Worker   cxt->mu.AssertHeld();
170*9356374aSAndroid Build Coastguard Worker   while (cxt->g0 < cxt->iterations) {
171*9356374aSAndroid Build Coastguard Worker     cxt->mu.Await(absl::Condition(&mc, &MyContext::MyTurn));
172*9356374aSAndroid Build Coastguard Worker     CHECK(mc.MyTurn()) << "Error in TestAwait";
173*9356374aSAndroid Build Coastguard Worker     cxt->mu.AssertHeld();
174*9356374aSAndroid Build Coastguard Worker     if (cxt->g0 < cxt->iterations) {
175*9356374aSAndroid Build Coastguard Worker       int a = cxt->g0 + 1;
176*9356374aSAndroid Build Coastguard Worker       cxt->g0 = a;
177*9356374aSAndroid Build Coastguard Worker       mc.target += cxt->threads;
178*9356374aSAndroid Build Coastguard Worker     }
179*9356374aSAndroid Build Coastguard Worker   }
180*9356374aSAndroid Build Coastguard Worker }
181*9356374aSAndroid Build Coastguard Worker 
TestSignalAll(TestContext * cxt,int c)182*9356374aSAndroid Build Coastguard Worker static void TestSignalAll(TestContext *cxt, int c) {
183*9356374aSAndroid Build Coastguard Worker   int target = c;
184*9356374aSAndroid Build Coastguard Worker   absl::MutexLock l(&cxt->mu);
185*9356374aSAndroid Build Coastguard Worker   cxt->mu.AssertHeld();
186*9356374aSAndroid Build Coastguard Worker   while (cxt->g0 < cxt->iterations) {
187*9356374aSAndroid Build Coastguard Worker     while (cxt->g0 != target && cxt->g0 != cxt->iterations) {
188*9356374aSAndroid Build Coastguard Worker       cxt->cv.Wait(&cxt->mu);
189*9356374aSAndroid Build Coastguard Worker     }
190*9356374aSAndroid Build Coastguard Worker     if (cxt->g0 < cxt->iterations) {
191*9356374aSAndroid Build Coastguard Worker       int a = cxt->g0 + 1;
192*9356374aSAndroid Build Coastguard Worker       cxt->g0 = a;
193*9356374aSAndroid Build Coastguard Worker       cxt->cv.SignalAll();
194*9356374aSAndroid Build Coastguard Worker       target += cxt->threads;
195*9356374aSAndroid Build Coastguard Worker     }
196*9356374aSAndroid Build Coastguard Worker   }
197*9356374aSAndroid Build Coastguard Worker }
198*9356374aSAndroid Build Coastguard Worker 
TestSignal(TestContext * cxt,int c)199*9356374aSAndroid Build Coastguard Worker static void TestSignal(TestContext *cxt, int c) {
200*9356374aSAndroid Build Coastguard Worker   CHECK_EQ(cxt->threads, 2) << "TestSignal should use 2 threads";
201*9356374aSAndroid Build Coastguard Worker   int target = c;
202*9356374aSAndroid Build Coastguard Worker   absl::MutexLock l(&cxt->mu);
203*9356374aSAndroid Build Coastguard Worker   cxt->mu.AssertHeld();
204*9356374aSAndroid Build Coastguard Worker   while (cxt->g0 < cxt->iterations) {
205*9356374aSAndroid Build Coastguard Worker     while (cxt->g0 != target && cxt->g0 != cxt->iterations) {
206*9356374aSAndroid Build Coastguard Worker       cxt->cv.Wait(&cxt->mu);
207*9356374aSAndroid Build Coastguard Worker     }
208*9356374aSAndroid Build Coastguard Worker     if (cxt->g0 < cxt->iterations) {
209*9356374aSAndroid Build Coastguard Worker       int a = cxt->g0 + 1;
210*9356374aSAndroid Build Coastguard Worker       cxt->g0 = a;
211*9356374aSAndroid Build Coastguard Worker       cxt->cv.Signal();
212*9356374aSAndroid Build Coastguard Worker       target += cxt->threads;
213*9356374aSAndroid Build Coastguard Worker     }
214*9356374aSAndroid Build Coastguard Worker   }
215*9356374aSAndroid Build Coastguard Worker }
216*9356374aSAndroid Build Coastguard Worker 
TestCVTimeout(TestContext * cxt,int c)217*9356374aSAndroid Build Coastguard Worker static void TestCVTimeout(TestContext *cxt, int c) {
218*9356374aSAndroid Build Coastguard Worker   int target = c;
219*9356374aSAndroid Build Coastguard Worker   absl::MutexLock l(&cxt->mu);
220*9356374aSAndroid Build Coastguard Worker   cxt->mu.AssertHeld();
221*9356374aSAndroid Build Coastguard Worker   while (cxt->g0 < cxt->iterations) {
222*9356374aSAndroid Build Coastguard Worker     while (cxt->g0 != target && cxt->g0 != cxt->iterations) {
223*9356374aSAndroid Build Coastguard Worker       cxt->cv.WaitWithTimeout(&cxt->mu, absl::Seconds(100));
224*9356374aSAndroid Build Coastguard Worker     }
225*9356374aSAndroid Build Coastguard Worker     if (cxt->g0 < cxt->iterations) {
226*9356374aSAndroid Build Coastguard Worker       int a = cxt->g0 + 1;
227*9356374aSAndroid Build Coastguard Worker       cxt->g0 = a;
228*9356374aSAndroid Build Coastguard Worker       cxt->cv.SignalAll();
229*9356374aSAndroid Build Coastguard Worker       target += cxt->threads;
230*9356374aSAndroid Build Coastguard Worker     }
231*9356374aSAndroid Build Coastguard Worker   }
232*9356374aSAndroid Build Coastguard Worker }
233*9356374aSAndroid Build Coastguard Worker 
G0GE2(TestContext * cxt)234*9356374aSAndroid Build Coastguard Worker static bool G0GE2(TestContext *cxt) { return cxt->g0 >= 2; }
235*9356374aSAndroid Build Coastguard Worker 
TestTime(TestContext * cxt,int c,bool use_cv)236*9356374aSAndroid Build Coastguard Worker static void TestTime(TestContext *cxt, int c, bool use_cv) {
237*9356374aSAndroid Build Coastguard Worker   CHECK_EQ(cxt->iterations, 1) << "TestTime should only use 1 iteration";
238*9356374aSAndroid Build Coastguard Worker   CHECK_GT(cxt->threads, 2) << "TestTime should use more than 2 threads";
239*9356374aSAndroid Build Coastguard Worker   const bool kFalse = false;
240*9356374aSAndroid Build Coastguard Worker   absl::Condition false_cond(&kFalse);
241*9356374aSAndroid Build Coastguard Worker   absl::Condition g0ge2(G0GE2, cxt);
242*9356374aSAndroid Build Coastguard Worker   if (c == 0) {
243*9356374aSAndroid Build Coastguard Worker     absl::MutexLock l(&cxt->mu);
244*9356374aSAndroid Build Coastguard Worker 
245*9356374aSAndroid Build Coastguard Worker     absl::Time start = absl::Now();
246*9356374aSAndroid Build Coastguard Worker     if (use_cv) {
247*9356374aSAndroid Build Coastguard Worker       cxt->cv.WaitWithTimeout(&cxt->mu, absl::Seconds(1));
248*9356374aSAndroid Build Coastguard Worker     } else {
249*9356374aSAndroid Build Coastguard Worker       CHECK(!cxt->mu.AwaitWithTimeout(false_cond, absl::Seconds(1)))
250*9356374aSAndroid Build Coastguard Worker           << "TestTime failed";
251*9356374aSAndroid Build Coastguard Worker     }
252*9356374aSAndroid Build Coastguard Worker     absl::Duration elapsed = absl::Now() - start;
253*9356374aSAndroid Build Coastguard Worker     CHECK(absl::Seconds(0.9) <= elapsed && elapsed <= absl::Seconds(2.0))
254*9356374aSAndroid Build Coastguard Worker         << "TestTime failed";
255*9356374aSAndroid Build Coastguard Worker     CHECK_EQ(cxt->g0, 1) << "TestTime failed";
256*9356374aSAndroid Build Coastguard Worker 
257*9356374aSAndroid Build Coastguard Worker     start = absl::Now();
258*9356374aSAndroid Build Coastguard Worker     if (use_cv) {
259*9356374aSAndroid Build Coastguard Worker       cxt->cv.WaitWithTimeout(&cxt->mu, absl::Seconds(1));
260*9356374aSAndroid Build Coastguard Worker     } else {
261*9356374aSAndroid Build Coastguard Worker       CHECK(!cxt->mu.AwaitWithTimeout(false_cond, absl::Seconds(1)))
262*9356374aSAndroid Build Coastguard Worker           << "TestTime failed";
263*9356374aSAndroid Build Coastguard Worker     }
264*9356374aSAndroid Build Coastguard Worker     elapsed = absl::Now() - start;
265*9356374aSAndroid Build Coastguard Worker     CHECK(absl::Seconds(0.9) <= elapsed && elapsed <= absl::Seconds(2.0))
266*9356374aSAndroid Build Coastguard Worker         << "TestTime failed";
267*9356374aSAndroid Build Coastguard Worker     cxt->g0++;
268*9356374aSAndroid Build Coastguard Worker     if (use_cv) {
269*9356374aSAndroid Build Coastguard Worker       cxt->cv.Signal();
270*9356374aSAndroid Build Coastguard Worker     }
271*9356374aSAndroid Build Coastguard Worker 
272*9356374aSAndroid Build Coastguard Worker     start = absl::Now();
273*9356374aSAndroid Build Coastguard Worker     if (use_cv) {
274*9356374aSAndroid Build Coastguard Worker       cxt->cv.WaitWithTimeout(&cxt->mu, absl::Seconds(4));
275*9356374aSAndroid Build Coastguard Worker     } else {
276*9356374aSAndroid Build Coastguard Worker       CHECK(!cxt->mu.AwaitWithTimeout(false_cond, absl::Seconds(4)))
277*9356374aSAndroid Build Coastguard Worker           << "TestTime failed";
278*9356374aSAndroid Build Coastguard Worker     }
279*9356374aSAndroid Build Coastguard Worker     elapsed = absl::Now() - start;
280*9356374aSAndroid Build Coastguard Worker     CHECK(absl::Seconds(3.9) <= elapsed && elapsed <= absl::Seconds(6.0))
281*9356374aSAndroid Build Coastguard Worker         << "TestTime failed";
282*9356374aSAndroid Build Coastguard Worker     CHECK_GE(cxt->g0, 3) << "TestTime failed";
283*9356374aSAndroid Build Coastguard Worker 
284*9356374aSAndroid Build Coastguard Worker     start = absl::Now();
285*9356374aSAndroid Build Coastguard Worker     if (use_cv) {
286*9356374aSAndroid Build Coastguard Worker       cxt->cv.WaitWithTimeout(&cxt->mu, absl::Seconds(1));
287*9356374aSAndroid Build Coastguard Worker     } else {
288*9356374aSAndroid Build Coastguard Worker       CHECK(!cxt->mu.AwaitWithTimeout(false_cond, absl::Seconds(1)))
289*9356374aSAndroid Build Coastguard Worker           << "TestTime failed";
290*9356374aSAndroid Build Coastguard Worker     }
291*9356374aSAndroid Build Coastguard Worker     elapsed = absl::Now() - start;
292*9356374aSAndroid Build Coastguard Worker     CHECK(absl::Seconds(0.9) <= elapsed && elapsed <= absl::Seconds(2.0))
293*9356374aSAndroid Build Coastguard Worker         << "TestTime failed";
294*9356374aSAndroid Build Coastguard Worker     if (use_cv) {
295*9356374aSAndroid Build Coastguard Worker       cxt->cv.SignalAll();
296*9356374aSAndroid Build Coastguard Worker     }
297*9356374aSAndroid Build Coastguard Worker 
298*9356374aSAndroid Build Coastguard Worker     start = absl::Now();
299*9356374aSAndroid Build Coastguard Worker     if (use_cv) {
300*9356374aSAndroid Build Coastguard Worker       cxt->cv.WaitWithTimeout(&cxt->mu, absl::Seconds(1));
301*9356374aSAndroid Build Coastguard Worker     } else {
302*9356374aSAndroid Build Coastguard Worker       CHECK(!cxt->mu.AwaitWithTimeout(false_cond, absl::Seconds(1)))
303*9356374aSAndroid Build Coastguard Worker           << "TestTime failed";
304*9356374aSAndroid Build Coastguard Worker     }
305*9356374aSAndroid Build Coastguard Worker     elapsed = absl::Now() - start;
306*9356374aSAndroid Build Coastguard Worker     CHECK(absl::Seconds(0.9) <= elapsed && elapsed <= absl::Seconds(2.0))
307*9356374aSAndroid Build Coastguard Worker         << "TestTime failed";
308*9356374aSAndroid Build Coastguard Worker     CHECK_EQ(cxt->g0, cxt->threads) << "TestTime failed";
309*9356374aSAndroid Build Coastguard Worker 
310*9356374aSAndroid Build Coastguard Worker   } else if (c == 1) {
311*9356374aSAndroid Build Coastguard Worker     absl::MutexLock l(&cxt->mu);
312*9356374aSAndroid Build Coastguard Worker     const absl::Time start = absl::Now();
313*9356374aSAndroid Build Coastguard Worker     if (use_cv) {
314*9356374aSAndroid Build Coastguard Worker       cxt->cv.WaitWithTimeout(&cxt->mu, absl::Milliseconds(500));
315*9356374aSAndroid Build Coastguard Worker     } else {
316*9356374aSAndroid Build Coastguard Worker       CHECK(!cxt->mu.AwaitWithTimeout(false_cond, absl::Milliseconds(500)))
317*9356374aSAndroid Build Coastguard Worker           << "TestTime failed";
318*9356374aSAndroid Build Coastguard Worker     }
319*9356374aSAndroid Build Coastguard Worker     const absl::Duration elapsed = absl::Now() - start;
320*9356374aSAndroid Build Coastguard Worker     CHECK(absl::Seconds(0.4) <= elapsed && elapsed <= absl::Seconds(0.9))
321*9356374aSAndroid Build Coastguard Worker         << "TestTime failed";
322*9356374aSAndroid Build Coastguard Worker     cxt->g0++;
323*9356374aSAndroid Build Coastguard Worker   } else if (c == 2) {
324*9356374aSAndroid Build Coastguard Worker     absl::MutexLock l(&cxt->mu);
325*9356374aSAndroid Build Coastguard Worker     if (use_cv) {
326*9356374aSAndroid Build Coastguard Worker       while (cxt->g0 < 2) {
327*9356374aSAndroid Build Coastguard Worker         cxt->cv.WaitWithTimeout(&cxt->mu, absl::Seconds(100));
328*9356374aSAndroid Build Coastguard Worker       }
329*9356374aSAndroid Build Coastguard Worker     } else {
330*9356374aSAndroid Build Coastguard Worker       CHECK(cxt->mu.AwaitWithTimeout(g0ge2, absl::Seconds(100)))
331*9356374aSAndroid Build Coastguard Worker           << "TestTime failed";
332*9356374aSAndroid Build Coastguard Worker     }
333*9356374aSAndroid Build Coastguard Worker     cxt->g0++;
334*9356374aSAndroid Build Coastguard Worker   } else {
335*9356374aSAndroid Build Coastguard Worker     absl::MutexLock l(&cxt->mu);
336*9356374aSAndroid Build Coastguard Worker     if (use_cv) {
337*9356374aSAndroid Build Coastguard Worker       while (cxt->g0 < 2) {
338*9356374aSAndroid Build Coastguard Worker         cxt->cv.Wait(&cxt->mu);
339*9356374aSAndroid Build Coastguard Worker       }
340*9356374aSAndroid Build Coastguard Worker     } else {
341*9356374aSAndroid Build Coastguard Worker       cxt->mu.Await(g0ge2);
342*9356374aSAndroid Build Coastguard Worker     }
343*9356374aSAndroid Build Coastguard Worker     cxt->g0++;
344*9356374aSAndroid Build Coastguard Worker   }
345*9356374aSAndroid Build Coastguard Worker }
346*9356374aSAndroid Build Coastguard Worker 
TestMuTime(TestContext * cxt,int c)347*9356374aSAndroid Build Coastguard Worker static void TestMuTime(TestContext *cxt, int c) { TestTime(cxt, c, false); }
348*9356374aSAndroid Build Coastguard Worker 
TestCVTime(TestContext * cxt,int c)349*9356374aSAndroid Build Coastguard Worker static void TestCVTime(TestContext *cxt, int c) { TestTime(cxt, c, true); }
350*9356374aSAndroid Build Coastguard Worker 
EndTest(int * c0,int * c1,absl::Mutex * mu,absl::CondVar * cv,const std::function<void (int)> & cb)351*9356374aSAndroid Build Coastguard Worker static void EndTest(int *c0, int *c1, absl::Mutex *mu, absl::CondVar *cv,
352*9356374aSAndroid Build Coastguard Worker                     const std::function<void(int)> &cb) {
353*9356374aSAndroid Build Coastguard Worker   mu->Lock();
354*9356374aSAndroid Build Coastguard Worker   int c = (*c0)++;
355*9356374aSAndroid Build Coastguard Worker   mu->Unlock();
356*9356374aSAndroid Build Coastguard Worker   cb(c);
357*9356374aSAndroid Build Coastguard Worker   absl::MutexLock l(mu);
358*9356374aSAndroid Build Coastguard Worker   (*c1)++;
359*9356374aSAndroid Build Coastguard Worker   cv->Signal();
360*9356374aSAndroid Build Coastguard Worker }
361*9356374aSAndroid Build Coastguard Worker 
362*9356374aSAndroid Build Coastguard Worker // Code common to RunTest() and RunTestWithInvariantDebugging().
RunTestCommon(TestContext * cxt,void (* test)(TestContext * cxt,int),int threads,int iterations,int operations)363*9356374aSAndroid Build Coastguard Worker static int RunTestCommon(TestContext *cxt, void (*test)(TestContext *cxt, int),
364*9356374aSAndroid Build Coastguard Worker                          int threads, int iterations, int operations) {
365*9356374aSAndroid Build Coastguard Worker   absl::Mutex mu2;
366*9356374aSAndroid Build Coastguard Worker   absl::CondVar cv2;
367*9356374aSAndroid Build Coastguard Worker   int c0 = 0;
368*9356374aSAndroid Build Coastguard Worker   int c1 = 0;
369*9356374aSAndroid Build Coastguard Worker   cxt->g0 = 0;
370*9356374aSAndroid Build Coastguard Worker   cxt->g1 = 0;
371*9356374aSAndroid Build Coastguard Worker   cxt->iterations = iterations;
372*9356374aSAndroid Build Coastguard Worker   cxt->threads = threads;
373*9356374aSAndroid Build Coastguard Worker   absl::synchronization_internal::ThreadPool tp(threads);
374*9356374aSAndroid Build Coastguard Worker   for (int i = 0; i != threads; i++) {
375*9356374aSAndroid Build Coastguard Worker     tp.Schedule(std::bind(
376*9356374aSAndroid Build Coastguard Worker         &EndTest, &c0, &c1, &mu2, &cv2,
377*9356374aSAndroid Build Coastguard Worker         std::function<void(int)>(std::bind(test, cxt, std::placeholders::_1))));
378*9356374aSAndroid Build Coastguard Worker   }
379*9356374aSAndroid Build Coastguard Worker   mu2.Lock();
380*9356374aSAndroid Build Coastguard Worker   while (c1 != threads) {
381*9356374aSAndroid Build Coastguard Worker     cv2.Wait(&mu2);
382*9356374aSAndroid Build Coastguard Worker   }
383*9356374aSAndroid Build Coastguard Worker   mu2.Unlock();
384*9356374aSAndroid Build Coastguard Worker   return cxt->g0;
385*9356374aSAndroid Build Coastguard Worker }
386*9356374aSAndroid Build Coastguard Worker 
387*9356374aSAndroid Build Coastguard Worker // Basis for the parameterized tests configured below.
RunTest(void (* test)(TestContext * cxt,int),int threads,int iterations,int operations)388*9356374aSAndroid Build Coastguard Worker static int RunTest(void (*test)(TestContext *cxt, int), int threads,
389*9356374aSAndroid Build Coastguard Worker                    int iterations, int operations) {
390*9356374aSAndroid Build Coastguard Worker   TestContext cxt;
391*9356374aSAndroid Build Coastguard Worker   return RunTestCommon(&cxt, test, threads, iterations, operations);
392*9356374aSAndroid Build Coastguard Worker }
393*9356374aSAndroid Build Coastguard Worker 
394*9356374aSAndroid Build Coastguard Worker // Like RunTest(), but sets an invariant on the tested Mutex and
395*9356374aSAndroid Build Coastguard Worker // verifies that the invariant check happened. The invariant function
396*9356374aSAndroid Build Coastguard Worker // will be passed the TestContext* as its arg and must call
397*9356374aSAndroid Build Coastguard Worker // SetInvariantChecked(true);
398*9356374aSAndroid Build Coastguard Worker #if !defined(ABSL_MUTEX_ENABLE_INVARIANT_DEBUGGING_NOT_IMPLEMENTED)
RunTestWithInvariantDebugging(void (* test)(TestContext * cxt,int),int threads,int iterations,int operations,void (* invariant)(void *))399*9356374aSAndroid Build Coastguard Worker static int RunTestWithInvariantDebugging(void (*test)(TestContext *cxt, int),
400*9356374aSAndroid Build Coastguard Worker                                          int threads, int iterations,
401*9356374aSAndroid Build Coastguard Worker                                          int operations,
402*9356374aSAndroid Build Coastguard Worker                                          void (*invariant)(void *)) {
403*9356374aSAndroid Build Coastguard Worker   ScopedInvariantDebugging scoped_debugging;
404*9356374aSAndroid Build Coastguard Worker   SetInvariantChecked(false);
405*9356374aSAndroid Build Coastguard Worker   TestContext cxt;
406*9356374aSAndroid Build Coastguard Worker   cxt.mu.EnableInvariantDebugging(invariant, &cxt);
407*9356374aSAndroid Build Coastguard Worker   int ret = RunTestCommon(&cxt, test, threads, iterations, operations);
408*9356374aSAndroid Build Coastguard Worker   CHECK(GetInvariantChecked()) << "Invariant not checked";
409*9356374aSAndroid Build Coastguard Worker   return ret;
410*9356374aSAndroid Build Coastguard Worker }
411*9356374aSAndroid Build Coastguard Worker #endif
412*9356374aSAndroid Build Coastguard Worker 
413*9356374aSAndroid Build Coastguard Worker // --------------------------------------------------------
414*9356374aSAndroid Build Coastguard Worker // Test for fix of bug in TryRemove()
415*9356374aSAndroid Build Coastguard Worker struct TimeoutBugStruct {
416*9356374aSAndroid Build Coastguard Worker   absl::Mutex mu;
417*9356374aSAndroid Build Coastguard Worker   bool a;
418*9356374aSAndroid Build Coastguard Worker   int a_waiter_count;
419*9356374aSAndroid Build Coastguard Worker };
420*9356374aSAndroid Build Coastguard Worker 
WaitForA(TimeoutBugStruct * x)421*9356374aSAndroid Build Coastguard Worker static void WaitForA(TimeoutBugStruct *x) {
422*9356374aSAndroid Build Coastguard Worker   x->mu.LockWhen(absl::Condition(&x->a));
423*9356374aSAndroid Build Coastguard Worker   x->a_waiter_count--;
424*9356374aSAndroid Build Coastguard Worker   x->mu.Unlock();
425*9356374aSAndroid Build Coastguard Worker }
426*9356374aSAndroid Build Coastguard Worker 
NoAWaiters(TimeoutBugStruct * x)427*9356374aSAndroid Build Coastguard Worker static bool NoAWaiters(TimeoutBugStruct *x) { return x->a_waiter_count == 0; }
428*9356374aSAndroid Build Coastguard Worker 
429*9356374aSAndroid Build Coastguard Worker // Test that a CondVar.Wait(&mutex) can un-block a call to mutex.Await() in
430*9356374aSAndroid Build Coastguard Worker // another thread.
TEST(Mutex,CondVarWaitSignalsAwait)431*9356374aSAndroid Build Coastguard Worker TEST(Mutex, CondVarWaitSignalsAwait) {
432*9356374aSAndroid Build Coastguard Worker   // Use a struct so the lock annotations apply.
433*9356374aSAndroid Build Coastguard Worker   struct {
434*9356374aSAndroid Build Coastguard Worker     absl::Mutex barrier_mu;
435*9356374aSAndroid Build Coastguard Worker     bool barrier ABSL_GUARDED_BY(barrier_mu) = false;
436*9356374aSAndroid Build Coastguard Worker 
437*9356374aSAndroid Build Coastguard Worker     absl::Mutex release_mu;
438*9356374aSAndroid Build Coastguard Worker     bool release ABSL_GUARDED_BY(release_mu) = false;
439*9356374aSAndroid Build Coastguard Worker     absl::CondVar released_cv;
440*9356374aSAndroid Build Coastguard Worker   } state;
441*9356374aSAndroid Build Coastguard Worker 
442*9356374aSAndroid Build Coastguard Worker   auto pool = CreateDefaultPool();
443*9356374aSAndroid Build Coastguard Worker 
444*9356374aSAndroid Build Coastguard Worker   // Thread A.  Sets barrier, waits for release using Mutex::Await, then
445*9356374aSAndroid Build Coastguard Worker   // signals released_cv.
446*9356374aSAndroid Build Coastguard Worker   pool->Schedule([&state] {
447*9356374aSAndroid Build Coastguard Worker     state.release_mu.Lock();
448*9356374aSAndroid Build Coastguard Worker 
449*9356374aSAndroid Build Coastguard Worker     state.barrier_mu.Lock();
450*9356374aSAndroid Build Coastguard Worker     state.barrier = true;
451*9356374aSAndroid Build Coastguard Worker     state.barrier_mu.Unlock();
452*9356374aSAndroid Build Coastguard Worker 
453*9356374aSAndroid Build Coastguard Worker     state.release_mu.Await(absl::Condition(&state.release));
454*9356374aSAndroid Build Coastguard Worker     state.released_cv.Signal();
455*9356374aSAndroid Build Coastguard Worker     state.release_mu.Unlock();
456*9356374aSAndroid Build Coastguard Worker   });
457*9356374aSAndroid Build Coastguard Worker 
458*9356374aSAndroid Build Coastguard Worker   state.barrier_mu.LockWhen(absl::Condition(&state.barrier));
459*9356374aSAndroid Build Coastguard Worker   state.barrier_mu.Unlock();
460*9356374aSAndroid Build Coastguard Worker   state.release_mu.Lock();
461*9356374aSAndroid Build Coastguard Worker   // Thread A is now blocked on release by way of Mutex::Await().
462*9356374aSAndroid Build Coastguard Worker 
463*9356374aSAndroid Build Coastguard Worker   // Set release.  Calling released_cv.Wait() should un-block thread A,
464*9356374aSAndroid Build Coastguard Worker   // which will signal released_cv.  If not, the test will hang.
465*9356374aSAndroid Build Coastguard Worker   state.release = true;
466*9356374aSAndroid Build Coastguard Worker   state.released_cv.Wait(&state.release_mu);
467*9356374aSAndroid Build Coastguard Worker   state.release_mu.Unlock();
468*9356374aSAndroid Build Coastguard Worker }
469*9356374aSAndroid Build Coastguard Worker 
470*9356374aSAndroid Build Coastguard Worker // Test that a CondVar.WaitWithTimeout(&mutex) can un-block a call to
471*9356374aSAndroid Build Coastguard Worker // mutex.Await() in another thread.
TEST(Mutex,CondVarWaitWithTimeoutSignalsAwait)472*9356374aSAndroid Build Coastguard Worker TEST(Mutex, CondVarWaitWithTimeoutSignalsAwait) {
473*9356374aSAndroid Build Coastguard Worker   // Use a struct so the lock annotations apply.
474*9356374aSAndroid Build Coastguard Worker   struct {
475*9356374aSAndroid Build Coastguard Worker     absl::Mutex barrier_mu;
476*9356374aSAndroid Build Coastguard Worker     bool barrier ABSL_GUARDED_BY(barrier_mu) = false;
477*9356374aSAndroid Build Coastguard Worker 
478*9356374aSAndroid Build Coastguard Worker     absl::Mutex release_mu;
479*9356374aSAndroid Build Coastguard Worker     bool release ABSL_GUARDED_BY(release_mu) = false;
480*9356374aSAndroid Build Coastguard Worker     absl::CondVar released_cv;
481*9356374aSAndroid Build Coastguard Worker   } state;
482*9356374aSAndroid Build Coastguard Worker 
483*9356374aSAndroid Build Coastguard Worker   auto pool = CreateDefaultPool();
484*9356374aSAndroid Build Coastguard Worker 
485*9356374aSAndroid Build Coastguard Worker   // Thread A.  Sets barrier, waits for release using Mutex::Await, then
486*9356374aSAndroid Build Coastguard Worker   // signals released_cv.
487*9356374aSAndroid Build Coastguard Worker   pool->Schedule([&state] {
488*9356374aSAndroid Build Coastguard Worker     state.release_mu.Lock();
489*9356374aSAndroid Build Coastguard Worker 
490*9356374aSAndroid Build Coastguard Worker     state.barrier_mu.Lock();
491*9356374aSAndroid Build Coastguard Worker     state.barrier = true;
492*9356374aSAndroid Build Coastguard Worker     state.barrier_mu.Unlock();
493*9356374aSAndroid Build Coastguard Worker 
494*9356374aSAndroid Build Coastguard Worker     state.release_mu.Await(absl::Condition(&state.release));
495*9356374aSAndroid Build Coastguard Worker     state.released_cv.Signal();
496*9356374aSAndroid Build Coastguard Worker     state.release_mu.Unlock();
497*9356374aSAndroid Build Coastguard Worker   });
498*9356374aSAndroid Build Coastguard Worker 
499*9356374aSAndroid Build Coastguard Worker   state.barrier_mu.LockWhen(absl::Condition(&state.barrier));
500*9356374aSAndroid Build Coastguard Worker   state.barrier_mu.Unlock();
501*9356374aSAndroid Build Coastguard Worker   state.release_mu.Lock();
502*9356374aSAndroid Build Coastguard Worker   // Thread A is now blocked on release by way of Mutex::Await().
503*9356374aSAndroid Build Coastguard Worker 
504*9356374aSAndroid Build Coastguard Worker   // Set release.  Calling released_cv.Wait() should un-block thread A,
505*9356374aSAndroid Build Coastguard Worker   // which will signal released_cv.  If not, the test will hang.
506*9356374aSAndroid Build Coastguard Worker   state.release = true;
507*9356374aSAndroid Build Coastguard Worker   EXPECT_TRUE(
508*9356374aSAndroid Build Coastguard Worker       !state.released_cv.WaitWithTimeout(&state.release_mu, absl::Seconds(10)))
509*9356374aSAndroid Build Coastguard Worker       << "; Unrecoverable test failure: CondVar::WaitWithTimeout did not "
510*9356374aSAndroid Build Coastguard Worker          "unblock the absl::Mutex::Await call in another thread.";
511*9356374aSAndroid Build Coastguard Worker 
512*9356374aSAndroid Build Coastguard Worker   state.release_mu.Unlock();
513*9356374aSAndroid Build Coastguard Worker }
514*9356374aSAndroid Build Coastguard Worker 
515*9356374aSAndroid Build Coastguard Worker // Test for regression of a bug in loop of TryRemove()
TEST(Mutex,MutexTimeoutBug)516*9356374aSAndroid Build Coastguard Worker TEST(Mutex, MutexTimeoutBug) {
517*9356374aSAndroid Build Coastguard Worker   auto tp = CreateDefaultPool();
518*9356374aSAndroid Build Coastguard Worker 
519*9356374aSAndroid Build Coastguard Worker   TimeoutBugStruct x;
520*9356374aSAndroid Build Coastguard Worker   x.a = false;
521*9356374aSAndroid Build Coastguard Worker   x.a_waiter_count = 2;
522*9356374aSAndroid Build Coastguard Worker   tp->Schedule(std::bind(&WaitForA, &x));
523*9356374aSAndroid Build Coastguard Worker   tp->Schedule(std::bind(&WaitForA, &x));
524*9356374aSAndroid Build Coastguard Worker   absl::SleepFor(absl::Seconds(1));  // Allow first two threads to hang.
525*9356374aSAndroid Build Coastguard Worker   // The skip field of the second will point to the first because there are
526*9356374aSAndroid Build Coastguard Worker   // only two.
527*9356374aSAndroid Build Coastguard Worker 
528*9356374aSAndroid Build Coastguard Worker   // Now cause a thread waiting on an always-false to time out
529*9356374aSAndroid Build Coastguard Worker   // This would deadlock when the bug was present.
530*9356374aSAndroid Build Coastguard Worker   bool always_false = false;
531*9356374aSAndroid Build Coastguard Worker   x.mu.LockWhenWithTimeout(absl::Condition(&always_false),
532*9356374aSAndroid Build Coastguard Worker                            absl::Milliseconds(500));
533*9356374aSAndroid Build Coastguard Worker 
534*9356374aSAndroid Build Coastguard Worker   // if we get here, the bug is not present.   Cleanup the state.
535*9356374aSAndroid Build Coastguard Worker 
536*9356374aSAndroid Build Coastguard Worker   x.a = true;                                    // wakeup the two waiters on A
537*9356374aSAndroid Build Coastguard Worker   x.mu.Await(absl::Condition(&NoAWaiters, &x));  // wait for them to exit
538*9356374aSAndroid Build Coastguard Worker   x.mu.Unlock();
539*9356374aSAndroid Build Coastguard Worker }
540*9356374aSAndroid Build Coastguard Worker 
541*9356374aSAndroid Build Coastguard Worker struct CondVarWaitDeadlock : testing::TestWithParam<int> {
542*9356374aSAndroid Build Coastguard Worker   absl::Mutex mu;
543*9356374aSAndroid Build Coastguard Worker   absl::CondVar cv;
544*9356374aSAndroid Build Coastguard Worker   bool cond1 = false;
545*9356374aSAndroid Build Coastguard Worker   bool cond2 = false;
546*9356374aSAndroid Build Coastguard Worker   bool read_lock1;
547*9356374aSAndroid Build Coastguard Worker   bool read_lock2;
548*9356374aSAndroid Build Coastguard Worker   bool signal_unlocked;
549*9356374aSAndroid Build Coastguard Worker 
CondVarWaitDeadlock__anon8f30ae2e0111::CondVarWaitDeadlock550*9356374aSAndroid Build Coastguard Worker   CondVarWaitDeadlock() {
551*9356374aSAndroid Build Coastguard Worker     read_lock1 = GetParam() & (1 << 0);
552*9356374aSAndroid Build Coastguard Worker     read_lock2 = GetParam() & (1 << 1);
553*9356374aSAndroid Build Coastguard Worker     signal_unlocked = GetParam() & (1 << 2);
554*9356374aSAndroid Build Coastguard Worker   }
555*9356374aSAndroid Build Coastguard Worker 
Waiter1__anon8f30ae2e0111::CondVarWaitDeadlock556*9356374aSAndroid Build Coastguard Worker   void Waiter1() {
557*9356374aSAndroid Build Coastguard Worker     if (read_lock1) {
558*9356374aSAndroid Build Coastguard Worker       mu.ReaderLock();
559*9356374aSAndroid Build Coastguard Worker       while (!cond1) {
560*9356374aSAndroid Build Coastguard Worker         cv.Wait(&mu);
561*9356374aSAndroid Build Coastguard Worker       }
562*9356374aSAndroid Build Coastguard Worker       mu.ReaderUnlock();
563*9356374aSAndroid Build Coastguard Worker     } else {
564*9356374aSAndroid Build Coastguard Worker       mu.Lock();
565*9356374aSAndroid Build Coastguard Worker       while (!cond1) {
566*9356374aSAndroid Build Coastguard Worker         cv.Wait(&mu);
567*9356374aSAndroid Build Coastguard Worker       }
568*9356374aSAndroid Build Coastguard Worker       mu.Unlock();
569*9356374aSAndroid Build Coastguard Worker     }
570*9356374aSAndroid Build Coastguard Worker   }
571*9356374aSAndroid Build Coastguard Worker 
Waiter2__anon8f30ae2e0111::CondVarWaitDeadlock572*9356374aSAndroid Build Coastguard Worker   void Waiter2() {
573*9356374aSAndroid Build Coastguard Worker     if (read_lock2) {
574*9356374aSAndroid Build Coastguard Worker       mu.ReaderLockWhen(absl::Condition(&cond2));
575*9356374aSAndroid Build Coastguard Worker       mu.ReaderUnlock();
576*9356374aSAndroid Build Coastguard Worker     } else {
577*9356374aSAndroid Build Coastguard Worker       mu.LockWhen(absl::Condition(&cond2));
578*9356374aSAndroid Build Coastguard Worker       mu.Unlock();
579*9356374aSAndroid Build Coastguard Worker     }
580*9356374aSAndroid Build Coastguard Worker   }
581*9356374aSAndroid Build Coastguard Worker };
582*9356374aSAndroid Build Coastguard Worker 
583*9356374aSAndroid Build Coastguard Worker // Test for a deadlock bug in Mutex::Fer().
584*9356374aSAndroid Build Coastguard Worker // The sequence of events that lead to the deadlock is:
585*9356374aSAndroid Build Coastguard Worker // 1. waiter1 blocks on cv in read mode (mu bits = 0).
586*9356374aSAndroid Build Coastguard Worker // 2. waiter2 blocks on mu in either mode (mu bits = kMuWait).
587*9356374aSAndroid Build Coastguard Worker // 3. main thread locks mu, sets cond1, unlocks mu (mu bits = kMuWait).
588*9356374aSAndroid Build Coastguard Worker // 4. main thread signals on cv and this eventually calls Mutex::Fer().
589*9356374aSAndroid Build Coastguard Worker // Currently Fer wakes waiter1 since mu bits = kMuWait (mutex is unlocked).
590*9356374aSAndroid Build Coastguard Worker // Before the bug fix Fer neither woke waiter1 nor queued it on mutex,
591*9356374aSAndroid Build Coastguard Worker // which resulted in deadlock.
TEST_P(CondVarWaitDeadlock,Test)592*9356374aSAndroid Build Coastguard Worker TEST_P(CondVarWaitDeadlock, Test) {
593*9356374aSAndroid Build Coastguard Worker   auto waiter1 = CreatePool(1);
594*9356374aSAndroid Build Coastguard Worker   auto waiter2 = CreatePool(1);
595*9356374aSAndroid Build Coastguard Worker   waiter1->Schedule([this] { this->Waiter1(); });
596*9356374aSAndroid Build Coastguard Worker   waiter2->Schedule([this] { this->Waiter2(); });
597*9356374aSAndroid Build Coastguard Worker 
598*9356374aSAndroid Build Coastguard Worker   // Wait while threads block (best-effort is fine).
599*9356374aSAndroid Build Coastguard Worker   absl::SleepFor(absl::Milliseconds(100));
600*9356374aSAndroid Build Coastguard Worker 
601*9356374aSAndroid Build Coastguard Worker   // Wake condwaiter.
602*9356374aSAndroid Build Coastguard Worker   mu.Lock();
603*9356374aSAndroid Build Coastguard Worker   cond1 = true;
604*9356374aSAndroid Build Coastguard Worker   if (signal_unlocked) {
605*9356374aSAndroid Build Coastguard Worker     mu.Unlock();
606*9356374aSAndroid Build Coastguard Worker     cv.Signal();
607*9356374aSAndroid Build Coastguard Worker   } else {
608*9356374aSAndroid Build Coastguard Worker     cv.Signal();
609*9356374aSAndroid Build Coastguard Worker     mu.Unlock();
610*9356374aSAndroid Build Coastguard Worker   }
611*9356374aSAndroid Build Coastguard Worker   waiter1.reset();  // "join" waiter1
612*9356374aSAndroid Build Coastguard Worker 
613*9356374aSAndroid Build Coastguard Worker   // Wake waiter.
614*9356374aSAndroid Build Coastguard Worker   mu.Lock();
615*9356374aSAndroid Build Coastguard Worker   cond2 = true;
616*9356374aSAndroid Build Coastguard Worker   mu.Unlock();
617*9356374aSAndroid Build Coastguard Worker   waiter2.reset();  // "join" waiter2
618*9356374aSAndroid Build Coastguard Worker }
619*9356374aSAndroid Build Coastguard Worker 
620*9356374aSAndroid Build Coastguard Worker INSTANTIATE_TEST_SUITE_P(CondVarWaitDeadlockTest, CondVarWaitDeadlock,
621*9356374aSAndroid Build Coastguard Worker                          ::testing::Range(0, 8),
622*9356374aSAndroid Build Coastguard Worker                          ::testing::PrintToStringParamName());
623*9356374aSAndroid Build Coastguard Worker 
624*9356374aSAndroid Build Coastguard Worker // --------------------------------------------------------
625*9356374aSAndroid Build Coastguard Worker // Test for fix of bug in DequeueAllWakeable()
626*9356374aSAndroid Build Coastguard Worker // Bug was that if there was more than one waiting reader
627*9356374aSAndroid Build Coastguard Worker // and all should be woken, the most recently blocked one
628*9356374aSAndroid Build Coastguard Worker // would not be.
629*9356374aSAndroid Build Coastguard Worker 
630*9356374aSAndroid Build Coastguard Worker struct DequeueAllWakeableBugStruct {
631*9356374aSAndroid Build Coastguard Worker   absl::Mutex mu;
632*9356374aSAndroid Build Coastguard Worker   absl::Mutex mu2;       // protects all fields below
633*9356374aSAndroid Build Coastguard Worker   int unfinished_count;  // count of unfinished readers; under mu2
634*9356374aSAndroid Build Coastguard Worker   bool done1;            // unfinished_count == 0; under mu2
635*9356374aSAndroid Build Coastguard Worker   int finished_count;    // count of finished readers, under mu2
636*9356374aSAndroid Build Coastguard Worker   bool done2;            // finished_count == 0; under mu2
637*9356374aSAndroid Build Coastguard Worker };
638*9356374aSAndroid Build Coastguard Worker 
639*9356374aSAndroid Build Coastguard Worker // Test for regression of a bug in loop of DequeueAllWakeable()
AcquireAsReader(DequeueAllWakeableBugStruct * x)640*9356374aSAndroid Build Coastguard Worker static void AcquireAsReader(DequeueAllWakeableBugStruct *x) {
641*9356374aSAndroid Build Coastguard Worker   x->mu.ReaderLock();
642*9356374aSAndroid Build Coastguard Worker   x->mu2.Lock();
643*9356374aSAndroid Build Coastguard Worker   x->unfinished_count--;
644*9356374aSAndroid Build Coastguard Worker   x->done1 = (x->unfinished_count == 0);
645*9356374aSAndroid Build Coastguard Worker   x->mu2.Unlock();
646*9356374aSAndroid Build Coastguard Worker   // make sure that both readers acquired mu before we release it.
647*9356374aSAndroid Build Coastguard Worker   absl::SleepFor(absl::Seconds(2));
648*9356374aSAndroid Build Coastguard Worker   x->mu.ReaderUnlock();
649*9356374aSAndroid Build Coastguard Worker 
650*9356374aSAndroid Build Coastguard Worker   x->mu2.Lock();
651*9356374aSAndroid Build Coastguard Worker   x->finished_count--;
652*9356374aSAndroid Build Coastguard Worker   x->done2 = (x->finished_count == 0);
653*9356374aSAndroid Build Coastguard Worker   x->mu2.Unlock();
654*9356374aSAndroid Build Coastguard Worker }
655*9356374aSAndroid Build Coastguard Worker 
656*9356374aSAndroid Build Coastguard Worker // Test for regression of a bug in loop of DequeueAllWakeable()
TEST(Mutex,MutexReaderWakeupBug)657*9356374aSAndroid Build Coastguard Worker TEST(Mutex, MutexReaderWakeupBug) {
658*9356374aSAndroid Build Coastguard Worker   auto tp = CreateDefaultPool();
659*9356374aSAndroid Build Coastguard Worker 
660*9356374aSAndroid Build Coastguard Worker   DequeueAllWakeableBugStruct x;
661*9356374aSAndroid Build Coastguard Worker   x.unfinished_count = 2;
662*9356374aSAndroid Build Coastguard Worker   x.done1 = false;
663*9356374aSAndroid Build Coastguard Worker   x.finished_count = 2;
664*9356374aSAndroid Build Coastguard Worker   x.done2 = false;
665*9356374aSAndroid Build Coastguard Worker   x.mu.Lock();  // acquire mu exclusively
666*9356374aSAndroid Build Coastguard Worker   // queue two thread that will block on reader locks on x.mu
667*9356374aSAndroid Build Coastguard Worker   tp->Schedule(std::bind(&AcquireAsReader, &x));
668*9356374aSAndroid Build Coastguard Worker   tp->Schedule(std::bind(&AcquireAsReader, &x));
669*9356374aSAndroid Build Coastguard Worker   absl::SleepFor(absl::Seconds(1));  // give time for reader threads to block
670*9356374aSAndroid Build Coastguard Worker   x.mu.Unlock();                     // wake them up
671*9356374aSAndroid Build Coastguard Worker 
672*9356374aSAndroid Build Coastguard Worker   // both readers should finish promptly
673*9356374aSAndroid Build Coastguard Worker   EXPECT_TRUE(
674*9356374aSAndroid Build Coastguard Worker       x.mu2.LockWhenWithTimeout(absl::Condition(&x.done1), absl::Seconds(10)));
675*9356374aSAndroid Build Coastguard Worker   x.mu2.Unlock();
676*9356374aSAndroid Build Coastguard Worker 
677*9356374aSAndroid Build Coastguard Worker   EXPECT_TRUE(
678*9356374aSAndroid Build Coastguard Worker       x.mu2.LockWhenWithTimeout(absl::Condition(&x.done2), absl::Seconds(10)));
679*9356374aSAndroid Build Coastguard Worker   x.mu2.Unlock();
680*9356374aSAndroid Build Coastguard Worker }
681*9356374aSAndroid Build Coastguard Worker 
682*9356374aSAndroid Build Coastguard Worker struct LockWhenTestStruct {
683*9356374aSAndroid Build Coastguard Worker   absl::Mutex mu1;
684*9356374aSAndroid Build Coastguard Worker   bool cond = false;
685*9356374aSAndroid Build Coastguard Worker 
686*9356374aSAndroid Build Coastguard Worker   absl::Mutex mu2;
687*9356374aSAndroid Build Coastguard Worker   bool waiting = false;
688*9356374aSAndroid Build Coastguard Worker };
689*9356374aSAndroid Build Coastguard Worker 
LockWhenTestIsCond(LockWhenTestStruct * s)690*9356374aSAndroid Build Coastguard Worker static bool LockWhenTestIsCond(LockWhenTestStruct *s) {
691*9356374aSAndroid Build Coastguard Worker   s->mu2.Lock();
692*9356374aSAndroid Build Coastguard Worker   s->waiting = true;
693*9356374aSAndroid Build Coastguard Worker   s->mu2.Unlock();
694*9356374aSAndroid Build Coastguard Worker   return s->cond;
695*9356374aSAndroid Build Coastguard Worker }
696*9356374aSAndroid Build Coastguard Worker 
LockWhenTestWaitForIsCond(LockWhenTestStruct * s)697*9356374aSAndroid Build Coastguard Worker static void LockWhenTestWaitForIsCond(LockWhenTestStruct *s) {
698*9356374aSAndroid Build Coastguard Worker   s->mu1.LockWhen(absl::Condition(&LockWhenTestIsCond, s));
699*9356374aSAndroid Build Coastguard Worker   s->mu1.Unlock();
700*9356374aSAndroid Build Coastguard Worker }
701*9356374aSAndroid Build Coastguard Worker 
TEST(Mutex,LockWhen)702*9356374aSAndroid Build Coastguard Worker TEST(Mutex, LockWhen) {
703*9356374aSAndroid Build Coastguard Worker   LockWhenTestStruct s;
704*9356374aSAndroid Build Coastguard Worker 
705*9356374aSAndroid Build Coastguard Worker   std::thread t(LockWhenTestWaitForIsCond, &s);
706*9356374aSAndroid Build Coastguard Worker   s.mu2.LockWhen(absl::Condition(&s.waiting));
707*9356374aSAndroid Build Coastguard Worker   s.mu2.Unlock();
708*9356374aSAndroid Build Coastguard Worker 
709*9356374aSAndroid Build Coastguard Worker   s.mu1.Lock();
710*9356374aSAndroid Build Coastguard Worker   s.cond = true;
711*9356374aSAndroid Build Coastguard Worker   s.mu1.Unlock();
712*9356374aSAndroid Build Coastguard Worker 
713*9356374aSAndroid Build Coastguard Worker   t.join();
714*9356374aSAndroid Build Coastguard Worker }
715*9356374aSAndroid Build Coastguard Worker 
TEST(Mutex,LockWhenGuard)716*9356374aSAndroid Build Coastguard Worker TEST(Mutex, LockWhenGuard) {
717*9356374aSAndroid Build Coastguard Worker   absl::Mutex mu;
718*9356374aSAndroid Build Coastguard Worker   int n = 30;
719*9356374aSAndroid Build Coastguard Worker   bool done = false;
720*9356374aSAndroid Build Coastguard Worker 
721*9356374aSAndroid Build Coastguard Worker   // We don't inline the lambda because the conversion is ambiguous in MSVC.
722*9356374aSAndroid Build Coastguard Worker   bool (*cond_eq_10)(int *) = [](int *p) { return *p == 10; };
723*9356374aSAndroid Build Coastguard Worker   bool (*cond_lt_10)(int *) = [](int *p) { return *p < 10; };
724*9356374aSAndroid Build Coastguard Worker 
725*9356374aSAndroid Build Coastguard Worker   std::thread t1([&mu, &n, &done, cond_eq_10]() {
726*9356374aSAndroid Build Coastguard Worker     absl::ReaderMutexLock lock(&mu, absl::Condition(cond_eq_10, &n));
727*9356374aSAndroid Build Coastguard Worker     done = true;
728*9356374aSAndroid Build Coastguard Worker   });
729*9356374aSAndroid Build Coastguard Worker 
730*9356374aSAndroid Build Coastguard Worker   std::thread t2[10];
731*9356374aSAndroid Build Coastguard Worker   for (std::thread &t : t2) {
732*9356374aSAndroid Build Coastguard Worker     t = std::thread([&mu, &n, cond_lt_10]() {
733*9356374aSAndroid Build Coastguard Worker       absl::WriterMutexLock lock(&mu, absl::Condition(cond_lt_10, &n));
734*9356374aSAndroid Build Coastguard Worker       ++n;
735*9356374aSAndroid Build Coastguard Worker     });
736*9356374aSAndroid Build Coastguard Worker   }
737*9356374aSAndroid Build Coastguard Worker 
738*9356374aSAndroid Build Coastguard Worker   {
739*9356374aSAndroid Build Coastguard Worker     absl::MutexLock lock(&mu);
740*9356374aSAndroid Build Coastguard Worker     n = 0;
741*9356374aSAndroid Build Coastguard Worker   }
742*9356374aSAndroid Build Coastguard Worker 
743*9356374aSAndroid Build Coastguard Worker   for (std::thread &t : t2) t.join();
744*9356374aSAndroid Build Coastguard Worker   t1.join();
745*9356374aSAndroid Build Coastguard Worker 
746*9356374aSAndroid Build Coastguard Worker   EXPECT_TRUE(done);
747*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(n, 10);
748*9356374aSAndroid Build Coastguard Worker }
749*9356374aSAndroid Build Coastguard Worker 
750*9356374aSAndroid Build Coastguard Worker // --------------------------------------------------------
751*9356374aSAndroid Build Coastguard Worker // The following test requires Mutex::ReaderLock to be a real shared
752*9356374aSAndroid Build Coastguard Worker // lock, which is not the case in all builds.
753*9356374aSAndroid Build Coastguard Worker #if !defined(ABSL_MUTEX_READER_LOCK_IS_EXCLUSIVE)
754*9356374aSAndroid Build Coastguard Worker 
755*9356374aSAndroid Build Coastguard Worker // Test for fix of bug in UnlockSlow() that incorrectly decremented the reader
756*9356374aSAndroid Build Coastguard Worker // count when putting a thread to sleep waiting for a false condition when the
757*9356374aSAndroid Build Coastguard Worker // lock was not held.
758*9356374aSAndroid Build Coastguard Worker 
759*9356374aSAndroid Build Coastguard Worker // For this bug to strike, we make a thread wait on a free mutex with no
760*9356374aSAndroid Build Coastguard Worker // waiters by causing its wakeup condition to be false.   Then the
761*9356374aSAndroid Build Coastguard Worker // next two acquirers must be readers.   The bug causes the lock
762*9356374aSAndroid Build Coastguard Worker // to be released when one reader unlocks, rather than both.
763*9356374aSAndroid Build Coastguard Worker 
764*9356374aSAndroid Build Coastguard Worker struct ReaderDecrementBugStruct {
765*9356374aSAndroid Build Coastguard Worker   bool cond;  // to delay first thread (under mu)
766*9356374aSAndroid Build Coastguard Worker   int done;   // reference count (under mu)
767*9356374aSAndroid Build Coastguard Worker   absl::Mutex mu;
768*9356374aSAndroid Build Coastguard Worker 
769*9356374aSAndroid Build Coastguard Worker   bool waiting_on_cond;   // under mu2
770*9356374aSAndroid Build Coastguard Worker   bool have_reader_lock;  // under mu2
771*9356374aSAndroid Build Coastguard Worker   bool complete;          // under mu2
772*9356374aSAndroid Build Coastguard Worker   absl::Mutex mu2;        // > mu
773*9356374aSAndroid Build Coastguard Worker };
774*9356374aSAndroid Build Coastguard Worker 
775*9356374aSAndroid Build Coastguard Worker // L >= mu, L < mu_waiting_on_cond
IsCond(void * v)776*9356374aSAndroid Build Coastguard Worker static bool IsCond(void *v) {
777*9356374aSAndroid Build Coastguard Worker   ReaderDecrementBugStruct *x = reinterpret_cast<ReaderDecrementBugStruct *>(v);
778*9356374aSAndroid Build Coastguard Worker   x->mu2.Lock();
779*9356374aSAndroid Build Coastguard Worker   x->waiting_on_cond = true;
780*9356374aSAndroid Build Coastguard Worker   x->mu2.Unlock();
781*9356374aSAndroid Build Coastguard Worker   return x->cond;
782*9356374aSAndroid Build Coastguard Worker }
783*9356374aSAndroid Build Coastguard Worker 
784*9356374aSAndroid Build Coastguard Worker // L >= mu
AllDone(void * v)785*9356374aSAndroid Build Coastguard Worker static bool AllDone(void *v) {
786*9356374aSAndroid Build Coastguard Worker   ReaderDecrementBugStruct *x = reinterpret_cast<ReaderDecrementBugStruct *>(v);
787*9356374aSAndroid Build Coastguard Worker   return x->done == 0;
788*9356374aSAndroid Build Coastguard Worker }
789*9356374aSAndroid Build Coastguard Worker 
790*9356374aSAndroid Build Coastguard Worker // L={}
WaitForCond(ReaderDecrementBugStruct * x)791*9356374aSAndroid Build Coastguard Worker static void WaitForCond(ReaderDecrementBugStruct *x) {
792*9356374aSAndroid Build Coastguard Worker   absl::Mutex dummy;
793*9356374aSAndroid Build Coastguard Worker   absl::MutexLock l(&dummy);
794*9356374aSAndroid Build Coastguard Worker   x->mu.LockWhen(absl::Condition(&IsCond, x));
795*9356374aSAndroid Build Coastguard Worker   x->done--;
796*9356374aSAndroid Build Coastguard Worker   x->mu.Unlock();
797*9356374aSAndroid Build Coastguard Worker }
798*9356374aSAndroid Build Coastguard Worker 
799*9356374aSAndroid Build Coastguard Worker // L={}
GetReadLock(ReaderDecrementBugStruct * x)800*9356374aSAndroid Build Coastguard Worker static void GetReadLock(ReaderDecrementBugStruct *x) {
801*9356374aSAndroid Build Coastguard Worker   x->mu.ReaderLock();
802*9356374aSAndroid Build Coastguard Worker   x->mu2.Lock();
803*9356374aSAndroid Build Coastguard Worker   x->have_reader_lock = true;
804*9356374aSAndroid Build Coastguard Worker   x->mu2.Await(absl::Condition(&x->complete));
805*9356374aSAndroid Build Coastguard Worker   x->mu2.Unlock();
806*9356374aSAndroid Build Coastguard Worker   x->mu.ReaderUnlock();
807*9356374aSAndroid Build Coastguard Worker   x->mu.Lock();
808*9356374aSAndroid Build Coastguard Worker   x->done--;
809*9356374aSAndroid Build Coastguard Worker   x->mu.Unlock();
810*9356374aSAndroid Build Coastguard Worker }
811*9356374aSAndroid Build Coastguard Worker 
812*9356374aSAndroid Build Coastguard Worker // Test for reader counter being decremented incorrectly by waiter
813*9356374aSAndroid Build Coastguard Worker // with false condition.
TEST(Mutex,MutexReaderDecrementBug)814*9356374aSAndroid Build Coastguard Worker TEST(Mutex, MutexReaderDecrementBug) ABSL_NO_THREAD_SAFETY_ANALYSIS {
815*9356374aSAndroid Build Coastguard Worker   ReaderDecrementBugStruct x;
816*9356374aSAndroid Build Coastguard Worker   x.cond = false;
817*9356374aSAndroid Build Coastguard Worker   x.waiting_on_cond = false;
818*9356374aSAndroid Build Coastguard Worker   x.have_reader_lock = false;
819*9356374aSAndroid Build Coastguard Worker   x.complete = false;
820*9356374aSAndroid Build Coastguard Worker   x.done = 2;  // initial ref count
821*9356374aSAndroid Build Coastguard Worker 
822*9356374aSAndroid Build Coastguard Worker   // Run WaitForCond() and wait for it to sleep
823*9356374aSAndroid Build Coastguard Worker   std::thread thread1(WaitForCond, &x);
824*9356374aSAndroid Build Coastguard Worker   x.mu2.LockWhen(absl::Condition(&x.waiting_on_cond));
825*9356374aSAndroid Build Coastguard Worker   x.mu2.Unlock();
826*9356374aSAndroid Build Coastguard Worker 
827*9356374aSAndroid Build Coastguard Worker   // Run GetReadLock(), and wait for it to get the read lock
828*9356374aSAndroid Build Coastguard Worker   std::thread thread2(GetReadLock, &x);
829*9356374aSAndroid Build Coastguard Worker   x.mu2.LockWhen(absl::Condition(&x.have_reader_lock));
830*9356374aSAndroid Build Coastguard Worker   x.mu2.Unlock();
831*9356374aSAndroid Build Coastguard Worker 
832*9356374aSAndroid Build Coastguard Worker   // Get the reader lock ourselves, and release it.
833*9356374aSAndroid Build Coastguard Worker   x.mu.ReaderLock();
834*9356374aSAndroid Build Coastguard Worker   x.mu.ReaderUnlock();
835*9356374aSAndroid Build Coastguard Worker 
836*9356374aSAndroid Build Coastguard Worker   // The lock should be held in read mode by GetReadLock().
837*9356374aSAndroid Build Coastguard Worker   // If we have the bug, the lock will be free.
838*9356374aSAndroid Build Coastguard Worker   x.mu.AssertReaderHeld();
839*9356374aSAndroid Build Coastguard Worker 
840*9356374aSAndroid Build Coastguard Worker   // Wake up all the threads.
841*9356374aSAndroid Build Coastguard Worker   x.mu2.Lock();
842*9356374aSAndroid Build Coastguard Worker   x.complete = true;
843*9356374aSAndroid Build Coastguard Worker   x.mu2.Unlock();
844*9356374aSAndroid Build Coastguard Worker 
845*9356374aSAndroid Build Coastguard Worker   // TODO(delesley): turn on analysis once lock upgrading is supported.
846*9356374aSAndroid Build Coastguard Worker   // (This call upgrades the lock from shared to exclusive.)
847*9356374aSAndroid Build Coastguard Worker   x.mu.Lock();
848*9356374aSAndroid Build Coastguard Worker   x.cond = true;
849*9356374aSAndroid Build Coastguard Worker   x.mu.Await(absl::Condition(&AllDone, &x));
850*9356374aSAndroid Build Coastguard Worker   x.mu.Unlock();
851*9356374aSAndroid Build Coastguard Worker 
852*9356374aSAndroid Build Coastguard Worker   thread1.join();
853*9356374aSAndroid Build Coastguard Worker   thread2.join();
854*9356374aSAndroid Build Coastguard Worker }
855*9356374aSAndroid Build Coastguard Worker #endif  // !ABSL_MUTEX_READER_LOCK_IS_EXCLUSIVE
856*9356374aSAndroid Build Coastguard Worker 
857*9356374aSAndroid Build Coastguard Worker // Test that we correctly handle the situation when a lock is
858*9356374aSAndroid Build Coastguard Worker // held and then destroyed (w/o unlocking).
859*9356374aSAndroid Build Coastguard Worker #ifdef ABSL_HAVE_THREAD_SANITIZER
860*9356374aSAndroid Build Coastguard Worker // TSAN reports errors when locked Mutexes are destroyed.
TEST(Mutex,DISABLED_LockedMutexDestructionBug)861*9356374aSAndroid Build Coastguard Worker TEST(Mutex, DISABLED_LockedMutexDestructionBug) ABSL_NO_THREAD_SAFETY_ANALYSIS {
862*9356374aSAndroid Build Coastguard Worker #else
863*9356374aSAndroid Build Coastguard Worker TEST(Mutex, LockedMutexDestructionBug) ABSL_NO_THREAD_SAFETY_ANALYSIS {
864*9356374aSAndroid Build Coastguard Worker #endif
865*9356374aSAndroid Build Coastguard Worker   for (int i = 0; i != 10; i++) {
866*9356374aSAndroid Build Coastguard Worker     // Create, lock and destroy 10 locks.
867*9356374aSAndroid Build Coastguard Worker     const int kNumLocks = 10;
868*9356374aSAndroid Build Coastguard Worker     auto mu = absl::make_unique<absl::Mutex[]>(kNumLocks);
869*9356374aSAndroid Build Coastguard Worker     for (int j = 0; j != kNumLocks; j++) {
870*9356374aSAndroid Build Coastguard Worker       if ((j % 2) == 0) {
871*9356374aSAndroid Build Coastguard Worker         mu[j].WriterLock();
872*9356374aSAndroid Build Coastguard Worker       } else {
873*9356374aSAndroid Build Coastguard Worker         mu[j].ReaderLock();
874*9356374aSAndroid Build Coastguard Worker       }
875*9356374aSAndroid Build Coastguard Worker     }
876*9356374aSAndroid Build Coastguard Worker   }
877*9356374aSAndroid Build Coastguard Worker }
878*9356374aSAndroid Build Coastguard Worker 
879*9356374aSAndroid Build Coastguard Worker // Some functions taking pointers to non-const.
880*9356374aSAndroid Build Coastguard Worker bool Equals42(int *p) { return *p == 42; }
881*9356374aSAndroid Build Coastguard Worker bool Equals43(int *p) { return *p == 43; }
882*9356374aSAndroid Build Coastguard Worker 
883*9356374aSAndroid Build Coastguard Worker // Some functions taking pointers to const.
884*9356374aSAndroid Build Coastguard Worker bool ConstEquals42(const int *p) { return *p == 42; }
885*9356374aSAndroid Build Coastguard Worker bool ConstEquals43(const int *p) { return *p == 43; }
886*9356374aSAndroid Build Coastguard Worker 
887*9356374aSAndroid Build Coastguard Worker // Some function templates taking pointers. Note it's possible for `T` to be
888*9356374aSAndroid Build Coastguard Worker // deduced as non-const or const, which creates the potential for ambiguity,
889*9356374aSAndroid Build Coastguard Worker // but which the implementation is careful to avoid.
890*9356374aSAndroid Build Coastguard Worker template <typename T>
891*9356374aSAndroid Build Coastguard Worker bool TemplateEquals42(T *p) {
892*9356374aSAndroid Build Coastguard Worker   return *p == 42;
893*9356374aSAndroid Build Coastguard Worker }
894*9356374aSAndroid Build Coastguard Worker template <typename T>
895*9356374aSAndroid Build Coastguard Worker bool TemplateEquals43(T *p) {
896*9356374aSAndroid Build Coastguard Worker   return *p == 43;
897*9356374aSAndroid Build Coastguard Worker }
898*9356374aSAndroid Build Coastguard Worker 
899*9356374aSAndroid Build Coastguard Worker TEST(Mutex, FunctionPointerCondition) {
900*9356374aSAndroid Build Coastguard Worker   // Some arguments.
901*9356374aSAndroid Build Coastguard Worker   int x = 42;
902*9356374aSAndroid Build Coastguard Worker   const int const_x = 42;
903*9356374aSAndroid Build Coastguard Worker 
904*9356374aSAndroid Build Coastguard Worker   // Parameter non-const, argument non-const.
905*9356374aSAndroid Build Coastguard Worker   EXPECT_TRUE(absl::Condition(Equals42, &x).Eval());
906*9356374aSAndroid Build Coastguard Worker   EXPECT_FALSE(absl::Condition(Equals43, &x).Eval());
907*9356374aSAndroid Build Coastguard Worker 
908*9356374aSAndroid Build Coastguard Worker   // Parameter const, argument non-const.
909*9356374aSAndroid Build Coastguard Worker   EXPECT_TRUE(absl::Condition(ConstEquals42, &x).Eval());
910*9356374aSAndroid Build Coastguard Worker   EXPECT_FALSE(absl::Condition(ConstEquals43, &x).Eval());
911*9356374aSAndroid Build Coastguard Worker 
912*9356374aSAndroid Build Coastguard Worker   // Parameter const, argument const.
913*9356374aSAndroid Build Coastguard Worker   EXPECT_TRUE(absl::Condition(ConstEquals42, &const_x).Eval());
914*9356374aSAndroid Build Coastguard Worker   EXPECT_FALSE(absl::Condition(ConstEquals43, &const_x).Eval());
915*9356374aSAndroid Build Coastguard Worker 
916*9356374aSAndroid Build Coastguard Worker   // Parameter type deduced, argument non-const.
917*9356374aSAndroid Build Coastguard Worker   EXPECT_TRUE(absl::Condition(TemplateEquals42, &x).Eval());
918*9356374aSAndroid Build Coastguard Worker   EXPECT_FALSE(absl::Condition(TemplateEquals43, &x).Eval());
919*9356374aSAndroid Build Coastguard Worker 
920*9356374aSAndroid Build Coastguard Worker   // Parameter type deduced, argument const.
921*9356374aSAndroid Build Coastguard Worker   EXPECT_TRUE(absl::Condition(TemplateEquals42, &const_x).Eval());
922*9356374aSAndroid Build Coastguard Worker   EXPECT_FALSE(absl::Condition(TemplateEquals43, &const_x).Eval());
923*9356374aSAndroid Build Coastguard Worker 
924*9356374aSAndroid Build Coastguard Worker   // Parameter non-const, argument const is not well-formed.
925*9356374aSAndroid Build Coastguard Worker   EXPECT_FALSE((std::is_constructible<absl::Condition, decltype(Equals42),
926*9356374aSAndroid Build Coastguard Worker                                       decltype(&const_x)>::value));
927*9356374aSAndroid Build Coastguard Worker   // Validate use of is_constructible by contrasting to a well-formed case.
928*9356374aSAndroid Build Coastguard Worker   EXPECT_TRUE((std::is_constructible<absl::Condition, decltype(ConstEquals42),
929*9356374aSAndroid Build Coastguard Worker                                      decltype(&const_x)>::value));
930*9356374aSAndroid Build Coastguard Worker }
931*9356374aSAndroid Build Coastguard Worker 
932*9356374aSAndroid Build Coastguard Worker // Example base and derived class for use in predicates and test below. Not a
933*9356374aSAndroid Build Coastguard Worker // particularly realistic example, but it suffices for testing purposes.
934*9356374aSAndroid Build Coastguard Worker struct Base {
935*9356374aSAndroid Build Coastguard Worker   explicit Base(int v) : value(v) {}
936*9356374aSAndroid Build Coastguard Worker   int value;
937*9356374aSAndroid Build Coastguard Worker };
938*9356374aSAndroid Build Coastguard Worker struct Derived : Base {
939*9356374aSAndroid Build Coastguard Worker   explicit Derived(int v) : Base(v) {}
940*9356374aSAndroid Build Coastguard Worker };
941*9356374aSAndroid Build Coastguard Worker 
942*9356374aSAndroid Build Coastguard Worker // Some functions taking pointer to non-const `Base`.
943*9356374aSAndroid Build Coastguard Worker bool BaseEquals42(Base *p) { return p->value == 42; }
944*9356374aSAndroid Build Coastguard Worker bool BaseEquals43(Base *p) { return p->value == 43; }
945*9356374aSAndroid Build Coastguard Worker 
946*9356374aSAndroid Build Coastguard Worker // Some functions taking pointer to const `Base`.
947*9356374aSAndroid Build Coastguard Worker bool ConstBaseEquals42(const Base *p) { return p->value == 42; }
948*9356374aSAndroid Build Coastguard Worker bool ConstBaseEquals43(const Base *p) { return p->value == 43; }
949*9356374aSAndroid Build Coastguard Worker 
950*9356374aSAndroid Build Coastguard Worker TEST(Mutex, FunctionPointerConditionWithDerivedToBaseConversion) {
951*9356374aSAndroid Build Coastguard Worker   // Some arguments.
952*9356374aSAndroid Build Coastguard Worker   Derived derived(42);
953*9356374aSAndroid Build Coastguard Worker   const Derived const_derived(42);
954*9356374aSAndroid Build Coastguard Worker 
955*9356374aSAndroid Build Coastguard Worker   // Parameter non-const base, argument derived non-const.
956*9356374aSAndroid Build Coastguard Worker   EXPECT_TRUE(absl::Condition(BaseEquals42, &derived).Eval());
957*9356374aSAndroid Build Coastguard Worker   EXPECT_FALSE(absl::Condition(BaseEquals43, &derived).Eval());
958*9356374aSAndroid Build Coastguard Worker 
959*9356374aSAndroid Build Coastguard Worker   // Parameter const base, argument derived non-const.
960*9356374aSAndroid Build Coastguard Worker   EXPECT_TRUE(absl::Condition(ConstBaseEquals42, &derived).Eval());
961*9356374aSAndroid Build Coastguard Worker   EXPECT_FALSE(absl::Condition(ConstBaseEquals43, &derived).Eval());
962*9356374aSAndroid Build Coastguard Worker 
963*9356374aSAndroid Build Coastguard Worker   // Parameter const base, argument derived const.
964*9356374aSAndroid Build Coastguard Worker   EXPECT_TRUE(absl::Condition(ConstBaseEquals42, &const_derived).Eval());
965*9356374aSAndroid Build Coastguard Worker   EXPECT_FALSE(absl::Condition(ConstBaseEquals43, &const_derived).Eval());
966*9356374aSAndroid Build Coastguard Worker 
967*9356374aSAndroid Build Coastguard Worker   // Parameter const base, argument derived const.
968*9356374aSAndroid Build Coastguard Worker   EXPECT_TRUE(absl::Condition(ConstBaseEquals42, &const_derived).Eval());
969*9356374aSAndroid Build Coastguard Worker   EXPECT_FALSE(absl::Condition(ConstBaseEquals43, &const_derived).Eval());
970*9356374aSAndroid Build Coastguard Worker 
971*9356374aSAndroid Build Coastguard Worker   // Parameter derived, argument base is not well-formed.
972*9356374aSAndroid Build Coastguard Worker   bool (*derived_pred)(const Derived *) = [](const Derived *) { return true; };
973*9356374aSAndroid Build Coastguard Worker   EXPECT_FALSE((std::is_constructible<absl::Condition, decltype(derived_pred),
974*9356374aSAndroid Build Coastguard Worker                                       Base *>::value));
975*9356374aSAndroid Build Coastguard Worker   EXPECT_FALSE((std::is_constructible<absl::Condition, decltype(derived_pred),
976*9356374aSAndroid Build Coastguard Worker                                       const Base *>::value));
977*9356374aSAndroid Build Coastguard Worker   // Validate use of is_constructible by contrasting to well-formed cases.
978*9356374aSAndroid Build Coastguard Worker   EXPECT_TRUE((std::is_constructible<absl::Condition, decltype(derived_pred),
979*9356374aSAndroid Build Coastguard Worker                                      Derived *>::value));
980*9356374aSAndroid Build Coastguard Worker   EXPECT_TRUE((std::is_constructible<absl::Condition, decltype(derived_pred),
981*9356374aSAndroid Build Coastguard Worker                                      const Derived *>::value));
982*9356374aSAndroid Build Coastguard Worker }
983*9356374aSAndroid Build Coastguard Worker 
984*9356374aSAndroid Build Coastguard Worker struct Constable {
985*9356374aSAndroid Build Coastguard Worker   bool WotsAllThisThen() const { return true; }
986*9356374aSAndroid Build Coastguard Worker };
987*9356374aSAndroid Build Coastguard Worker 
988*9356374aSAndroid Build Coastguard Worker TEST(Mutex, FunctionPointerConditionWithConstMethod) {
989*9356374aSAndroid Build Coastguard Worker   const Constable chapman;
990*9356374aSAndroid Build Coastguard Worker   EXPECT_TRUE(absl::Condition(&chapman, &Constable::WotsAllThisThen).Eval());
991*9356374aSAndroid Build Coastguard Worker }
992*9356374aSAndroid Build Coastguard Worker 
993*9356374aSAndroid Build Coastguard Worker struct True {
994*9356374aSAndroid Build Coastguard Worker   template <class... Args>
995*9356374aSAndroid Build Coastguard Worker   bool operator()(Args...) const {
996*9356374aSAndroid Build Coastguard Worker     return true;
997*9356374aSAndroid Build Coastguard Worker   }
998*9356374aSAndroid Build Coastguard Worker };
999*9356374aSAndroid Build Coastguard Worker 
1000*9356374aSAndroid Build Coastguard Worker struct DerivedTrue : True {};
1001*9356374aSAndroid Build Coastguard Worker 
1002*9356374aSAndroid Build Coastguard Worker TEST(Mutex, FunctorCondition) {
1003*9356374aSAndroid Build Coastguard Worker   {  // Variadic
1004*9356374aSAndroid Build Coastguard Worker     True f;
1005*9356374aSAndroid Build Coastguard Worker     EXPECT_TRUE(absl::Condition(&f).Eval());
1006*9356374aSAndroid Build Coastguard Worker   }
1007*9356374aSAndroid Build Coastguard Worker 
1008*9356374aSAndroid Build Coastguard Worker   {  // Inherited
1009*9356374aSAndroid Build Coastguard Worker     DerivedTrue g;
1010*9356374aSAndroid Build Coastguard Worker     EXPECT_TRUE(absl::Condition(&g).Eval());
1011*9356374aSAndroid Build Coastguard Worker   }
1012*9356374aSAndroid Build Coastguard Worker 
1013*9356374aSAndroid Build Coastguard Worker   {  // lambda
1014*9356374aSAndroid Build Coastguard Worker     int value = 3;
1015*9356374aSAndroid Build Coastguard Worker     auto is_zero = [&value] { return value == 0; };
1016*9356374aSAndroid Build Coastguard Worker     absl::Condition c(&is_zero);
1017*9356374aSAndroid Build Coastguard Worker     EXPECT_FALSE(c.Eval());
1018*9356374aSAndroid Build Coastguard Worker     value = 0;
1019*9356374aSAndroid Build Coastguard Worker     EXPECT_TRUE(c.Eval());
1020*9356374aSAndroid Build Coastguard Worker   }
1021*9356374aSAndroid Build Coastguard Worker 
1022*9356374aSAndroid Build Coastguard Worker   {  // bind
1023*9356374aSAndroid Build Coastguard Worker     int value = 0;
1024*9356374aSAndroid Build Coastguard Worker     auto is_positive = std::bind(std::less<int>(), 0, std::cref(value));
1025*9356374aSAndroid Build Coastguard Worker     absl::Condition c(&is_positive);
1026*9356374aSAndroid Build Coastguard Worker     EXPECT_FALSE(c.Eval());
1027*9356374aSAndroid Build Coastguard Worker     value = 1;
1028*9356374aSAndroid Build Coastguard Worker     EXPECT_TRUE(c.Eval());
1029*9356374aSAndroid Build Coastguard Worker   }
1030*9356374aSAndroid Build Coastguard Worker 
1031*9356374aSAndroid Build Coastguard Worker   {  // std::function
1032*9356374aSAndroid Build Coastguard Worker     int value = 3;
1033*9356374aSAndroid Build Coastguard Worker     std::function<bool()> is_zero = [&value] { return value == 0; };
1034*9356374aSAndroid Build Coastguard Worker     absl::Condition c(&is_zero);
1035*9356374aSAndroid Build Coastguard Worker     EXPECT_FALSE(c.Eval());
1036*9356374aSAndroid Build Coastguard Worker     value = 0;
1037*9356374aSAndroid Build Coastguard Worker     EXPECT_TRUE(c.Eval());
1038*9356374aSAndroid Build Coastguard Worker   }
1039*9356374aSAndroid Build Coastguard Worker }
1040*9356374aSAndroid Build Coastguard Worker 
1041*9356374aSAndroid Build Coastguard Worker TEST(Mutex, ConditionSwap) {
1042*9356374aSAndroid Build Coastguard Worker   // Ensure that Conditions can be swap'ed.
1043*9356374aSAndroid Build Coastguard Worker   bool b1 = true;
1044*9356374aSAndroid Build Coastguard Worker   absl::Condition c1(&b1);
1045*9356374aSAndroid Build Coastguard Worker   bool b2 = false;
1046*9356374aSAndroid Build Coastguard Worker   absl::Condition c2(&b2);
1047*9356374aSAndroid Build Coastguard Worker   EXPECT_TRUE(c1.Eval());
1048*9356374aSAndroid Build Coastguard Worker   EXPECT_FALSE(c2.Eval());
1049*9356374aSAndroid Build Coastguard Worker   std::swap(c1, c2);
1050*9356374aSAndroid Build Coastguard Worker   EXPECT_FALSE(c1.Eval());
1051*9356374aSAndroid Build Coastguard Worker   EXPECT_TRUE(c2.Eval());
1052*9356374aSAndroid Build Coastguard Worker }
1053*9356374aSAndroid Build Coastguard Worker 
1054*9356374aSAndroid Build Coastguard Worker // --------------------------------------------------------
1055*9356374aSAndroid Build Coastguard Worker // Test for bug with pattern of readers using a condvar.  The bug was that if a
1056*9356374aSAndroid Build Coastguard Worker // reader went to sleep on a condition variable while one or more other readers
1057*9356374aSAndroid Build Coastguard Worker // held the lock, but there were no waiters, the reader count (held in the
1058*9356374aSAndroid Build Coastguard Worker // mutex word) would be lost.  (This is because Enqueue() had at one time
1059*9356374aSAndroid Build Coastguard Worker // always placed the thread on the Mutex queue.  Later (CL 4075610), to
1060*9356374aSAndroid Build Coastguard Worker // tolerate re-entry into Mutex from a Condition predicate, Enqueue() was
1061*9356374aSAndroid Build Coastguard Worker // changed so that it could also place a thread on a condition-variable.  This
1062*9356374aSAndroid Build Coastguard Worker // introduced the case where Enqueue() returned with an empty queue, and this
1063*9356374aSAndroid Build Coastguard Worker // case was handled incorrectly in one place.)
1064*9356374aSAndroid Build Coastguard Worker 
1065*9356374aSAndroid Build Coastguard Worker static void ReaderForReaderOnCondVar(absl::Mutex *mu, absl::CondVar *cv,
1066*9356374aSAndroid Build Coastguard Worker                                      int *running) {
1067*9356374aSAndroid Build Coastguard Worker   std::random_device dev;
1068*9356374aSAndroid Build Coastguard Worker   std::mt19937 gen(dev());
1069*9356374aSAndroid Build Coastguard Worker   std::uniform_int_distribution<int> random_millis(0, 15);
1070*9356374aSAndroid Build Coastguard Worker   mu->ReaderLock();
1071*9356374aSAndroid Build Coastguard Worker   while (*running == 3) {
1072*9356374aSAndroid Build Coastguard Worker     absl::SleepFor(absl::Milliseconds(random_millis(gen)));
1073*9356374aSAndroid Build Coastguard Worker     cv->WaitWithTimeout(mu, absl::Milliseconds(random_millis(gen)));
1074*9356374aSAndroid Build Coastguard Worker   }
1075*9356374aSAndroid Build Coastguard Worker   mu->ReaderUnlock();
1076*9356374aSAndroid Build Coastguard Worker   mu->Lock();
1077*9356374aSAndroid Build Coastguard Worker   (*running)--;
1078*9356374aSAndroid Build Coastguard Worker   mu->Unlock();
1079*9356374aSAndroid Build Coastguard Worker }
1080*9356374aSAndroid Build Coastguard Worker 
1081*9356374aSAndroid Build Coastguard Worker static bool IntIsZero(int *x) { return *x == 0; }
1082*9356374aSAndroid Build Coastguard Worker 
1083*9356374aSAndroid Build Coastguard Worker // Test for reader waiting condition variable when there are other readers
1084*9356374aSAndroid Build Coastguard Worker // but no waiters.
1085*9356374aSAndroid Build Coastguard Worker TEST(Mutex, TestReaderOnCondVar) {
1086*9356374aSAndroid Build Coastguard Worker   auto tp = CreateDefaultPool();
1087*9356374aSAndroid Build Coastguard Worker   absl::Mutex mu;
1088*9356374aSAndroid Build Coastguard Worker   absl::CondVar cv;
1089*9356374aSAndroid Build Coastguard Worker   int running = 3;
1090*9356374aSAndroid Build Coastguard Worker   tp->Schedule(std::bind(&ReaderForReaderOnCondVar, &mu, &cv, &running));
1091*9356374aSAndroid Build Coastguard Worker   tp->Schedule(std::bind(&ReaderForReaderOnCondVar, &mu, &cv, &running));
1092*9356374aSAndroid Build Coastguard Worker   absl::SleepFor(absl::Seconds(2));
1093*9356374aSAndroid Build Coastguard Worker   mu.Lock();
1094*9356374aSAndroid Build Coastguard Worker   running--;
1095*9356374aSAndroid Build Coastguard Worker   mu.Await(absl::Condition(&IntIsZero, &running));
1096*9356374aSAndroid Build Coastguard Worker   mu.Unlock();
1097*9356374aSAndroid Build Coastguard Worker }
1098*9356374aSAndroid Build Coastguard Worker 
1099*9356374aSAndroid Build Coastguard Worker // --------------------------------------------------------
1100*9356374aSAndroid Build Coastguard Worker struct AcquireFromConditionStruct {
1101*9356374aSAndroid Build Coastguard Worker   absl::Mutex mu0;   // protects value, done
1102*9356374aSAndroid Build Coastguard Worker   int value;         // times condition function is called; under mu0,
1103*9356374aSAndroid Build Coastguard Worker   bool done;         // done with test?  under mu0
1104*9356374aSAndroid Build Coastguard Worker   absl::Mutex mu1;   // used to attempt to mess up state of mu0
1105*9356374aSAndroid Build Coastguard Worker   absl::CondVar cv;  // so the condition function can be invoked from
1106*9356374aSAndroid Build Coastguard Worker                      // CondVar::Wait().
1107*9356374aSAndroid Build Coastguard Worker };
1108*9356374aSAndroid Build Coastguard Worker 
1109*9356374aSAndroid Build Coastguard Worker static bool ConditionWithAcquire(AcquireFromConditionStruct *x) {
1110*9356374aSAndroid Build Coastguard Worker   x->value++;  // count times this function is called
1111*9356374aSAndroid Build Coastguard Worker 
1112*9356374aSAndroid Build Coastguard Worker   if (x->value == 2 || x->value == 3) {
1113*9356374aSAndroid Build Coastguard Worker     // On the second and third invocation of this function, sleep for 100ms,
1114*9356374aSAndroid Build Coastguard Worker     // but with the side-effect of altering the state of a Mutex other than
1115*9356374aSAndroid Build Coastguard Worker     // than one for which this is a condition.  The spec now explicitly allows
1116*9356374aSAndroid Build Coastguard Worker     // this side effect; previously it did not.  it was illegal.
1117*9356374aSAndroid Build Coastguard Worker     bool always_false = false;
1118*9356374aSAndroid Build Coastguard Worker     x->mu1.LockWhenWithTimeout(absl::Condition(&always_false),
1119*9356374aSAndroid Build Coastguard Worker                                absl::Milliseconds(100));
1120*9356374aSAndroid Build Coastguard Worker     x->mu1.Unlock();
1121*9356374aSAndroid Build Coastguard Worker   }
1122*9356374aSAndroid Build Coastguard Worker   CHECK_LT(x->value, 4) << "should not be invoked a fourth time";
1123*9356374aSAndroid Build Coastguard Worker 
1124*9356374aSAndroid Build Coastguard Worker   // We arrange for the condition to return true on only the 2nd and 3rd calls.
1125*9356374aSAndroid Build Coastguard Worker   return x->value == 2 || x->value == 3;
1126*9356374aSAndroid Build Coastguard Worker }
1127*9356374aSAndroid Build Coastguard Worker 
1128*9356374aSAndroid Build Coastguard Worker static void WaitForCond2(AcquireFromConditionStruct *x) {
1129*9356374aSAndroid Build Coastguard Worker   // wait for cond0 to become true
1130*9356374aSAndroid Build Coastguard Worker   x->mu0.LockWhen(absl::Condition(&ConditionWithAcquire, x));
1131*9356374aSAndroid Build Coastguard Worker   x->done = true;
1132*9356374aSAndroid Build Coastguard Worker   x->mu0.Unlock();
1133*9356374aSAndroid Build Coastguard Worker }
1134*9356374aSAndroid Build Coastguard Worker 
1135*9356374aSAndroid Build Coastguard Worker // Test for Condition whose function acquires other Mutexes
1136*9356374aSAndroid Build Coastguard Worker TEST(Mutex, AcquireFromCondition) {
1137*9356374aSAndroid Build Coastguard Worker   auto tp = CreateDefaultPool();
1138*9356374aSAndroid Build Coastguard Worker 
1139*9356374aSAndroid Build Coastguard Worker   AcquireFromConditionStruct x;
1140*9356374aSAndroid Build Coastguard Worker   x.value = 0;
1141*9356374aSAndroid Build Coastguard Worker   x.done = false;
1142*9356374aSAndroid Build Coastguard Worker   tp->Schedule(
1143*9356374aSAndroid Build Coastguard Worker       std::bind(&WaitForCond2, &x));  // run WaitForCond2() in a thread T
1144*9356374aSAndroid Build Coastguard Worker   // T will hang because the first invocation of ConditionWithAcquire() will
1145*9356374aSAndroid Build Coastguard Worker   // return false.
1146*9356374aSAndroid Build Coastguard Worker   absl::SleepFor(absl::Milliseconds(500));  // allow T time to hang
1147*9356374aSAndroid Build Coastguard Worker 
1148*9356374aSAndroid Build Coastguard Worker   x.mu0.Lock();
1149*9356374aSAndroid Build Coastguard Worker   x.cv.WaitWithTimeout(&x.mu0, absl::Milliseconds(500));  // wake T
1150*9356374aSAndroid Build Coastguard Worker   // T will be woken because the Wait() will call ConditionWithAcquire()
1151*9356374aSAndroid Build Coastguard Worker   // for the second time, and it will return true.
1152*9356374aSAndroid Build Coastguard Worker 
1153*9356374aSAndroid Build Coastguard Worker   x.mu0.Unlock();
1154*9356374aSAndroid Build Coastguard Worker 
1155*9356374aSAndroid Build Coastguard Worker   // T will then acquire the lock and recheck its own condition.
1156*9356374aSAndroid Build Coastguard Worker   // It will find the condition true, as this is the third invocation,
1157*9356374aSAndroid Build Coastguard Worker   // but the use of another Mutex by the calling function will
1158*9356374aSAndroid Build Coastguard Worker   // cause the old mutex implementation to think that the outer
1159*9356374aSAndroid Build Coastguard Worker   // LockWhen() has timed out because the inner LockWhenWithTimeout() did.
1160*9356374aSAndroid Build Coastguard Worker   // T will then check the condition a fourth time because it finds a
1161*9356374aSAndroid Build Coastguard Worker   // timeout occurred.  This should not happen in the new
1162*9356374aSAndroid Build Coastguard Worker   // implementation that allows the Condition function to use Mutexes.
1163*9356374aSAndroid Build Coastguard Worker 
1164*9356374aSAndroid Build Coastguard Worker   // It should also succeed, even though the Condition function
1165*9356374aSAndroid Build Coastguard Worker   // is being invoked from CondVar::Wait, and thus this thread
1166*9356374aSAndroid Build Coastguard Worker   // is conceptually waiting both on the condition variable, and on mu2.
1167*9356374aSAndroid Build Coastguard Worker 
1168*9356374aSAndroid Build Coastguard Worker   x.mu0.LockWhen(absl::Condition(&x.done));
1169*9356374aSAndroid Build Coastguard Worker   x.mu0.Unlock();
1170*9356374aSAndroid Build Coastguard Worker }
1171*9356374aSAndroid Build Coastguard Worker 
1172*9356374aSAndroid Build Coastguard Worker TEST(Mutex, DeadlockDetector) {
1173*9356374aSAndroid Build Coastguard Worker   absl::SetMutexDeadlockDetectionMode(absl::OnDeadlockCycle::kAbort);
1174*9356374aSAndroid Build Coastguard Worker 
1175*9356374aSAndroid Build Coastguard Worker   // check that we can call ForgetDeadlockInfo() on a lock with the lock held
1176*9356374aSAndroid Build Coastguard Worker   absl::Mutex m1;
1177*9356374aSAndroid Build Coastguard Worker   absl::Mutex m2;
1178*9356374aSAndroid Build Coastguard Worker   absl::Mutex m3;
1179*9356374aSAndroid Build Coastguard Worker   absl::Mutex m4;
1180*9356374aSAndroid Build Coastguard Worker 
1181*9356374aSAndroid Build Coastguard Worker   m1.Lock();  // m1 gets ID1
1182*9356374aSAndroid Build Coastguard Worker   m2.Lock();  // m2 gets ID2
1183*9356374aSAndroid Build Coastguard Worker   m3.Lock();  // m3 gets ID3
1184*9356374aSAndroid Build Coastguard Worker   m3.Unlock();
1185*9356374aSAndroid Build Coastguard Worker   m2.Unlock();
1186*9356374aSAndroid Build Coastguard Worker   // m1 still held
1187*9356374aSAndroid Build Coastguard Worker   m1.ForgetDeadlockInfo();  // m1 loses ID
1188*9356374aSAndroid Build Coastguard Worker   m2.Lock();                // m2 gets ID2
1189*9356374aSAndroid Build Coastguard Worker   m3.Lock();                // m3 gets ID3
1190*9356374aSAndroid Build Coastguard Worker   m4.Lock();                // m4 gets ID4
1191*9356374aSAndroid Build Coastguard Worker   m3.Unlock();
1192*9356374aSAndroid Build Coastguard Worker   m2.Unlock();
1193*9356374aSAndroid Build Coastguard Worker   m4.Unlock();
1194*9356374aSAndroid Build Coastguard Worker   m1.Unlock();
1195*9356374aSAndroid Build Coastguard Worker }
1196*9356374aSAndroid Build Coastguard Worker 
1197*9356374aSAndroid Build Coastguard Worker // Bazel has a test "warning" file that programs can write to if the
1198*9356374aSAndroid Build Coastguard Worker // test should pass with a warning.  This class disables the warning
1199*9356374aSAndroid Build Coastguard Worker // file until it goes out of scope.
1200*9356374aSAndroid Build Coastguard Worker class ScopedDisableBazelTestWarnings {
1201*9356374aSAndroid Build Coastguard Worker  public:
1202*9356374aSAndroid Build Coastguard Worker   ScopedDisableBazelTestWarnings() {
1203*9356374aSAndroid Build Coastguard Worker #ifdef _WIN32
1204*9356374aSAndroid Build Coastguard Worker     char file[MAX_PATH];
1205*9356374aSAndroid Build Coastguard Worker     if (GetEnvironmentVariableA(kVarName, file, sizeof(file)) < sizeof(file)) {
1206*9356374aSAndroid Build Coastguard Worker       warnings_output_file_ = file;
1207*9356374aSAndroid Build Coastguard Worker       SetEnvironmentVariableA(kVarName, nullptr);
1208*9356374aSAndroid Build Coastguard Worker     }
1209*9356374aSAndroid Build Coastguard Worker #else
1210*9356374aSAndroid Build Coastguard Worker     const char *file = getenv(kVarName);
1211*9356374aSAndroid Build Coastguard Worker     if (file != nullptr) {
1212*9356374aSAndroid Build Coastguard Worker       warnings_output_file_ = file;
1213*9356374aSAndroid Build Coastguard Worker       unsetenv(kVarName);
1214*9356374aSAndroid Build Coastguard Worker     }
1215*9356374aSAndroid Build Coastguard Worker #endif
1216*9356374aSAndroid Build Coastguard Worker   }
1217*9356374aSAndroid Build Coastguard Worker 
1218*9356374aSAndroid Build Coastguard Worker   ~ScopedDisableBazelTestWarnings() {
1219*9356374aSAndroid Build Coastguard Worker     if (!warnings_output_file_.empty()) {
1220*9356374aSAndroid Build Coastguard Worker #ifdef _WIN32
1221*9356374aSAndroid Build Coastguard Worker       SetEnvironmentVariableA(kVarName, warnings_output_file_.c_str());
1222*9356374aSAndroid Build Coastguard Worker #else
1223*9356374aSAndroid Build Coastguard Worker       setenv(kVarName, warnings_output_file_.c_str(), 0);
1224*9356374aSAndroid Build Coastguard Worker #endif
1225*9356374aSAndroid Build Coastguard Worker     }
1226*9356374aSAndroid Build Coastguard Worker   }
1227*9356374aSAndroid Build Coastguard Worker 
1228*9356374aSAndroid Build Coastguard Worker  private:
1229*9356374aSAndroid Build Coastguard Worker   static const char kVarName[];
1230*9356374aSAndroid Build Coastguard Worker   std::string warnings_output_file_;
1231*9356374aSAndroid Build Coastguard Worker };
1232*9356374aSAndroid Build Coastguard Worker const char ScopedDisableBazelTestWarnings::kVarName[] =
1233*9356374aSAndroid Build Coastguard Worker     "TEST_WARNINGS_OUTPUT_FILE";
1234*9356374aSAndroid Build Coastguard Worker 
1235*9356374aSAndroid Build Coastguard Worker #ifdef ABSL_HAVE_THREAD_SANITIZER
1236*9356374aSAndroid Build Coastguard Worker // This test intentionally creates deadlocks to test the deadlock detector.
1237*9356374aSAndroid Build Coastguard Worker TEST(Mutex, DISABLED_DeadlockDetectorBazelWarning) {
1238*9356374aSAndroid Build Coastguard Worker #else
1239*9356374aSAndroid Build Coastguard Worker TEST(Mutex, DeadlockDetectorBazelWarning) {
1240*9356374aSAndroid Build Coastguard Worker #endif
1241*9356374aSAndroid Build Coastguard Worker   absl::SetMutexDeadlockDetectionMode(absl::OnDeadlockCycle::kReport);
1242*9356374aSAndroid Build Coastguard Worker 
1243*9356374aSAndroid Build Coastguard Worker   // Cause deadlock detection to detect something, if it's
1244*9356374aSAndroid Build Coastguard Worker   // compiled in and enabled.  But turn off the bazel warning.
1245*9356374aSAndroid Build Coastguard Worker   ScopedDisableBazelTestWarnings disable_bazel_test_warnings;
1246*9356374aSAndroid Build Coastguard Worker 
1247*9356374aSAndroid Build Coastguard Worker   absl::Mutex mu0;
1248*9356374aSAndroid Build Coastguard Worker   absl::Mutex mu1;
1249*9356374aSAndroid Build Coastguard Worker   bool got_mu0 = mu0.TryLock();
1250*9356374aSAndroid Build Coastguard Worker   mu1.Lock();  // acquire mu1 while holding mu0
1251*9356374aSAndroid Build Coastguard Worker   if (got_mu0) {
1252*9356374aSAndroid Build Coastguard Worker     mu0.Unlock();
1253*9356374aSAndroid Build Coastguard Worker   }
1254*9356374aSAndroid Build Coastguard Worker   if (mu0.TryLock()) {  // try lock shouldn't cause deadlock detector to fire
1255*9356374aSAndroid Build Coastguard Worker     mu0.Unlock();
1256*9356374aSAndroid Build Coastguard Worker   }
1257*9356374aSAndroid Build Coastguard Worker   mu0.Lock();  // acquire mu0 while holding mu1; should get one deadlock
1258*9356374aSAndroid Build Coastguard Worker                // report here
1259*9356374aSAndroid Build Coastguard Worker   mu0.Unlock();
1260*9356374aSAndroid Build Coastguard Worker   mu1.Unlock();
1261*9356374aSAndroid Build Coastguard Worker 
1262*9356374aSAndroid Build Coastguard Worker   absl::SetMutexDeadlockDetectionMode(absl::OnDeadlockCycle::kAbort);
1263*9356374aSAndroid Build Coastguard Worker }
1264*9356374aSAndroid Build Coastguard Worker 
1265*9356374aSAndroid Build Coastguard Worker TEST(Mutex, DeadlockDetectorLongCycle) {
1266*9356374aSAndroid Build Coastguard Worker   absl::SetMutexDeadlockDetectionMode(absl::OnDeadlockCycle::kReport);
1267*9356374aSAndroid Build Coastguard Worker 
1268*9356374aSAndroid Build Coastguard Worker   // This test generates a warning if it passes, and crashes otherwise.
1269*9356374aSAndroid Build Coastguard Worker   // Cause bazel to ignore the warning.
1270*9356374aSAndroid Build Coastguard Worker   ScopedDisableBazelTestWarnings disable_bazel_test_warnings;
1271*9356374aSAndroid Build Coastguard Worker 
1272*9356374aSAndroid Build Coastguard Worker   // Check that we survive a deadlock with a lock cycle.
1273*9356374aSAndroid Build Coastguard Worker   std::vector<absl::Mutex> mutex(100);
1274*9356374aSAndroid Build Coastguard Worker   for (size_t i = 0; i != mutex.size(); i++) {
1275*9356374aSAndroid Build Coastguard Worker     mutex[i].Lock();
1276*9356374aSAndroid Build Coastguard Worker     mutex[(i + 1) % mutex.size()].Lock();
1277*9356374aSAndroid Build Coastguard Worker     mutex[i].Unlock();
1278*9356374aSAndroid Build Coastguard Worker     mutex[(i + 1) % mutex.size()].Unlock();
1279*9356374aSAndroid Build Coastguard Worker   }
1280*9356374aSAndroid Build Coastguard Worker 
1281*9356374aSAndroid Build Coastguard Worker   absl::SetMutexDeadlockDetectionMode(absl::OnDeadlockCycle::kAbort);
1282*9356374aSAndroid Build Coastguard Worker }
1283*9356374aSAndroid Build Coastguard Worker 
1284*9356374aSAndroid Build Coastguard Worker // This test is tagged with NO_THREAD_SAFETY_ANALYSIS because the
1285*9356374aSAndroid Build Coastguard Worker // annotation-based static thread-safety analysis is not currently
1286*9356374aSAndroid Build Coastguard Worker // predicate-aware and cannot tell if the two for-loops that acquire and
1287*9356374aSAndroid Build Coastguard Worker // release the locks have the same predicates.
1288*9356374aSAndroid Build Coastguard Worker TEST(Mutex, DeadlockDetectorStressTest) ABSL_NO_THREAD_SAFETY_ANALYSIS {
1289*9356374aSAndroid Build Coastguard Worker   // Stress test: Here we create a large number of locks and use all of them.
1290*9356374aSAndroid Build Coastguard Worker   // If a deadlock detector keeps a full graph of lock acquisition order,
1291*9356374aSAndroid Build Coastguard Worker   // it will likely be too slow for this test to pass.
1292*9356374aSAndroid Build Coastguard Worker   const int n_locks = 1 << 17;
1293*9356374aSAndroid Build Coastguard Worker   auto array_of_locks = absl::make_unique<absl::Mutex[]>(n_locks);
1294*9356374aSAndroid Build Coastguard Worker   for (int i = 0; i < n_locks; i++) {
1295*9356374aSAndroid Build Coastguard Worker     int end = std::min(n_locks, i + 5);
1296*9356374aSAndroid Build Coastguard Worker     // acquire and then release locks i, i+1, ..., i+4
1297*9356374aSAndroid Build Coastguard Worker     for (int j = i; j < end; j++) {
1298*9356374aSAndroid Build Coastguard Worker       array_of_locks[j].Lock();
1299*9356374aSAndroid Build Coastguard Worker     }
1300*9356374aSAndroid Build Coastguard Worker     for (int j = i; j < end; j++) {
1301*9356374aSAndroid Build Coastguard Worker       array_of_locks[j].Unlock();
1302*9356374aSAndroid Build Coastguard Worker     }
1303*9356374aSAndroid Build Coastguard Worker   }
1304*9356374aSAndroid Build Coastguard Worker }
1305*9356374aSAndroid Build Coastguard Worker 
1306*9356374aSAndroid Build Coastguard Worker #ifdef ABSL_HAVE_THREAD_SANITIZER
1307*9356374aSAndroid Build Coastguard Worker // TSAN reports errors when locked Mutexes are destroyed.
1308*9356374aSAndroid Build Coastguard Worker TEST(Mutex, DISABLED_DeadlockIdBug) ABSL_NO_THREAD_SAFETY_ANALYSIS {
1309*9356374aSAndroid Build Coastguard Worker #else
1310*9356374aSAndroid Build Coastguard Worker TEST(Mutex, DeadlockIdBug) ABSL_NO_THREAD_SAFETY_ANALYSIS {
1311*9356374aSAndroid Build Coastguard Worker #endif
1312*9356374aSAndroid Build Coastguard Worker   // Test a scenario where a cached deadlock graph node id in the
1313*9356374aSAndroid Build Coastguard Worker   // list of held locks is not invalidated when the corresponding
1314*9356374aSAndroid Build Coastguard Worker   // mutex is deleted.
1315*9356374aSAndroid Build Coastguard Worker   absl::SetMutexDeadlockDetectionMode(absl::OnDeadlockCycle::kAbort);
1316*9356374aSAndroid Build Coastguard Worker   // Mutex that will be destroyed while being held
1317*9356374aSAndroid Build Coastguard Worker   absl::Mutex *a = new absl::Mutex;
1318*9356374aSAndroid Build Coastguard Worker   // Other mutexes needed by test
1319*9356374aSAndroid Build Coastguard Worker   absl::Mutex b, c;
1320*9356374aSAndroid Build Coastguard Worker 
1321*9356374aSAndroid Build Coastguard Worker   // Hold mutex.
1322*9356374aSAndroid Build Coastguard Worker   a->Lock();
1323*9356374aSAndroid Build Coastguard Worker 
1324*9356374aSAndroid Build Coastguard Worker   // Force deadlock id assignment by acquiring another lock.
1325*9356374aSAndroid Build Coastguard Worker   b.Lock();
1326*9356374aSAndroid Build Coastguard Worker   b.Unlock();
1327*9356374aSAndroid Build Coastguard Worker 
1328*9356374aSAndroid Build Coastguard Worker   // Delete the mutex. The Mutex destructor tries to remove held locks,
1329*9356374aSAndroid Build Coastguard Worker   // but the attempt isn't foolproof.  It can fail if:
1330*9356374aSAndroid Build Coastguard Worker   //   (a) Deadlock detection is currently disabled.
1331*9356374aSAndroid Build Coastguard Worker   //   (b) The destruction is from another thread.
1332*9356374aSAndroid Build Coastguard Worker   // We exploit (a) by temporarily disabling deadlock detection.
1333*9356374aSAndroid Build Coastguard Worker   absl::SetMutexDeadlockDetectionMode(absl::OnDeadlockCycle::kIgnore);
1334*9356374aSAndroid Build Coastguard Worker   delete a;
1335*9356374aSAndroid Build Coastguard Worker   absl::SetMutexDeadlockDetectionMode(absl::OnDeadlockCycle::kAbort);
1336*9356374aSAndroid Build Coastguard Worker 
1337*9356374aSAndroid Build Coastguard Worker   // Now acquire another lock which will force a deadlock id assignment.
1338*9356374aSAndroid Build Coastguard Worker   // We should end up getting assigned the same deadlock id that was
1339*9356374aSAndroid Build Coastguard Worker   // freed up when "a" was deleted, which will cause a spurious deadlock
1340*9356374aSAndroid Build Coastguard Worker   // report if the held lock entry for "a" was not invalidated.
1341*9356374aSAndroid Build Coastguard Worker   c.Lock();
1342*9356374aSAndroid Build Coastguard Worker   c.Unlock();
1343*9356374aSAndroid Build Coastguard Worker }
1344*9356374aSAndroid Build Coastguard Worker 
1345*9356374aSAndroid Build Coastguard Worker // --------------------------------------------------------
1346*9356374aSAndroid Build Coastguard Worker // Test for timeouts/deadlines on condition waits that are specified using
1347*9356374aSAndroid Build Coastguard Worker // absl::Duration and absl::Time.  For each waiting function we test with
1348*9356374aSAndroid Build Coastguard Worker // a timeout/deadline that has already expired/passed, one that is infinite
1349*9356374aSAndroid Build Coastguard Worker // and so never expires/passes, and one that will expire/pass in the near
1350*9356374aSAndroid Build Coastguard Worker // future.
1351*9356374aSAndroid Build Coastguard Worker 
1352*9356374aSAndroid Build Coastguard Worker static absl::Duration TimeoutTestAllowedSchedulingDelay() {
1353*9356374aSAndroid Build Coastguard Worker   // Note: we use a function here because Microsoft Visual Studio fails to
1354*9356374aSAndroid Build Coastguard Worker   // properly initialize constexpr static absl::Duration variables.
1355*9356374aSAndroid Build Coastguard Worker   return absl::Milliseconds(150);
1356*9356374aSAndroid Build Coastguard Worker }
1357*9356374aSAndroid Build Coastguard Worker 
1358*9356374aSAndroid Build Coastguard Worker // Returns true if `actual_delay` is close enough to `expected_delay` to pass
1359*9356374aSAndroid Build Coastguard Worker // the timeouts/deadlines test.  Otherwise, logs warnings and returns false.
1360*9356374aSAndroid Build Coastguard Worker ABSL_MUST_USE_RESULT
1361*9356374aSAndroid Build Coastguard Worker static bool DelayIsWithinBounds(absl::Duration expected_delay,
1362*9356374aSAndroid Build Coastguard Worker                                 absl::Duration actual_delay) {
1363*9356374aSAndroid Build Coastguard Worker   bool pass = true;
1364*9356374aSAndroid Build Coastguard Worker   // Do not allow the observed delay to be less than expected.  This may occur
1365*9356374aSAndroid Build Coastguard Worker   // in practice due to clock skew or when the synchronization primitives use a
1366*9356374aSAndroid Build Coastguard Worker   // different clock than absl::Now(), but these cases should be handled by the
1367*9356374aSAndroid Build Coastguard Worker   // the retry mechanism in each TimeoutTest.
1368*9356374aSAndroid Build Coastguard Worker   if (actual_delay < expected_delay) {
1369*9356374aSAndroid Build Coastguard Worker     LOG(WARNING) << "Actual delay " << actual_delay
1370*9356374aSAndroid Build Coastguard Worker                  << " was too short, expected " << expected_delay
1371*9356374aSAndroid Build Coastguard Worker                  << " (difference " << actual_delay - expected_delay << ")";
1372*9356374aSAndroid Build Coastguard Worker     pass = false;
1373*9356374aSAndroid Build Coastguard Worker   }
1374*9356374aSAndroid Build Coastguard Worker   // If the expected delay is <= zero then allow a small error tolerance, since
1375*9356374aSAndroid Build Coastguard Worker   // we do not expect context switches to occur during test execution.
1376*9356374aSAndroid Build Coastguard Worker   // Otherwise, thread scheduling delays may be substantial in rare cases, so
1377*9356374aSAndroid Build Coastguard Worker   // tolerate up to kTimeoutTestAllowedSchedulingDelay of error.
1378*9356374aSAndroid Build Coastguard Worker   absl::Duration tolerance = expected_delay <= absl::ZeroDuration()
1379*9356374aSAndroid Build Coastguard Worker                                  ? absl::Milliseconds(10)
1380*9356374aSAndroid Build Coastguard Worker                                  : TimeoutTestAllowedSchedulingDelay();
1381*9356374aSAndroid Build Coastguard Worker   if (actual_delay > expected_delay + tolerance) {
1382*9356374aSAndroid Build Coastguard Worker     LOG(WARNING) << "Actual delay " << actual_delay
1383*9356374aSAndroid Build Coastguard Worker                  << " was too long, expected " << expected_delay
1384*9356374aSAndroid Build Coastguard Worker                  << " (difference " << actual_delay - expected_delay << ")";
1385*9356374aSAndroid Build Coastguard Worker     pass = false;
1386*9356374aSAndroid Build Coastguard Worker   }
1387*9356374aSAndroid Build Coastguard Worker   return pass;
1388*9356374aSAndroid Build Coastguard Worker }
1389*9356374aSAndroid Build Coastguard Worker 
1390*9356374aSAndroid Build Coastguard Worker // Parameters for TimeoutTest, below.
1391*9356374aSAndroid Build Coastguard Worker struct TimeoutTestParam {
1392*9356374aSAndroid Build Coastguard Worker   // The file and line number (used for logging purposes only).
1393*9356374aSAndroid Build Coastguard Worker   const char *from_file;
1394*9356374aSAndroid Build Coastguard Worker   int from_line;
1395*9356374aSAndroid Build Coastguard Worker 
1396*9356374aSAndroid Build Coastguard Worker   // Should the absolute deadline API based on absl::Time be tested?  If false,
1397*9356374aSAndroid Build Coastguard Worker   // the relative deadline API based on absl::Duration is tested.
1398*9356374aSAndroid Build Coastguard Worker   bool use_absolute_deadline;
1399*9356374aSAndroid Build Coastguard Worker 
1400*9356374aSAndroid Build Coastguard Worker   // The deadline/timeout used when calling the API being tested
1401*9356374aSAndroid Build Coastguard Worker   // (e.g. Mutex::LockWhenWithDeadline).
1402*9356374aSAndroid Build Coastguard Worker   absl::Duration wait_timeout;
1403*9356374aSAndroid Build Coastguard Worker 
1404*9356374aSAndroid Build Coastguard Worker   // The delay before the condition will be set true by the test code.  If zero
1405*9356374aSAndroid Build Coastguard Worker   // or negative, the condition is set true immediately (before calling the API
1406*9356374aSAndroid Build Coastguard Worker   // being tested).  Otherwise, if infinite, the condition is never set true.
1407*9356374aSAndroid Build Coastguard Worker   // Otherwise a closure is scheduled for the future that sets the condition
1408*9356374aSAndroid Build Coastguard Worker   // true.
1409*9356374aSAndroid Build Coastguard Worker   absl::Duration satisfy_condition_delay;
1410*9356374aSAndroid Build Coastguard Worker 
1411*9356374aSAndroid Build Coastguard Worker   // The expected result of the condition after the call to the API being
1412*9356374aSAndroid Build Coastguard Worker   // tested. Generally `true` means the condition was true when the API returns,
1413*9356374aSAndroid Build Coastguard Worker   // `false` indicates an expected timeout.
1414*9356374aSAndroid Build Coastguard Worker   bool expected_result;
1415*9356374aSAndroid Build Coastguard Worker 
1416*9356374aSAndroid Build Coastguard Worker   // The expected delay before the API under test returns.  This is inherently
1417*9356374aSAndroid Build Coastguard Worker   // flaky, so some slop is allowed (see `DelayIsWithinBounds` above), and the
1418*9356374aSAndroid Build Coastguard Worker   // test keeps trying indefinitely until this constraint passes.
1419*9356374aSAndroid Build Coastguard Worker   absl::Duration expected_delay;
1420*9356374aSAndroid Build Coastguard Worker };
1421*9356374aSAndroid Build Coastguard Worker 
1422*9356374aSAndroid Build Coastguard Worker // Print a `TimeoutTestParam` to a debug log.
1423*9356374aSAndroid Build Coastguard Worker std::ostream &operator<<(std::ostream &os, const TimeoutTestParam &param) {
1424*9356374aSAndroid Build Coastguard Worker   return os << "from: " << param.from_file << ":" << param.from_line
1425*9356374aSAndroid Build Coastguard Worker             << " use_absolute_deadline: "
1426*9356374aSAndroid Build Coastguard Worker             << (param.use_absolute_deadline ? "true" : "false")
1427*9356374aSAndroid Build Coastguard Worker             << " wait_timeout: " << param.wait_timeout
1428*9356374aSAndroid Build Coastguard Worker             << " satisfy_condition_delay: " << param.satisfy_condition_delay
1429*9356374aSAndroid Build Coastguard Worker             << " expected_result: "
1430*9356374aSAndroid Build Coastguard Worker             << (param.expected_result ? "true" : "false")
1431*9356374aSAndroid Build Coastguard Worker             << " expected_delay: " << param.expected_delay;
1432*9356374aSAndroid Build Coastguard Worker }
1433*9356374aSAndroid Build Coastguard Worker 
1434*9356374aSAndroid Build Coastguard Worker // Like `thread::Executor::ScheduleAt` except:
1435*9356374aSAndroid Build Coastguard Worker // a) Delays zero or negative are executed immediately in the current thread.
1436*9356374aSAndroid Build Coastguard Worker // b) Infinite delays are never scheduled.
1437*9356374aSAndroid Build Coastguard Worker // c) Calls this test's `ScheduleAt` helper instead of using `pool` directly.
1438*9356374aSAndroid Build Coastguard Worker static void RunAfterDelay(absl::Duration delay,
1439*9356374aSAndroid Build Coastguard Worker                           absl::synchronization_internal::ThreadPool *pool,
1440*9356374aSAndroid Build Coastguard Worker                           const std::function<void()> &callback) {
1441*9356374aSAndroid Build Coastguard Worker   if (delay <= absl::ZeroDuration()) {
1442*9356374aSAndroid Build Coastguard Worker     callback();  // immediate
1443*9356374aSAndroid Build Coastguard Worker   } else if (delay != absl::InfiniteDuration()) {
1444*9356374aSAndroid Build Coastguard Worker     ScheduleAfter(pool, delay, callback);
1445*9356374aSAndroid Build Coastguard Worker   }
1446*9356374aSAndroid Build Coastguard Worker }
1447*9356374aSAndroid Build Coastguard Worker 
1448*9356374aSAndroid Build Coastguard Worker class TimeoutTest : public ::testing::Test,
1449*9356374aSAndroid Build Coastguard Worker                     public ::testing::WithParamInterface<TimeoutTestParam> {};
1450*9356374aSAndroid Build Coastguard Worker 
1451*9356374aSAndroid Build Coastguard Worker std::vector<TimeoutTestParam> MakeTimeoutTestParamValues() {
1452*9356374aSAndroid Build Coastguard Worker   // The `finite` delay is a finite, relatively short, delay.  We make it larger
1453*9356374aSAndroid Build Coastguard Worker   // than our allowed scheduling delay (slop factor) to avoid confusion when
1454*9356374aSAndroid Build Coastguard Worker   // diagnosing test failures.  The other constants here have clear meanings.
1455*9356374aSAndroid Build Coastguard Worker   const absl::Duration finite = 3 * TimeoutTestAllowedSchedulingDelay();
1456*9356374aSAndroid Build Coastguard Worker   const absl::Duration never = absl::InfiniteDuration();
1457*9356374aSAndroid Build Coastguard Worker   const absl::Duration negative = -absl::InfiniteDuration();
1458*9356374aSAndroid Build Coastguard Worker   const absl::Duration immediate = absl::ZeroDuration();
1459*9356374aSAndroid Build Coastguard Worker 
1460*9356374aSAndroid Build Coastguard Worker   // Every test case is run twice; once using the absolute deadline API and once
1461*9356374aSAndroid Build Coastguard Worker   // using the relative timeout API.
1462*9356374aSAndroid Build Coastguard Worker   std::vector<TimeoutTestParam> values;
1463*9356374aSAndroid Build Coastguard Worker   for (bool use_absolute_deadline : {false, true}) {
1464*9356374aSAndroid Build Coastguard Worker     // Tests with a negative timeout (deadline in the past), which should
1465*9356374aSAndroid Build Coastguard Worker     // immediately return current state of the condition.
1466*9356374aSAndroid Build Coastguard Worker 
1467*9356374aSAndroid Build Coastguard Worker     // The condition is already true:
1468*9356374aSAndroid Build Coastguard Worker     values.push_back(TimeoutTestParam{
1469*9356374aSAndroid Build Coastguard Worker         __FILE__, __LINE__, use_absolute_deadline,
1470*9356374aSAndroid Build Coastguard Worker         negative,   // wait_timeout
1471*9356374aSAndroid Build Coastguard Worker         immediate,  // satisfy_condition_delay
1472*9356374aSAndroid Build Coastguard Worker         true,       // expected_result
1473*9356374aSAndroid Build Coastguard Worker         immediate,  // expected_delay
1474*9356374aSAndroid Build Coastguard Worker     });
1475*9356374aSAndroid Build Coastguard Worker 
1476*9356374aSAndroid Build Coastguard Worker     // The condition becomes true, but the timeout has already expired:
1477*9356374aSAndroid Build Coastguard Worker     values.push_back(TimeoutTestParam{
1478*9356374aSAndroid Build Coastguard Worker         __FILE__, __LINE__, use_absolute_deadline,
1479*9356374aSAndroid Build Coastguard Worker         negative,  // wait_timeout
1480*9356374aSAndroid Build Coastguard Worker         finite,    // satisfy_condition_delay
1481*9356374aSAndroid Build Coastguard Worker         false,     // expected_result
1482*9356374aSAndroid Build Coastguard Worker         immediate  // expected_delay
1483*9356374aSAndroid Build Coastguard Worker     });
1484*9356374aSAndroid Build Coastguard Worker 
1485*9356374aSAndroid Build Coastguard Worker     // The condition never becomes true:
1486*9356374aSAndroid Build Coastguard Worker     values.push_back(TimeoutTestParam{
1487*9356374aSAndroid Build Coastguard Worker         __FILE__, __LINE__, use_absolute_deadline,
1488*9356374aSAndroid Build Coastguard Worker         negative,  // wait_timeout
1489*9356374aSAndroid Build Coastguard Worker         never,     // satisfy_condition_delay
1490*9356374aSAndroid Build Coastguard Worker         false,     // expected_result
1491*9356374aSAndroid Build Coastguard Worker         immediate  // expected_delay
1492*9356374aSAndroid Build Coastguard Worker     });
1493*9356374aSAndroid Build Coastguard Worker 
1494*9356374aSAndroid Build Coastguard Worker     // Tests with an infinite timeout (deadline in the infinite future), which
1495*9356374aSAndroid Build Coastguard Worker     // should only return when the condition becomes true.
1496*9356374aSAndroid Build Coastguard Worker 
1497*9356374aSAndroid Build Coastguard Worker     // The condition is already true:
1498*9356374aSAndroid Build Coastguard Worker     values.push_back(TimeoutTestParam{
1499*9356374aSAndroid Build Coastguard Worker         __FILE__, __LINE__, use_absolute_deadline,
1500*9356374aSAndroid Build Coastguard Worker         never,      // wait_timeout
1501*9356374aSAndroid Build Coastguard Worker         immediate,  // satisfy_condition_delay
1502*9356374aSAndroid Build Coastguard Worker         true,       // expected_result
1503*9356374aSAndroid Build Coastguard Worker         immediate   // expected_delay
1504*9356374aSAndroid Build Coastguard Worker     });
1505*9356374aSAndroid Build Coastguard Worker 
1506*9356374aSAndroid Build Coastguard Worker     // The condition becomes true before the (infinite) expiry:
1507*9356374aSAndroid Build Coastguard Worker     values.push_back(TimeoutTestParam{
1508*9356374aSAndroid Build Coastguard Worker         __FILE__, __LINE__, use_absolute_deadline,
1509*9356374aSAndroid Build Coastguard Worker         never,   // wait_timeout
1510*9356374aSAndroid Build Coastguard Worker         finite,  // satisfy_condition_delay
1511*9356374aSAndroid Build Coastguard Worker         true,    // expected_result
1512*9356374aSAndroid Build Coastguard Worker         finite,  // expected_delay
1513*9356374aSAndroid Build Coastguard Worker     });
1514*9356374aSAndroid Build Coastguard Worker 
1515*9356374aSAndroid Build Coastguard Worker     // Tests with a (small) finite timeout (deadline soon), with the condition
1516*9356374aSAndroid Build Coastguard Worker     // becoming true both before and after its expiry.
1517*9356374aSAndroid Build Coastguard Worker 
1518*9356374aSAndroid Build Coastguard Worker     // The condition is already true:
1519*9356374aSAndroid Build Coastguard Worker     values.push_back(TimeoutTestParam{
1520*9356374aSAndroid Build Coastguard Worker         __FILE__, __LINE__, use_absolute_deadline,
1521*9356374aSAndroid Build Coastguard Worker         never,      // wait_timeout
1522*9356374aSAndroid Build Coastguard Worker         immediate,  // satisfy_condition_delay
1523*9356374aSAndroid Build Coastguard Worker         true,       // expected_result
1524*9356374aSAndroid Build Coastguard Worker         immediate   // expected_delay
1525*9356374aSAndroid Build Coastguard Worker     });
1526*9356374aSAndroid Build Coastguard Worker 
1527*9356374aSAndroid Build Coastguard Worker     // The condition becomes true before the expiry:
1528*9356374aSAndroid Build Coastguard Worker     values.push_back(TimeoutTestParam{
1529*9356374aSAndroid Build Coastguard Worker         __FILE__, __LINE__, use_absolute_deadline,
1530*9356374aSAndroid Build Coastguard Worker         finite * 2,  // wait_timeout
1531*9356374aSAndroid Build Coastguard Worker         finite,      // satisfy_condition_delay
1532*9356374aSAndroid Build Coastguard Worker         true,        // expected_result
1533*9356374aSAndroid Build Coastguard Worker         finite       // expected_delay
1534*9356374aSAndroid Build Coastguard Worker     });
1535*9356374aSAndroid Build Coastguard Worker 
1536*9356374aSAndroid Build Coastguard Worker     // The condition becomes true, but the timeout has already expired:
1537*9356374aSAndroid Build Coastguard Worker     values.push_back(TimeoutTestParam{
1538*9356374aSAndroid Build Coastguard Worker         __FILE__, __LINE__, use_absolute_deadline,
1539*9356374aSAndroid Build Coastguard Worker         finite,      // wait_timeout
1540*9356374aSAndroid Build Coastguard Worker         finite * 2,  // satisfy_condition_delay
1541*9356374aSAndroid Build Coastguard Worker         false,       // expected_result
1542*9356374aSAndroid Build Coastguard Worker         finite       // expected_delay
1543*9356374aSAndroid Build Coastguard Worker     });
1544*9356374aSAndroid Build Coastguard Worker 
1545*9356374aSAndroid Build Coastguard Worker     // The condition never becomes true:
1546*9356374aSAndroid Build Coastguard Worker     values.push_back(TimeoutTestParam{
1547*9356374aSAndroid Build Coastguard Worker         __FILE__, __LINE__, use_absolute_deadline,
1548*9356374aSAndroid Build Coastguard Worker         finite,  // wait_timeout
1549*9356374aSAndroid Build Coastguard Worker         never,   // satisfy_condition_delay
1550*9356374aSAndroid Build Coastguard Worker         false,   // expected_result
1551*9356374aSAndroid Build Coastguard Worker         finite   // expected_delay
1552*9356374aSAndroid Build Coastguard Worker     });
1553*9356374aSAndroid Build Coastguard Worker   }
1554*9356374aSAndroid Build Coastguard Worker   return values;
1555*9356374aSAndroid Build Coastguard Worker }
1556*9356374aSAndroid Build Coastguard Worker 
1557*9356374aSAndroid Build Coastguard Worker // Instantiate `TimeoutTest` with `MakeTimeoutTestParamValues()`.
1558*9356374aSAndroid Build Coastguard Worker INSTANTIATE_TEST_SUITE_P(All, TimeoutTest,
1559*9356374aSAndroid Build Coastguard Worker                          testing::ValuesIn(MakeTimeoutTestParamValues()));
1560*9356374aSAndroid Build Coastguard Worker 
1561*9356374aSAndroid Build Coastguard Worker TEST_P(TimeoutTest, Await) {
1562*9356374aSAndroid Build Coastguard Worker   const TimeoutTestParam params = GetParam();
1563*9356374aSAndroid Build Coastguard Worker   LOG(INFO) << "Params: " << params;
1564*9356374aSAndroid Build Coastguard Worker 
1565*9356374aSAndroid Build Coastguard Worker   // Because this test asserts bounds on scheduling delays it is flaky.  To
1566*9356374aSAndroid Build Coastguard Worker   // compensate it loops forever until it passes.  Failures express as test
1567*9356374aSAndroid Build Coastguard Worker   // timeouts, in which case the test log can be used to diagnose the issue.
1568*9356374aSAndroid Build Coastguard Worker   for (int attempt = 1;; ++attempt) {
1569*9356374aSAndroid Build Coastguard Worker     LOG(INFO) << "Attempt " << attempt;
1570*9356374aSAndroid Build Coastguard Worker 
1571*9356374aSAndroid Build Coastguard Worker     absl::Mutex mu;
1572*9356374aSAndroid Build Coastguard Worker     bool value = false;  // condition value (under mu)
1573*9356374aSAndroid Build Coastguard Worker 
1574*9356374aSAndroid Build Coastguard Worker     std::unique_ptr<absl::synchronization_internal::ThreadPool> pool =
1575*9356374aSAndroid Build Coastguard Worker         CreateDefaultPool();
1576*9356374aSAndroid Build Coastguard Worker     RunAfterDelay(params.satisfy_condition_delay, pool.get(), [&] {
1577*9356374aSAndroid Build Coastguard Worker       absl::MutexLock l(&mu);
1578*9356374aSAndroid Build Coastguard Worker       value = true;
1579*9356374aSAndroid Build Coastguard Worker     });
1580*9356374aSAndroid Build Coastguard Worker 
1581*9356374aSAndroid Build Coastguard Worker     absl::MutexLock lock(&mu);
1582*9356374aSAndroid Build Coastguard Worker     absl::Time start_time = absl::Now();
1583*9356374aSAndroid Build Coastguard Worker     absl::Condition cond(&value);
1584*9356374aSAndroid Build Coastguard Worker     bool result =
1585*9356374aSAndroid Build Coastguard Worker         params.use_absolute_deadline
1586*9356374aSAndroid Build Coastguard Worker             ? mu.AwaitWithDeadline(cond, start_time + params.wait_timeout)
1587*9356374aSAndroid Build Coastguard Worker             : mu.AwaitWithTimeout(cond, params.wait_timeout);
1588*9356374aSAndroid Build Coastguard Worker     if (DelayIsWithinBounds(params.expected_delay, absl::Now() - start_time)) {
1589*9356374aSAndroid Build Coastguard Worker       EXPECT_EQ(params.expected_result, result);
1590*9356374aSAndroid Build Coastguard Worker       break;
1591*9356374aSAndroid Build Coastguard Worker     }
1592*9356374aSAndroid Build Coastguard Worker   }
1593*9356374aSAndroid Build Coastguard Worker }
1594*9356374aSAndroid Build Coastguard Worker 
1595*9356374aSAndroid Build Coastguard Worker TEST_P(TimeoutTest, LockWhen) {
1596*9356374aSAndroid Build Coastguard Worker   const TimeoutTestParam params = GetParam();
1597*9356374aSAndroid Build Coastguard Worker   LOG(INFO) << "Params: " << params;
1598*9356374aSAndroid Build Coastguard Worker 
1599*9356374aSAndroid Build Coastguard Worker   // Because this test asserts bounds on scheduling delays it is flaky.  To
1600*9356374aSAndroid Build Coastguard Worker   // compensate it loops forever until it passes.  Failures express as test
1601*9356374aSAndroid Build Coastguard Worker   // timeouts, in which case the test log can be used to diagnose the issue.
1602*9356374aSAndroid Build Coastguard Worker   for (int attempt = 1;; ++attempt) {
1603*9356374aSAndroid Build Coastguard Worker     LOG(INFO) << "Attempt " << attempt;
1604*9356374aSAndroid Build Coastguard Worker 
1605*9356374aSAndroid Build Coastguard Worker     absl::Mutex mu;
1606*9356374aSAndroid Build Coastguard Worker     bool value = false;  // condition value (under mu)
1607*9356374aSAndroid Build Coastguard Worker 
1608*9356374aSAndroid Build Coastguard Worker     std::unique_ptr<absl::synchronization_internal::ThreadPool> pool =
1609*9356374aSAndroid Build Coastguard Worker         CreateDefaultPool();
1610*9356374aSAndroid Build Coastguard Worker     RunAfterDelay(params.satisfy_condition_delay, pool.get(), [&] {
1611*9356374aSAndroid Build Coastguard Worker       absl::MutexLock l(&mu);
1612*9356374aSAndroid Build Coastguard Worker       value = true;
1613*9356374aSAndroid Build Coastguard Worker     });
1614*9356374aSAndroid Build Coastguard Worker 
1615*9356374aSAndroid Build Coastguard Worker     absl::Time start_time = absl::Now();
1616*9356374aSAndroid Build Coastguard Worker     absl::Condition cond(&value);
1617*9356374aSAndroid Build Coastguard Worker     bool result =
1618*9356374aSAndroid Build Coastguard Worker         params.use_absolute_deadline
1619*9356374aSAndroid Build Coastguard Worker             ? mu.LockWhenWithDeadline(cond, start_time + params.wait_timeout)
1620*9356374aSAndroid Build Coastguard Worker             : mu.LockWhenWithTimeout(cond, params.wait_timeout);
1621*9356374aSAndroid Build Coastguard Worker     mu.Unlock();
1622*9356374aSAndroid Build Coastguard Worker 
1623*9356374aSAndroid Build Coastguard Worker     if (DelayIsWithinBounds(params.expected_delay, absl::Now() - start_time)) {
1624*9356374aSAndroid Build Coastguard Worker       EXPECT_EQ(params.expected_result, result);
1625*9356374aSAndroid Build Coastguard Worker       break;
1626*9356374aSAndroid Build Coastguard Worker     }
1627*9356374aSAndroid Build Coastguard Worker   }
1628*9356374aSAndroid Build Coastguard Worker }
1629*9356374aSAndroid Build Coastguard Worker 
1630*9356374aSAndroid Build Coastguard Worker TEST_P(TimeoutTest, ReaderLockWhen) {
1631*9356374aSAndroid Build Coastguard Worker   const TimeoutTestParam params = GetParam();
1632*9356374aSAndroid Build Coastguard Worker   LOG(INFO) << "Params: " << params;
1633*9356374aSAndroid Build Coastguard Worker 
1634*9356374aSAndroid Build Coastguard Worker   // Because this test asserts bounds on scheduling delays it is flaky.  To
1635*9356374aSAndroid Build Coastguard Worker   // compensate it loops forever until it passes.  Failures express as test
1636*9356374aSAndroid Build Coastguard Worker   // timeouts, in which case the test log can be used to diagnose the issue.
1637*9356374aSAndroid Build Coastguard Worker   for (int attempt = 0;; ++attempt) {
1638*9356374aSAndroid Build Coastguard Worker     LOG(INFO) << "Attempt " << attempt;
1639*9356374aSAndroid Build Coastguard Worker 
1640*9356374aSAndroid Build Coastguard Worker     absl::Mutex mu;
1641*9356374aSAndroid Build Coastguard Worker     bool value = false;  // condition value (under mu)
1642*9356374aSAndroid Build Coastguard Worker 
1643*9356374aSAndroid Build Coastguard Worker     std::unique_ptr<absl::synchronization_internal::ThreadPool> pool =
1644*9356374aSAndroid Build Coastguard Worker         CreateDefaultPool();
1645*9356374aSAndroid Build Coastguard Worker     RunAfterDelay(params.satisfy_condition_delay, pool.get(), [&] {
1646*9356374aSAndroid Build Coastguard Worker       absl::MutexLock l(&mu);
1647*9356374aSAndroid Build Coastguard Worker       value = true;
1648*9356374aSAndroid Build Coastguard Worker     });
1649*9356374aSAndroid Build Coastguard Worker 
1650*9356374aSAndroid Build Coastguard Worker     absl::Time start_time = absl::Now();
1651*9356374aSAndroid Build Coastguard Worker     bool result =
1652*9356374aSAndroid Build Coastguard Worker         params.use_absolute_deadline
1653*9356374aSAndroid Build Coastguard Worker             ? mu.ReaderLockWhenWithDeadline(absl::Condition(&value),
1654*9356374aSAndroid Build Coastguard Worker                                             start_time + params.wait_timeout)
1655*9356374aSAndroid Build Coastguard Worker             : mu.ReaderLockWhenWithTimeout(absl::Condition(&value),
1656*9356374aSAndroid Build Coastguard Worker                                            params.wait_timeout);
1657*9356374aSAndroid Build Coastguard Worker     mu.ReaderUnlock();
1658*9356374aSAndroid Build Coastguard Worker 
1659*9356374aSAndroid Build Coastguard Worker     if (DelayIsWithinBounds(params.expected_delay, absl::Now() - start_time)) {
1660*9356374aSAndroid Build Coastguard Worker       EXPECT_EQ(params.expected_result, result);
1661*9356374aSAndroid Build Coastguard Worker       break;
1662*9356374aSAndroid Build Coastguard Worker     }
1663*9356374aSAndroid Build Coastguard Worker   }
1664*9356374aSAndroid Build Coastguard Worker }
1665*9356374aSAndroid Build Coastguard Worker 
1666*9356374aSAndroid Build Coastguard Worker TEST_P(TimeoutTest, Wait) {
1667*9356374aSAndroid Build Coastguard Worker   const TimeoutTestParam params = GetParam();
1668*9356374aSAndroid Build Coastguard Worker   LOG(INFO) << "Params: " << params;
1669*9356374aSAndroid Build Coastguard Worker 
1670*9356374aSAndroid Build Coastguard Worker   // Because this test asserts bounds on scheduling delays it is flaky.  To
1671*9356374aSAndroid Build Coastguard Worker   // compensate it loops forever until it passes.  Failures express as test
1672*9356374aSAndroid Build Coastguard Worker   // timeouts, in which case the test log can be used to diagnose the issue.
1673*9356374aSAndroid Build Coastguard Worker   for (int attempt = 0;; ++attempt) {
1674*9356374aSAndroid Build Coastguard Worker     LOG(INFO) << "Attempt " << attempt;
1675*9356374aSAndroid Build Coastguard Worker 
1676*9356374aSAndroid Build Coastguard Worker     absl::Mutex mu;
1677*9356374aSAndroid Build Coastguard Worker     bool value = false;  // condition value (under mu)
1678*9356374aSAndroid Build Coastguard Worker     absl::CondVar cv;    // signals a change of `value`
1679*9356374aSAndroid Build Coastguard Worker 
1680*9356374aSAndroid Build Coastguard Worker     std::unique_ptr<absl::synchronization_internal::ThreadPool> pool =
1681*9356374aSAndroid Build Coastguard Worker         CreateDefaultPool();
1682*9356374aSAndroid Build Coastguard Worker     RunAfterDelay(params.satisfy_condition_delay, pool.get(), [&] {
1683*9356374aSAndroid Build Coastguard Worker       absl::MutexLock l(&mu);
1684*9356374aSAndroid Build Coastguard Worker       value = true;
1685*9356374aSAndroid Build Coastguard Worker       cv.Signal();
1686*9356374aSAndroid Build Coastguard Worker     });
1687*9356374aSAndroid Build Coastguard Worker 
1688*9356374aSAndroid Build Coastguard Worker     absl::MutexLock lock(&mu);
1689*9356374aSAndroid Build Coastguard Worker     absl::Time start_time = absl::Now();
1690*9356374aSAndroid Build Coastguard Worker     absl::Duration timeout = params.wait_timeout;
1691*9356374aSAndroid Build Coastguard Worker     absl::Time deadline = start_time + timeout;
1692*9356374aSAndroid Build Coastguard Worker     while (!value) {
1693*9356374aSAndroid Build Coastguard Worker       if (params.use_absolute_deadline ? cv.WaitWithDeadline(&mu, deadline)
1694*9356374aSAndroid Build Coastguard Worker                                        : cv.WaitWithTimeout(&mu, timeout)) {
1695*9356374aSAndroid Build Coastguard Worker         break;  // deadline/timeout exceeded
1696*9356374aSAndroid Build Coastguard Worker       }
1697*9356374aSAndroid Build Coastguard Worker       timeout = deadline - absl::Now();  // recompute
1698*9356374aSAndroid Build Coastguard Worker     }
1699*9356374aSAndroid Build Coastguard Worker     bool result = value;  // note: `mu` is still held
1700*9356374aSAndroid Build Coastguard Worker 
1701*9356374aSAndroid Build Coastguard Worker     if (DelayIsWithinBounds(params.expected_delay, absl::Now() - start_time)) {
1702*9356374aSAndroid Build Coastguard Worker       EXPECT_EQ(params.expected_result, result);
1703*9356374aSAndroid Build Coastguard Worker       break;
1704*9356374aSAndroid Build Coastguard Worker     }
1705*9356374aSAndroid Build Coastguard Worker   }
1706*9356374aSAndroid Build Coastguard Worker }
1707*9356374aSAndroid Build Coastguard Worker 
1708*9356374aSAndroid Build Coastguard Worker TEST(Mutex, Logging) {
1709*9356374aSAndroid Build Coastguard Worker   // Allow user to look at logging output
1710*9356374aSAndroid Build Coastguard Worker   absl::Mutex logged_mutex;
1711*9356374aSAndroid Build Coastguard Worker   logged_mutex.EnableDebugLog("fido_mutex");
1712*9356374aSAndroid Build Coastguard Worker   absl::CondVar logged_cv;
1713*9356374aSAndroid Build Coastguard Worker   logged_cv.EnableDebugLog("rover_cv");
1714*9356374aSAndroid Build Coastguard Worker   logged_mutex.Lock();
1715*9356374aSAndroid Build Coastguard Worker   logged_cv.WaitWithTimeout(&logged_mutex, absl::Milliseconds(20));
1716*9356374aSAndroid Build Coastguard Worker   logged_mutex.Unlock();
1717*9356374aSAndroid Build Coastguard Worker   logged_mutex.ReaderLock();
1718*9356374aSAndroid Build Coastguard Worker   logged_mutex.ReaderUnlock();
1719*9356374aSAndroid Build Coastguard Worker   logged_mutex.Lock();
1720*9356374aSAndroid Build Coastguard Worker   logged_mutex.Unlock();
1721*9356374aSAndroid Build Coastguard Worker   logged_cv.Signal();
1722*9356374aSAndroid Build Coastguard Worker   logged_cv.SignalAll();
1723*9356374aSAndroid Build Coastguard Worker }
1724*9356374aSAndroid Build Coastguard Worker 
1725*9356374aSAndroid Build Coastguard Worker TEST(Mutex, LoggingAddressReuse) {
1726*9356374aSAndroid Build Coastguard Worker   // Repeatedly re-create a Mutex with debug logging at the same address.
1727*9356374aSAndroid Build Coastguard Worker   ScopedInvariantDebugging scoped_debugging;
1728*9356374aSAndroid Build Coastguard Worker   alignas(absl::Mutex) char storage[sizeof(absl::Mutex)];
1729*9356374aSAndroid Build Coastguard Worker   auto invariant =
1730*9356374aSAndroid Build Coastguard Worker       +[](void *alive) { EXPECT_TRUE(*static_cast<bool *>(alive)); };
1731*9356374aSAndroid Build Coastguard Worker   constexpr size_t kIters = 10;
1732*9356374aSAndroid Build Coastguard Worker   bool alive[kIters] = {};
1733*9356374aSAndroid Build Coastguard Worker   for (size_t i = 0; i < kIters; ++i) {
1734*9356374aSAndroid Build Coastguard Worker     absl::Mutex *mu = new (storage) absl::Mutex;
1735*9356374aSAndroid Build Coastguard Worker     alive[i] = true;
1736*9356374aSAndroid Build Coastguard Worker     mu->EnableDebugLog("Mutex");
1737*9356374aSAndroid Build Coastguard Worker     mu->EnableInvariantDebugging(invariant, &alive[i]);
1738*9356374aSAndroid Build Coastguard Worker     mu->Lock();
1739*9356374aSAndroid Build Coastguard Worker     mu->Unlock();
1740*9356374aSAndroid Build Coastguard Worker     mu->~Mutex();
1741*9356374aSAndroid Build Coastguard Worker     alive[i] = false;
1742*9356374aSAndroid Build Coastguard Worker   }
1743*9356374aSAndroid Build Coastguard Worker }
1744*9356374aSAndroid Build Coastguard Worker 
1745*9356374aSAndroid Build Coastguard Worker TEST(Mutex, LoggingBankrupcy) {
1746*9356374aSAndroid Build Coastguard Worker   // Test the case with too many live Mutexes with debug logging.
1747*9356374aSAndroid Build Coastguard Worker   ScopedInvariantDebugging scoped_debugging;
1748*9356374aSAndroid Build Coastguard Worker   std::vector<absl::Mutex> mus(1 << 20);
1749*9356374aSAndroid Build Coastguard Worker   for (auto &mu : mus) {
1750*9356374aSAndroid Build Coastguard Worker     mu.EnableDebugLog("Mutex");
1751*9356374aSAndroid Build Coastguard Worker   }
1752*9356374aSAndroid Build Coastguard Worker }
1753*9356374aSAndroid Build Coastguard Worker 
1754*9356374aSAndroid Build Coastguard Worker TEST(Mutex, SynchEventRace) {
1755*9356374aSAndroid Build Coastguard Worker   // Regression test for a false TSan race report in
1756*9356374aSAndroid Build Coastguard Worker   // EnableInvariantDebugging/EnableDebugLog related to SynchEvent reuse.
1757*9356374aSAndroid Build Coastguard Worker   ScopedInvariantDebugging scoped_debugging;
1758*9356374aSAndroid Build Coastguard Worker   std::vector<std::thread> threads;
1759*9356374aSAndroid Build Coastguard Worker   for (size_t i = 0; i < 5; i++) {
1760*9356374aSAndroid Build Coastguard Worker     threads.emplace_back([&] {
1761*9356374aSAndroid Build Coastguard Worker       for (size_t j = 0; j < (1 << 17); j++) {
1762*9356374aSAndroid Build Coastguard Worker         {
1763*9356374aSAndroid Build Coastguard Worker           absl::Mutex mu;
1764*9356374aSAndroid Build Coastguard Worker           mu.EnableInvariantDebugging([](void *) {}, nullptr);
1765*9356374aSAndroid Build Coastguard Worker           mu.Lock();
1766*9356374aSAndroid Build Coastguard Worker           mu.Unlock();
1767*9356374aSAndroid Build Coastguard Worker         }
1768*9356374aSAndroid Build Coastguard Worker         {
1769*9356374aSAndroid Build Coastguard Worker           absl::Mutex mu;
1770*9356374aSAndroid Build Coastguard Worker           mu.EnableDebugLog("Mutex");
1771*9356374aSAndroid Build Coastguard Worker         }
1772*9356374aSAndroid Build Coastguard Worker       }
1773*9356374aSAndroid Build Coastguard Worker     });
1774*9356374aSAndroid Build Coastguard Worker   }
1775*9356374aSAndroid Build Coastguard Worker   for (auto &thread : threads) {
1776*9356374aSAndroid Build Coastguard Worker     thread.join();
1777*9356374aSAndroid Build Coastguard Worker   }
1778*9356374aSAndroid Build Coastguard Worker }
1779*9356374aSAndroid Build Coastguard Worker 
1780*9356374aSAndroid Build Coastguard Worker // --------------------------------------------------------
1781*9356374aSAndroid Build Coastguard Worker 
1782*9356374aSAndroid Build Coastguard Worker // Generate the vector of thread counts for tests parameterized on thread count.
1783*9356374aSAndroid Build Coastguard Worker static std::vector<int> AllThreadCountValues() {
1784*9356374aSAndroid Build Coastguard Worker   if (kExtendedTest) {
1785*9356374aSAndroid Build Coastguard Worker     return {2, 4, 8, 10, 16, 20, 24, 30, 32};
1786*9356374aSAndroid Build Coastguard Worker   }
1787*9356374aSAndroid Build Coastguard Worker   return {2, 4, 10};
1788*9356374aSAndroid Build Coastguard Worker }
1789*9356374aSAndroid Build Coastguard Worker 
1790*9356374aSAndroid Build Coastguard Worker // A test fixture parameterized by thread count.
1791*9356374aSAndroid Build Coastguard Worker class MutexVariableThreadCountTest : public ::testing::TestWithParam<int> {};
1792*9356374aSAndroid Build Coastguard Worker 
1793*9356374aSAndroid Build Coastguard Worker // Instantiate the above with AllThreadCountOptions().
1794*9356374aSAndroid Build Coastguard Worker INSTANTIATE_TEST_SUITE_P(ThreadCounts, MutexVariableThreadCountTest,
1795*9356374aSAndroid Build Coastguard Worker                          ::testing::ValuesIn(AllThreadCountValues()),
1796*9356374aSAndroid Build Coastguard Worker                          ::testing::PrintToStringParamName());
1797*9356374aSAndroid Build Coastguard Worker 
1798*9356374aSAndroid Build Coastguard Worker // Reduces iterations by some factor for slow platforms
1799*9356374aSAndroid Build Coastguard Worker // (determined empirically).
1800*9356374aSAndroid Build Coastguard Worker static int ScaleIterations(int x) {
1801*9356374aSAndroid Build Coastguard Worker   // ABSL_MUTEX_READER_LOCK_IS_EXCLUSIVE is set in the implementation
1802*9356374aSAndroid Build Coastguard Worker   // of Mutex that uses either std::mutex or pthread_mutex_t. Use
1803*9356374aSAndroid Build Coastguard Worker   // these as keys to determine the slow implementation.
1804*9356374aSAndroid Build Coastguard Worker #if defined(ABSL_MUTEX_READER_LOCK_IS_EXCLUSIVE)
1805*9356374aSAndroid Build Coastguard Worker   return x / 10;
1806*9356374aSAndroid Build Coastguard Worker #else
1807*9356374aSAndroid Build Coastguard Worker   return x;
1808*9356374aSAndroid Build Coastguard Worker #endif
1809*9356374aSAndroid Build Coastguard Worker }
1810*9356374aSAndroid Build Coastguard Worker 
1811*9356374aSAndroid Build Coastguard Worker TEST_P(MutexVariableThreadCountTest, Mutex) {
1812*9356374aSAndroid Build Coastguard Worker   int threads = GetParam();
1813*9356374aSAndroid Build Coastguard Worker   int iterations = ScaleIterations(10000000) / threads;
1814*9356374aSAndroid Build Coastguard Worker   int operations = threads * iterations;
1815*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(RunTest(&TestMu, threads, iterations, operations), operations);
1816*9356374aSAndroid Build Coastguard Worker #if !defined(ABSL_MUTEX_ENABLE_INVARIANT_DEBUGGING_NOT_IMPLEMENTED)
1817*9356374aSAndroid Build Coastguard Worker   iterations = std::min(iterations, 10);
1818*9356374aSAndroid Build Coastguard Worker   operations = threads * iterations;
1819*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(RunTestWithInvariantDebugging(&TestMu, threads, iterations,
1820*9356374aSAndroid Build Coastguard Worker                                           operations, CheckSumG0G1),
1821*9356374aSAndroid Build Coastguard Worker             operations);
1822*9356374aSAndroid Build Coastguard Worker #endif
1823*9356374aSAndroid Build Coastguard Worker }
1824*9356374aSAndroid Build Coastguard Worker 
1825*9356374aSAndroid Build Coastguard Worker TEST_P(MutexVariableThreadCountTest, Try) {
1826*9356374aSAndroid Build Coastguard Worker   int threads = GetParam();
1827*9356374aSAndroid Build Coastguard Worker   int iterations = 1000000 / threads;
1828*9356374aSAndroid Build Coastguard Worker   int operations = iterations * threads;
1829*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(RunTest(&TestTry, threads, iterations, operations), operations);
1830*9356374aSAndroid Build Coastguard Worker #if !defined(ABSL_MUTEX_ENABLE_INVARIANT_DEBUGGING_NOT_IMPLEMENTED)
1831*9356374aSAndroid Build Coastguard Worker   iterations = std::min(iterations, 10);
1832*9356374aSAndroid Build Coastguard Worker   operations = threads * iterations;
1833*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(RunTestWithInvariantDebugging(&TestTry, threads, iterations,
1834*9356374aSAndroid Build Coastguard Worker                                           operations, CheckSumG0G1),
1835*9356374aSAndroid Build Coastguard Worker             operations);
1836*9356374aSAndroid Build Coastguard Worker #endif
1837*9356374aSAndroid Build Coastguard Worker }
1838*9356374aSAndroid Build Coastguard Worker 
1839*9356374aSAndroid Build Coastguard Worker TEST_P(MutexVariableThreadCountTest, R20ms) {
1840*9356374aSAndroid Build Coastguard Worker   int threads = GetParam();
1841*9356374aSAndroid Build Coastguard Worker   int iterations = 100;
1842*9356374aSAndroid Build Coastguard Worker   int operations = iterations * threads;
1843*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(RunTest(&TestR20ms, threads, iterations, operations), 0);
1844*9356374aSAndroid Build Coastguard Worker }
1845*9356374aSAndroid Build Coastguard Worker 
1846*9356374aSAndroid Build Coastguard Worker TEST_P(MutexVariableThreadCountTest, RW) {
1847*9356374aSAndroid Build Coastguard Worker   int threads = GetParam();
1848*9356374aSAndroid Build Coastguard Worker   int iterations = ScaleIterations(20000000) / threads;
1849*9356374aSAndroid Build Coastguard Worker   int operations = iterations * threads;
1850*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(RunTest(&TestRW, threads, iterations, operations), operations / 2);
1851*9356374aSAndroid Build Coastguard Worker #if !defined(ABSL_MUTEX_ENABLE_INVARIANT_DEBUGGING_NOT_IMPLEMENTED)
1852*9356374aSAndroid Build Coastguard Worker   iterations = std::min(iterations, 10);
1853*9356374aSAndroid Build Coastguard Worker   operations = threads * iterations;
1854*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(RunTestWithInvariantDebugging(&TestRW, threads, iterations,
1855*9356374aSAndroid Build Coastguard Worker                                           operations, CheckSumG0G1),
1856*9356374aSAndroid Build Coastguard Worker             operations / 2);
1857*9356374aSAndroid Build Coastguard Worker #endif
1858*9356374aSAndroid Build Coastguard Worker }
1859*9356374aSAndroid Build Coastguard Worker 
1860*9356374aSAndroid Build Coastguard Worker TEST_P(MutexVariableThreadCountTest, Await) {
1861*9356374aSAndroid Build Coastguard Worker   int threads = GetParam();
1862*9356374aSAndroid Build Coastguard Worker   int iterations = ScaleIterations(500000);
1863*9356374aSAndroid Build Coastguard Worker   int operations = iterations;
1864*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(RunTest(&TestAwait, threads, iterations, operations), operations);
1865*9356374aSAndroid Build Coastguard Worker }
1866*9356374aSAndroid Build Coastguard Worker 
1867*9356374aSAndroid Build Coastguard Worker TEST_P(MutexVariableThreadCountTest, SignalAll) {
1868*9356374aSAndroid Build Coastguard Worker   int threads = GetParam();
1869*9356374aSAndroid Build Coastguard Worker   int iterations = 200000 / threads;
1870*9356374aSAndroid Build Coastguard Worker   int operations = iterations;
1871*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(RunTest(&TestSignalAll, threads, iterations, operations),
1872*9356374aSAndroid Build Coastguard Worker             operations);
1873*9356374aSAndroid Build Coastguard Worker }
1874*9356374aSAndroid Build Coastguard Worker 
1875*9356374aSAndroid Build Coastguard Worker TEST(Mutex, Signal) {
1876*9356374aSAndroid Build Coastguard Worker   int threads = 2;  // TestSignal must use two threads
1877*9356374aSAndroid Build Coastguard Worker   int iterations = 200000;
1878*9356374aSAndroid Build Coastguard Worker   int operations = iterations;
1879*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(RunTest(&TestSignal, threads, iterations, operations), operations);
1880*9356374aSAndroid Build Coastguard Worker }
1881*9356374aSAndroid Build Coastguard Worker 
1882*9356374aSAndroid Build Coastguard Worker TEST(Mutex, Timed) {
1883*9356374aSAndroid Build Coastguard Worker   int threads = 10;  // Use a fixed thread count of 10
1884*9356374aSAndroid Build Coastguard Worker   int iterations = 1000;
1885*9356374aSAndroid Build Coastguard Worker   int operations = iterations;
1886*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(RunTest(&TestCVTimeout, threads, iterations, operations),
1887*9356374aSAndroid Build Coastguard Worker             operations);
1888*9356374aSAndroid Build Coastguard Worker }
1889*9356374aSAndroid Build Coastguard Worker 
1890*9356374aSAndroid Build Coastguard Worker TEST(Mutex, CVTime) {
1891*9356374aSAndroid Build Coastguard Worker   int threads = 10;  // Use a fixed thread count of 10
1892*9356374aSAndroid Build Coastguard Worker   int iterations = 1;
1893*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(RunTest(&TestCVTime, threads, iterations, 1), threads * iterations);
1894*9356374aSAndroid Build Coastguard Worker }
1895*9356374aSAndroid Build Coastguard Worker 
1896*9356374aSAndroid Build Coastguard Worker TEST(Mutex, MuTime) {
1897*9356374aSAndroid Build Coastguard Worker   int threads = 10;  // Use a fixed thread count of 10
1898*9356374aSAndroid Build Coastguard Worker   int iterations = 1;
1899*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(RunTest(&TestMuTime, threads, iterations, 1), threads * iterations);
1900*9356374aSAndroid Build Coastguard Worker }
1901*9356374aSAndroid Build Coastguard Worker 
1902*9356374aSAndroid Build Coastguard Worker TEST(Mutex, SignalExitedThread) {
1903*9356374aSAndroid Build Coastguard Worker   // The test may expose a race when Mutex::Unlock signals a thread
1904*9356374aSAndroid Build Coastguard Worker   // that has already exited.
1905*9356374aSAndroid Build Coastguard Worker #if defined(__wasm__) || defined(__asmjs__)
1906*9356374aSAndroid Build Coastguard Worker   constexpr int kThreads = 1;  // OOMs under WASM
1907*9356374aSAndroid Build Coastguard Worker #else
1908*9356374aSAndroid Build Coastguard Worker   constexpr int kThreads = 100;
1909*9356374aSAndroid Build Coastguard Worker #endif
1910*9356374aSAndroid Build Coastguard Worker   std::vector<std::thread> top;
1911*9356374aSAndroid Build Coastguard Worker   for (unsigned i = 0; i < 2 * std::thread::hardware_concurrency(); i++) {
1912*9356374aSAndroid Build Coastguard Worker     top.emplace_back([&]() {
1913*9356374aSAndroid Build Coastguard Worker       for (int i = 0; i < kThreads; i++) {
1914*9356374aSAndroid Build Coastguard Worker         absl::Mutex mu;
1915*9356374aSAndroid Build Coastguard Worker         std::thread t([&]() {
1916*9356374aSAndroid Build Coastguard Worker           mu.Lock();
1917*9356374aSAndroid Build Coastguard Worker           mu.Unlock();
1918*9356374aSAndroid Build Coastguard Worker         });
1919*9356374aSAndroid Build Coastguard Worker         mu.Lock();
1920*9356374aSAndroid Build Coastguard Worker         mu.Unlock();
1921*9356374aSAndroid Build Coastguard Worker         t.join();
1922*9356374aSAndroid Build Coastguard Worker       }
1923*9356374aSAndroid Build Coastguard Worker     });
1924*9356374aSAndroid Build Coastguard Worker   }
1925*9356374aSAndroid Build Coastguard Worker   for (auto &th : top) th.join();
1926*9356374aSAndroid Build Coastguard Worker }
1927*9356374aSAndroid Build Coastguard Worker 
1928*9356374aSAndroid Build Coastguard Worker TEST(Mutex, WriterPriority) {
1929*9356374aSAndroid Build Coastguard Worker   absl::Mutex mu;
1930*9356374aSAndroid Build Coastguard Worker   bool wrote = false;
1931*9356374aSAndroid Build Coastguard Worker   std::atomic<bool> saw_wrote{false};
1932*9356374aSAndroid Build Coastguard Worker   auto readfunc = [&]() {
1933*9356374aSAndroid Build Coastguard Worker     for (size_t i = 0; i < 10; ++i) {
1934*9356374aSAndroid Build Coastguard Worker       absl::ReaderMutexLock lock(&mu);
1935*9356374aSAndroid Build Coastguard Worker       if (wrote) {
1936*9356374aSAndroid Build Coastguard Worker         saw_wrote = true;
1937*9356374aSAndroid Build Coastguard Worker         break;
1938*9356374aSAndroid Build Coastguard Worker       }
1939*9356374aSAndroid Build Coastguard Worker       absl::SleepFor(absl::Seconds(1));
1940*9356374aSAndroid Build Coastguard Worker     }
1941*9356374aSAndroid Build Coastguard Worker   };
1942*9356374aSAndroid Build Coastguard Worker   std::thread t1(readfunc);
1943*9356374aSAndroid Build Coastguard Worker   absl::SleepFor(absl::Milliseconds(500));
1944*9356374aSAndroid Build Coastguard Worker   std::thread t2(readfunc);
1945*9356374aSAndroid Build Coastguard Worker   // Note: this test guards against a bug that was related to an uninit
1946*9356374aSAndroid Build Coastguard Worker   // PerThreadSynch::priority, so the writer intentionally runs on a new thread.
1947*9356374aSAndroid Build Coastguard Worker   std::thread t3([&]() {
1948*9356374aSAndroid Build Coastguard Worker     // The writer should be able squeeze between the two alternating readers.
1949*9356374aSAndroid Build Coastguard Worker     absl::MutexLock lock(&mu);
1950*9356374aSAndroid Build Coastguard Worker     wrote = true;
1951*9356374aSAndroid Build Coastguard Worker   });
1952*9356374aSAndroid Build Coastguard Worker   t1.join();
1953*9356374aSAndroid Build Coastguard Worker   t2.join();
1954*9356374aSAndroid Build Coastguard Worker   t3.join();
1955*9356374aSAndroid Build Coastguard Worker   EXPECT_TRUE(saw_wrote.load());
1956*9356374aSAndroid Build Coastguard Worker }
1957*9356374aSAndroid Build Coastguard Worker 
1958*9356374aSAndroid Build Coastguard Worker #ifdef ABSL_HAVE_PTHREAD_GETSCHEDPARAM
1959*9356374aSAndroid Build Coastguard Worker TEST(Mutex, CondVarPriority) {
1960*9356374aSAndroid Build Coastguard Worker   // A regression test for a bug in condition variable wait morphing,
1961*9356374aSAndroid Build Coastguard Worker   // which resulted in the waiting thread getting priority of the waking thread.
1962*9356374aSAndroid Build Coastguard Worker   int err = 0;
1963*9356374aSAndroid Build Coastguard Worker   sched_param param;
1964*9356374aSAndroid Build Coastguard Worker   param.sched_priority = 7;
1965*9356374aSAndroid Build Coastguard Worker   std::thread test([&]() {
1966*9356374aSAndroid Build Coastguard Worker     err = pthread_setschedparam(pthread_self(), SCHED_FIFO, &param);
1967*9356374aSAndroid Build Coastguard Worker   });
1968*9356374aSAndroid Build Coastguard Worker   test.join();
1969*9356374aSAndroid Build Coastguard Worker   if (err) {
1970*9356374aSAndroid Build Coastguard Worker     // Setting priority usually requires special privileges.
1971*9356374aSAndroid Build Coastguard Worker     GTEST_SKIP() << "failed to set priority: " << strerror(err);
1972*9356374aSAndroid Build Coastguard Worker   }
1973*9356374aSAndroid Build Coastguard Worker   absl::Mutex mu;
1974*9356374aSAndroid Build Coastguard Worker   absl::CondVar cv;
1975*9356374aSAndroid Build Coastguard Worker   bool locked = false;
1976*9356374aSAndroid Build Coastguard Worker   bool notified = false;
1977*9356374aSAndroid Build Coastguard Worker   bool waiting = false;
1978*9356374aSAndroid Build Coastguard Worker   bool morph = false;
1979*9356374aSAndroid Build Coastguard Worker   std::thread th([&]() {
1980*9356374aSAndroid Build Coastguard Worker     EXPECT_EQ(0, pthread_setschedparam(pthread_self(), SCHED_FIFO, &param));
1981*9356374aSAndroid Build Coastguard Worker     mu.Lock();
1982*9356374aSAndroid Build Coastguard Worker     locked = true;
1983*9356374aSAndroid Build Coastguard Worker     mu.Await(absl::Condition(&notified));
1984*9356374aSAndroid Build Coastguard Worker     mu.Unlock();
1985*9356374aSAndroid Build Coastguard Worker     EXPECT_EQ(absl::synchronization_internal::GetOrCreateCurrentThreadIdentity()
1986*9356374aSAndroid Build Coastguard Worker                   ->per_thread_synch.priority,
1987*9356374aSAndroid Build Coastguard Worker               param.sched_priority);
1988*9356374aSAndroid Build Coastguard Worker     mu.Lock();
1989*9356374aSAndroid Build Coastguard Worker     mu.Await(absl::Condition(&waiting));
1990*9356374aSAndroid Build Coastguard Worker     morph = true;
1991*9356374aSAndroid Build Coastguard Worker     absl::SleepFor(absl::Seconds(1));
1992*9356374aSAndroid Build Coastguard Worker     cv.Signal();
1993*9356374aSAndroid Build Coastguard Worker     mu.Unlock();
1994*9356374aSAndroid Build Coastguard Worker   });
1995*9356374aSAndroid Build Coastguard Worker   mu.Lock();
1996*9356374aSAndroid Build Coastguard Worker   mu.Await(absl::Condition(&locked));
1997*9356374aSAndroid Build Coastguard Worker   notified = true;
1998*9356374aSAndroid Build Coastguard Worker   mu.Unlock();
1999*9356374aSAndroid Build Coastguard Worker   mu.Lock();
2000*9356374aSAndroid Build Coastguard Worker   waiting = true;
2001*9356374aSAndroid Build Coastguard Worker   while (!morph) {
2002*9356374aSAndroid Build Coastguard Worker     cv.Wait(&mu);
2003*9356374aSAndroid Build Coastguard Worker   }
2004*9356374aSAndroid Build Coastguard Worker   mu.Unlock();
2005*9356374aSAndroid Build Coastguard Worker   th.join();
2006*9356374aSAndroid Build Coastguard Worker   EXPECT_NE(absl::synchronization_internal::GetOrCreateCurrentThreadIdentity()
2007*9356374aSAndroid Build Coastguard Worker                 ->per_thread_synch.priority,
2008*9356374aSAndroid Build Coastguard Worker             param.sched_priority);
2009*9356374aSAndroid Build Coastguard Worker }
2010*9356374aSAndroid Build Coastguard Worker #endif
2011*9356374aSAndroid Build Coastguard Worker 
2012*9356374aSAndroid Build Coastguard Worker TEST(Mutex, LockWhenWithTimeoutResult) {
2013*9356374aSAndroid Build Coastguard Worker   // Check various corner cases for Await/LockWhen return value
2014*9356374aSAndroid Build Coastguard Worker   // with always true/always false conditions.
2015*9356374aSAndroid Build Coastguard Worker   absl::Mutex mu;
2016*9356374aSAndroid Build Coastguard Worker   const bool kAlwaysTrue = true, kAlwaysFalse = false;
2017*9356374aSAndroid Build Coastguard Worker   const absl::Condition kTrueCond(&kAlwaysTrue), kFalseCond(&kAlwaysFalse);
2018*9356374aSAndroid Build Coastguard Worker   EXPECT_TRUE(mu.LockWhenWithTimeout(kTrueCond, absl::Milliseconds(1)));
2019*9356374aSAndroid Build Coastguard Worker   mu.Unlock();
2020*9356374aSAndroid Build Coastguard Worker   EXPECT_FALSE(mu.LockWhenWithTimeout(kFalseCond, absl::Milliseconds(1)));
2021*9356374aSAndroid Build Coastguard Worker   EXPECT_TRUE(mu.AwaitWithTimeout(kTrueCond, absl::Milliseconds(1)));
2022*9356374aSAndroid Build Coastguard Worker   EXPECT_FALSE(mu.AwaitWithTimeout(kFalseCond, absl::Milliseconds(1)));
2023*9356374aSAndroid Build Coastguard Worker   std::thread th1([&]() {
2024*9356374aSAndroid Build Coastguard Worker     EXPECT_TRUE(mu.LockWhenWithTimeout(kTrueCond, absl::Milliseconds(1)));
2025*9356374aSAndroid Build Coastguard Worker     mu.Unlock();
2026*9356374aSAndroid Build Coastguard Worker   });
2027*9356374aSAndroid Build Coastguard Worker   std::thread th2([&]() {
2028*9356374aSAndroid Build Coastguard Worker     EXPECT_FALSE(mu.LockWhenWithTimeout(kFalseCond, absl::Milliseconds(1)));
2029*9356374aSAndroid Build Coastguard Worker     mu.Unlock();
2030*9356374aSAndroid Build Coastguard Worker   });
2031*9356374aSAndroid Build Coastguard Worker   absl::SleepFor(absl::Milliseconds(100));
2032*9356374aSAndroid Build Coastguard Worker   mu.Unlock();
2033*9356374aSAndroid Build Coastguard Worker   th1.join();
2034*9356374aSAndroid Build Coastguard Worker   th2.join();
2035*9356374aSAndroid Build Coastguard Worker }
2036*9356374aSAndroid Build Coastguard Worker 
2037*9356374aSAndroid Build Coastguard Worker }  // namespace
2038