mutex_test.cc 54 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707
  1. // Copyright 2017 The Abseil Authors.
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // https://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. #include "absl/synchronization/mutex.h"
  15. #ifdef _WIN32
  16. #include <windows.h>
  17. #endif
  18. #include <algorithm>
  19. #include <atomic>
  20. #include <cstdlib>
  21. #include <functional>
  22. #include <memory>
  23. #include <random>
  24. #include <string>
  25. #include <thread> // NOLINT(build/c++11)
  26. #include <type_traits>
  27. #include <vector>
  28. #include "gtest/gtest.h"
  29. #include "absl/base/attributes.h"
  30. #include "absl/base/config.h"
  31. #include "absl/base/internal/raw_logging.h"
  32. #include "absl/base/internal/sysinfo.h"
  33. #include "absl/memory/memory.h"
  34. #include "absl/synchronization/internal/thread_pool.h"
  35. #include "absl/time/clock.h"
  36. #include "absl/time/time.h"
  37. namespace {
  38. // TODO(dmauro): Replace with a commandline flag.
  39. static constexpr bool kExtendedTest = false;
  40. std::unique_ptr<absl::synchronization_internal::ThreadPool> CreatePool(
  41. int threads) {
  42. return absl::make_unique<absl::synchronization_internal::ThreadPool>(threads);
  43. }
  44. std::unique_ptr<absl::synchronization_internal::ThreadPool>
  45. CreateDefaultPool() {
  46. return CreatePool(kExtendedTest ? 32 : 10);
  47. }
  48. // Hack to schedule a function to run on a thread pool thread after a
  49. // duration has elapsed.
  50. static void ScheduleAfter(absl::synchronization_internal::ThreadPool *tp,
  51. absl::Duration after,
  52. const std::function<void()> &func) {
  53. tp->Schedule([func, after] {
  54. absl::SleepFor(after);
  55. func();
  56. });
  57. }
  58. struct TestContext {
  59. int iterations;
  60. int threads;
  61. int g0; // global 0
  62. int g1; // global 1
  63. absl::Mutex mu;
  64. absl::CondVar cv;
  65. };
  66. // To test whether the invariant check call occurs
  67. static std::atomic<bool> invariant_checked;
  68. static bool GetInvariantChecked() {
  69. return invariant_checked.load(std::memory_order_relaxed);
  70. }
  71. static void SetInvariantChecked(bool new_value) {
  72. invariant_checked.store(new_value, std::memory_order_relaxed);
  73. }
  74. static void CheckSumG0G1(void *v) {
  75. TestContext *cxt = static_cast<TestContext *>(v);
  76. ABSL_RAW_CHECK(cxt->g0 == -cxt->g1, "Error in CheckSumG0G1");
  77. SetInvariantChecked(true);
  78. }
  79. static void TestMu(TestContext *cxt, int c) {
  80. for (int i = 0; i != cxt->iterations; i++) {
  81. absl::MutexLock l(&cxt->mu);
  82. int a = cxt->g0 + 1;
  83. cxt->g0 = a;
  84. cxt->g1--;
  85. }
  86. }
  87. static void TestTry(TestContext *cxt, int c) {
  88. for (int i = 0; i != cxt->iterations; i++) {
  89. do {
  90. std::this_thread::yield();
  91. } while (!cxt->mu.TryLock());
  92. int a = cxt->g0 + 1;
  93. cxt->g0 = a;
  94. cxt->g1--;
  95. cxt->mu.Unlock();
  96. }
  97. }
  98. static void TestR20ms(TestContext *cxt, int c) {
  99. for (int i = 0; i != cxt->iterations; i++) {
  100. absl::ReaderMutexLock l(&cxt->mu);
  101. absl::SleepFor(absl::Milliseconds(20));
  102. cxt->mu.AssertReaderHeld();
  103. }
  104. }
  105. static void TestRW(TestContext *cxt, int c) {
  106. if ((c & 1) == 0) {
  107. for (int i = 0; i != cxt->iterations; i++) {
  108. absl::WriterMutexLock l(&cxt->mu);
  109. cxt->g0++;
  110. cxt->g1--;
  111. cxt->mu.AssertHeld();
  112. cxt->mu.AssertReaderHeld();
  113. }
  114. } else {
  115. for (int i = 0; i != cxt->iterations; i++) {
  116. absl::ReaderMutexLock l(&cxt->mu);
  117. ABSL_RAW_CHECK(cxt->g0 == -cxt->g1, "Error in TestRW");
  118. cxt->mu.AssertReaderHeld();
  119. }
  120. }
  121. }
  122. struct MyContext {
  123. int target;
  124. TestContext *cxt;
  125. bool MyTurn();
  126. };
  127. bool MyContext::MyTurn() {
  128. TestContext *cxt = this->cxt;
  129. return cxt->g0 == this->target || cxt->g0 == cxt->iterations;
  130. }
  131. static void TestAwait(TestContext *cxt, int c) {
  132. MyContext mc;
  133. mc.target = c;
  134. mc.cxt = cxt;
  135. absl::MutexLock l(&cxt->mu);
  136. cxt->mu.AssertHeld();
  137. while (cxt->g0 < cxt->iterations) {
  138. cxt->mu.Await(absl::Condition(&mc, &MyContext::MyTurn));
  139. ABSL_RAW_CHECK(mc.MyTurn(), "Error in TestAwait");
  140. cxt->mu.AssertHeld();
  141. if (cxt->g0 < cxt->iterations) {
  142. int a = cxt->g0 + 1;
  143. cxt->g0 = a;
  144. mc.target += cxt->threads;
  145. }
  146. }
  147. }
  148. static void TestSignalAll(TestContext *cxt, int c) {
  149. int target = c;
  150. absl::MutexLock l(&cxt->mu);
  151. cxt->mu.AssertHeld();
  152. while (cxt->g0 < cxt->iterations) {
  153. while (cxt->g0 != target && cxt->g0 != cxt->iterations) {
  154. cxt->cv.Wait(&cxt->mu);
  155. }
  156. if (cxt->g0 < cxt->iterations) {
  157. int a = cxt->g0 + 1;
  158. cxt->g0 = a;
  159. cxt->cv.SignalAll();
  160. target += cxt->threads;
  161. }
  162. }
  163. }
  164. static void TestSignal(TestContext *cxt, int c) {
  165. ABSL_RAW_CHECK(cxt->threads == 2, "TestSignal should use 2 threads");
  166. int target = c;
  167. absl::MutexLock l(&cxt->mu);
  168. cxt->mu.AssertHeld();
  169. while (cxt->g0 < cxt->iterations) {
  170. while (cxt->g0 != target && cxt->g0 != cxt->iterations) {
  171. cxt->cv.Wait(&cxt->mu);
  172. }
  173. if (cxt->g0 < cxt->iterations) {
  174. int a = cxt->g0 + 1;
  175. cxt->g0 = a;
  176. cxt->cv.Signal();
  177. target += cxt->threads;
  178. }
  179. }
  180. }
  181. static void TestCVTimeout(TestContext *cxt, int c) {
  182. int target = c;
  183. absl::MutexLock l(&cxt->mu);
  184. cxt->mu.AssertHeld();
  185. while (cxt->g0 < cxt->iterations) {
  186. while (cxt->g0 != target && cxt->g0 != cxt->iterations) {
  187. cxt->cv.WaitWithTimeout(&cxt->mu, absl::Seconds(100));
  188. }
  189. if (cxt->g0 < cxt->iterations) {
  190. int a = cxt->g0 + 1;
  191. cxt->g0 = a;
  192. cxt->cv.SignalAll();
  193. target += cxt->threads;
  194. }
  195. }
  196. }
  197. static bool G0GE2(TestContext *cxt) { return cxt->g0 >= 2; }
  198. static void TestTime(TestContext *cxt, int c, bool use_cv) {
  199. ABSL_RAW_CHECK(cxt->iterations == 1, "TestTime should only use 1 iteration");
  200. ABSL_RAW_CHECK(cxt->threads > 2, "TestTime should use more than 2 threads");
  201. const bool kFalse = false;
  202. absl::Condition false_cond(&kFalse);
  203. absl::Condition g0ge2(G0GE2, cxt);
  204. if (c == 0) {
  205. absl::MutexLock l(&cxt->mu);
  206. absl::Time start = absl::Now();
  207. if (use_cv) {
  208. cxt->cv.WaitWithTimeout(&cxt->mu, absl::Seconds(1));
  209. } else {
  210. ABSL_RAW_CHECK(!cxt->mu.AwaitWithTimeout(false_cond, absl::Seconds(1)),
  211. "TestTime failed");
  212. }
  213. absl::Duration elapsed = absl::Now() - start;
  214. ABSL_RAW_CHECK(
  215. absl::Seconds(0.9) <= elapsed && elapsed <= absl::Seconds(2.0),
  216. "TestTime failed");
  217. ABSL_RAW_CHECK(cxt->g0 == 1, "TestTime failed");
  218. start = absl::Now();
  219. if (use_cv) {
  220. cxt->cv.WaitWithTimeout(&cxt->mu, absl::Seconds(1));
  221. } else {
  222. ABSL_RAW_CHECK(!cxt->mu.AwaitWithTimeout(false_cond, absl::Seconds(1)),
  223. "TestTime failed");
  224. }
  225. elapsed = absl::Now() - start;
  226. ABSL_RAW_CHECK(
  227. absl::Seconds(0.9) <= elapsed && elapsed <= absl::Seconds(2.0),
  228. "TestTime failed");
  229. cxt->g0++;
  230. if (use_cv) {
  231. cxt->cv.Signal();
  232. }
  233. start = absl::Now();
  234. if (use_cv) {
  235. cxt->cv.WaitWithTimeout(&cxt->mu, absl::Seconds(4));
  236. } else {
  237. ABSL_RAW_CHECK(!cxt->mu.AwaitWithTimeout(false_cond, absl::Seconds(4)),
  238. "TestTime failed");
  239. }
  240. elapsed = absl::Now() - start;
  241. ABSL_RAW_CHECK(
  242. absl::Seconds(3.9) <= elapsed && elapsed <= absl::Seconds(6.0),
  243. "TestTime failed");
  244. ABSL_RAW_CHECK(cxt->g0 >= 3, "TestTime failed");
  245. start = absl::Now();
  246. if (use_cv) {
  247. cxt->cv.WaitWithTimeout(&cxt->mu, absl::Seconds(1));
  248. } else {
  249. ABSL_RAW_CHECK(!cxt->mu.AwaitWithTimeout(false_cond, absl::Seconds(1)),
  250. "TestTime failed");
  251. }
  252. elapsed = absl::Now() - start;
  253. ABSL_RAW_CHECK(
  254. absl::Seconds(0.9) <= elapsed && elapsed <= absl::Seconds(2.0),
  255. "TestTime failed");
  256. if (use_cv) {
  257. cxt->cv.SignalAll();
  258. }
  259. start = absl::Now();
  260. if (use_cv) {
  261. cxt->cv.WaitWithTimeout(&cxt->mu, absl::Seconds(1));
  262. } else {
  263. ABSL_RAW_CHECK(!cxt->mu.AwaitWithTimeout(false_cond, absl::Seconds(1)),
  264. "TestTime failed");
  265. }
  266. elapsed = absl::Now() - start;
  267. ABSL_RAW_CHECK(absl::Seconds(0.9) <= elapsed &&
  268. elapsed <= absl::Seconds(2.0), "TestTime failed");
  269. ABSL_RAW_CHECK(cxt->g0 == cxt->threads, "TestTime failed");
  270. } else if (c == 1) {
  271. absl::MutexLock l(&cxt->mu);
  272. const absl::Time start = absl::Now();
  273. if (use_cv) {
  274. cxt->cv.WaitWithTimeout(&cxt->mu, absl::Milliseconds(500));
  275. } else {
  276. ABSL_RAW_CHECK(
  277. !cxt->mu.AwaitWithTimeout(false_cond, absl::Milliseconds(500)),
  278. "TestTime failed");
  279. }
  280. const absl::Duration elapsed = absl::Now() - start;
  281. ABSL_RAW_CHECK(
  282. absl::Seconds(0.4) <= elapsed && elapsed <= absl::Seconds(0.9),
  283. "TestTime failed");
  284. cxt->g0++;
  285. } else if (c == 2) {
  286. absl::MutexLock l(&cxt->mu);
  287. if (use_cv) {
  288. while (cxt->g0 < 2) {
  289. cxt->cv.WaitWithTimeout(&cxt->mu, absl::Seconds(100));
  290. }
  291. } else {
  292. ABSL_RAW_CHECK(cxt->mu.AwaitWithTimeout(g0ge2, absl::Seconds(100)),
  293. "TestTime failed");
  294. }
  295. cxt->g0++;
  296. } else {
  297. absl::MutexLock l(&cxt->mu);
  298. if (use_cv) {
  299. while (cxt->g0 < 2) {
  300. cxt->cv.Wait(&cxt->mu);
  301. }
  302. } else {
  303. cxt->mu.Await(g0ge2);
  304. }
  305. cxt->g0++;
  306. }
  307. }
  308. static void TestMuTime(TestContext *cxt, int c) { TestTime(cxt, c, false); }
  309. static void TestCVTime(TestContext *cxt, int c) { TestTime(cxt, c, true); }
  310. static void EndTest(int *c0, int *c1, absl::Mutex *mu, absl::CondVar *cv,
  311. const std::function<void(int)>& cb) {
  312. mu->Lock();
  313. int c = (*c0)++;
  314. mu->Unlock();
  315. cb(c);
  316. absl::MutexLock l(mu);
  317. (*c1)++;
  318. cv->Signal();
  319. }
  320. // Code common to RunTest() and RunTestWithInvariantDebugging().
  321. static int RunTestCommon(TestContext *cxt, void (*test)(TestContext *cxt, int),
  322. int threads, int iterations, int operations) {
  323. absl::Mutex mu2;
  324. absl::CondVar cv2;
  325. int c0 = 0;
  326. int c1 = 0;
  327. cxt->g0 = 0;
  328. cxt->g1 = 0;
  329. cxt->iterations = iterations;
  330. cxt->threads = threads;
  331. absl::synchronization_internal::ThreadPool tp(threads);
  332. for (int i = 0; i != threads; i++) {
  333. tp.Schedule(std::bind(&EndTest, &c0, &c1, &mu2, &cv2,
  334. std::function<void(int)>(
  335. std::bind(test, cxt, std::placeholders::_1))));
  336. }
  337. mu2.Lock();
  338. while (c1 != threads) {
  339. cv2.Wait(&mu2);
  340. }
  341. mu2.Unlock();
  342. return cxt->g0;
  343. }
  344. // Basis for the parameterized tests configured below.
  345. static int RunTest(void (*test)(TestContext *cxt, int), int threads,
  346. int iterations, int operations) {
  347. TestContext cxt;
  348. return RunTestCommon(&cxt, test, threads, iterations, operations);
  349. }
  350. // Like RunTest(), but sets an invariant on the tested Mutex and
  351. // verifies that the invariant check happened. The invariant function
  352. // will be passed the TestContext* as its arg and must call
  353. // SetInvariantChecked(true);
  354. #if !defined(ABSL_MUTEX_ENABLE_INVARIANT_DEBUGGING_NOT_IMPLEMENTED)
  355. static int RunTestWithInvariantDebugging(void (*test)(TestContext *cxt, int),
  356. int threads, int iterations,
  357. int operations,
  358. void (*invariant)(void *)) {
  359. absl::EnableMutexInvariantDebugging(true);
  360. SetInvariantChecked(false);
  361. TestContext cxt;
  362. cxt.mu.EnableInvariantDebugging(invariant, &cxt);
  363. int ret = RunTestCommon(&cxt, test, threads, iterations, operations);
  364. ABSL_RAW_CHECK(GetInvariantChecked(), "Invariant not checked");
  365. absl::EnableMutexInvariantDebugging(false); // Restore.
  366. return ret;
  367. }
  368. #endif
  369. // --------------------------------------------------------
  370. // Test for fix of bug in TryRemove()
  371. struct TimeoutBugStruct {
  372. absl::Mutex mu;
  373. bool a;
  374. int a_waiter_count;
  375. };
  376. static void WaitForA(TimeoutBugStruct *x) {
  377. x->mu.LockWhen(absl::Condition(&x->a));
  378. x->a_waiter_count--;
  379. x->mu.Unlock();
  380. }
  381. static bool NoAWaiters(TimeoutBugStruct *x) { return x->a_waiter_count == 0; }
  382. // Test that a CondVar.Wait(&mutex) can un-block a call to mutex.Await() in
  383. // another thread.
  384. TEST(Mutex, CondVarWaitSignalsAwait) {
  385. // Use a struct so the lock annotations apply.
  386. struct {
  387. absl::Mutex barrier_mu;
  388. bool barrier ABSL_GUARDED_BY(barrier_mu) = false;
  389. absl::Mutex release_mu;
  390. bool release ABSL_GUARDED_BY(release_mu) = false;
  391. absl::CondVar released_cv;
  392. } state;
  393. auto pool = CreateDefaultPool();
  394. // Thread A. Sets barrier, waits for release using Mutex::Await, then
  395. // signals released_cv.
  396. pool->Schedule([&state] {
  397. state.release_mu.Lock();
  398. state.barrier_mu.Lock();
  399. state.barrier = true;
  400. state.barrier_mu.Unlock();
  401. state.release_mu.Await(absl::Condition(&state.release));
  402. state.released_cv.Signal();
  403. state.release_mu.Unlock();
  404. });
  405. state.barrier_mu.LockWhen(absl::Condition(&state.barrier));
  406. state.barrier_mu.Unlock();
  407. state.release_mu.Lock();
  408. // Thread A is now blocked on release by way of Mutex::Await().
  409. // Set release. Calling released_cv.Wait() should un-block thread A,
  410. // which will signal released_cv. If not, the test will hang.
  411. state.release = true;
  412. state.released_cv.Wait(&state.release_mu);
  413. state.release_mu.Unlock();
  414. }
  415. // Test that a CondVar.WaitWithTimeout(&mutex) can un-block a call to
  416. // mutex.Await() in another thread.
  417. TEST(Mutex, CondVarWaitWithTimeoutSignalsAwait) {
  418. // Use a struct so the lock annotations apply.
  419. struct {
  420. absl::Mutex barrier_mu;
  421. bool barrier ABSL_GUARDED_BY(barrier_mu) = false;
  422. absl::Mutex release_mu;
  423. bool release ABSL_GUARDED_BY(release_mu) = false;
  424. absl::CondVar released_cv;
  425. } state;
  426. auto pool = CreateDefaultPool();
  427. // Thread A. Sets barrier, waits for release using Mutex::Await, then
  428. // signals released_cv.
  429. pool->Schedule([&state] {
  430. state.release_mu.Lock();
  431. state.barrier_mu.Lock();
  432. state.barrier = true;
  433. state.barrier_mu.Unlock();
  434. state.release_mu.Await(absl::Condition(&state.release));
  435. state.released_cv.Signal();
  436. state.release_mu.Unlock();
  437. });
  438. state.barrier_mu.LockWhen(absl::Condition(&state.barrier));
  439. state.barrier_mu.Unlock();
  440. state.release_mu.Lock();
  441. // Thread A is now blocked on release by way of Mutex::Await().
  442. // Set release. Calling released_cv.Wait() should un-block thread A,
  443. // which will signal released_cv. If not, the test will hang.
  444. state.release = true;
  445. EXPECT_TRUE(
  446. !state.released_cv.WaitWithTimeout(&state.release_mu, absl::Seconds(10)))
  447. << "; Unrecoverable test failure: CondVar::WaitWithTimeout did not "
  448. "unblock the absl::Mutex::Await call in another thread.";
  449. state.release_mu.Unlock();
  450. }
  451. // Test for regression of a bug in loop of TryRemove()
  452. TEST(Mutex, MutexTimeoutBug) {
  453. auto tp = CreateDefaultPool();
  454. TimeoutBugStruct x;
  455. x.a = false;
  456. x.a_waiter_count = 2;
  457. tp->Schedule(std::bind(&WaitForA, &x));
  458. tp->Schedule(std::bind(&WaitForA, &x));
  459. absl::SleepFor(absl::Seconds(1)); // Allow first two threads to hang.
  460. // The skip field of the second will point to the first because there are
  461. // only two.
  462. // Now cause a thread waiting on an always-false to time out
  463. // This would deadlock when the bug was present.
  464. bool always_false = false;
  465. x.mu.LockWhenWithTimeout(absl::Condition(&always_false),
  466. absl::Milliseconds(500));
  467. // if we get here, the bug is not present. Cleanup the state.
  468. x.a = true; // wakeup the two waiters on A
  469. x.mu.Await(absl::Condition(&NoAWaiters, &x)); // wait for them to exit
  470. x.mu.Unlock();
  471. }
  472. struct CondVarWaitDeadlock : testing::TestWithParam<int> {
  473. absl::Mutex mu;
  474. absl::CondVar cv;
  475. bool cond1 = false;
  476. bool cond2 = false;
  477. bool read_lock1;
  478. bool read_lock2;
  479. bool signal_unlocked;
  480. CondVarWaitDeadlock() {
  481. read_lock1 = GetParam() & (1 << 0);
  482. read_lock2 = GetParam() & (1 << 1);
  483. signal_unlocked = GetParam() & (1 << 2);
  484. }
  485. void Waiter1() {
  486. if (read_lock1) {
  487. mu.ReaderLock();
  488. while (!cond1) {
  489. cv.Wait(&mu);
  490. }
  491. mu.ReaderUnlock();
  492. } else {
  493. mu.Lock();
  494. while (!cond1) {
  495. cv.Wait(&mu);
  496. }
  497. mu.Unlock();
  498. }
  499. }
  500. void Waiter2() {
  501. if (read_lock2) {
  502. mu.ReaderLockWhen(absl::Condition(&cond2));
  503. mu.ReaderUnlock();
  504. } else {
  505. mu.LockWhen(absl::Condition(&cond2));
  506. mu.Unlock();
  507. }
  508. }
  509. };
  510. // Test for a deadlock bug in Mutex::Fer().
  511. // The sequence of events that lead to the deadlock is:
  512. // 1. waiter1 blocks on cv in read mode (mu bits = 0).
  513. // 2. waiter2 blocks on mu in either mode (mu bits = kMuWait).
  514. // 3. main thread locks mu, sets cond1, unlocks mu (mu bits = kMuWait).
  515. // 4. main thread signals on cv and this eventually calls Mutex::Fer().
  516. // Currently Fer wakes waiter1 since mu bits = kMuWait (mutex is unlocked).
  517. // Before the bug fix Fer neither woke waiter1 nor queued it on mutex,
  518. // which resulted in deadlock.
  519. TEST_P(CondVarWaitDeadlock, Test) {
  520. auto waiter1 = CreatePool(1);
  521. auto waiter2 = CreatePool(1);
  522. waiter1->Schedule([this] { this->Waiter1(); });
  523. waiter2->Schedule([this] { this->Waiter2(); });
  524. // Wait while threads block (best-effort is fine).
  525. absl::SleepFor(absl::Milliseconds(100));
  526. // Wake condwaiter.
  527. mu.Lock();
  528. cond1 = true;
  529. if (signal_unlocked) {
  530. mu.Unlock();
  531. cv.Signal();
  532. } else {
  533. cv.Signal();
  534. mu.Unlock();
  535. }
  536. waiter1.reset(); // "join" waiter1
  537. // Wake waiter.
  538. mu.Lock();
  539. cond2 = true;
  540. mu.Unlock();
  541. waiter2.reset(); // "join" waiter2
  542. }
  543. INSTANTIATE_TEST_SUITE_P(CondVarWaitDeadlockTest, CondVarWaitDeadlock,
  544. ::testing::Range(0, 8),
  545. ::testing::PrintToStringParamName());
  546. // --------------------------------------------------------
  547. // Test for fix of bug in DequeueAllWakeable()
  548. // Bug was that if there was more than one waiting reader
  549. // and all should be woken, the most recently blocked one
  550. // would not be.
  551. struct DequeueAllWakeableBugStruct {
  552. absl::Mutex mu;
  553. absl::Mutex mu2; // protects all fields below
  554. int unfinished_count; // count of unfinished readers; under mu2
  555. bool done1; // unfinished_count == 0; under mu2
  556. int finished_count; // count of finished readers, under mu2
  557. bool done2; // finished_count == 0; under mu2
  558. };
  559. // Test for regression of a bug in loop of DequeueAllWakeable()
  560. static void AcquireAsReader(DequeueAllWakeableBugStruct *x) {
  561. x->mu.ReaderLock();
  562. x->mu2.Lock();
  563. x->unfinished_count--;
  564. x->done1 = (x->unfinished_count == 0);
  565. x->mu2.Unlock();
  566. // make sure that both readers acquired mu before we release it.
  567. absl::SleepFor(absl::Seconds(2));
  568. x->mu.ReaderUnlock();
  569. x->mu2.Lock();
  570. x->finished_count--;
  571. x->done2 = (x->finished_count == 0);
  572. x->mu2.Unlock();
  573. }
  574. // Test for regression of a bug in loop of DequeueAllWakeable()
  575. TEST(Mutex, MutexReaderWakeupBug) {
  576. auto tp = CreateDefaultPool();
  577. DequeueAllWakeableBugStruct x;
  578. x.unfinished_count = 2;
  579. x.done1 = false;
  580. x.finished_count = 2;
  581. x.done2 = false;
  582. x.mu.Lock(); // acquire mu exclusively
  583. // queue two thread that will block on reader locks on x.mu
  584. tp->Schedule(std::bind(&AcquireAsReader, &x));
  585. tp->Schedule(std::bind(&AcquireAsReader, &x));
  586. absl::SleepFor(absl::Seconds(1)); // give time for reader threads to block
  587. x.mu.Unlock(); // wake them up
  588. // both readers should finish promptly
  589. EXPECT_TRUE(
  590. x.mu2.LockWhenWithTimeout(absl::Condition(&x.done1), absl::Seconds(10)));
  591. x.mu2.Unlock();
  592. EXPECT_TRUE(
  593. x.mu2.LockWhenWithTimeout(absl::Condition(&x.done2), absl::Seconds(10)));
  594. x.mu2.Unlock();
  595. }
  596. struct LockWhenTestStruct {
  597. absl::Mutex mu1;
  598. bool cond = false;
  599. absl::Mutex mu2;
  600. bool waiting = false;
  601. };
  602. static bool LockWhenTestIsCond(LockWhenTestStruct* s) {
  603. s->mu2.Lock();
  604. s->waiting = true;
  605. s->mu2.Unlock();
  606. return s->cond;
  607. }
  608. static void LockWhenTestWaitForIsCond(LockWhenTestStruct* s) {
  609. s->mu1.LockWhen(absl::Condition(&LockWhenTestIsCond, s));
  610. s->mu1.Unlock();
  611. }
  612. TEST(Mutex, LockWhen) {
  613. LockWhenTestStruct s;
  614. std::thread t(LockWhenTestWaitForIsCond, &s);
  615. s.mu2.LockWhen(absl::Condition(&s.waiting));
  616. s.mu2.Unlock();
  617. s.mu1.Lock();
  618. s.cond = true;
  619. s.mu1.Unlock();
  620. t.join();
  621. }
  622. TEST(Mutex, LockWhenGuard) {
  623. absl::Mutex mu;
  624. int n = 30;
  625. bool done = false;
  626. // We don't inline the lambda because the conversion is ambiguous in MSVC.
  627. bool (*cond_eq_10)(int *) = [](int *p) { return *p == 10; };
  628. bool (*cond_lt_10)(int *) = [](int *p) { return *p < 10; };
  629. std::thread t1([&mu, &n, &done, cond_eq_10]() {
  630. absl::ReaderMutexLock lock(&mu, absl::Condition(cond_eq_10, &n));
  631. done = true;
  632. });
  633. std::thread t2[10];
  634. for (std::thread &t : t2) {
  635. t = std::thread([&mu, &n, cond_lt_10]() {
  636. absl::WriterMutexLock lock(&mu, absl::Condition(cond_lt_10, &n));
  637. ++n;
  638. });
  639. }
  640. {
  641. absl::MutexLock lock(&mu);
  642. n = 0;
  643. }
  644. for (std::thread &t : t2) t.join();
  645. t1.join();
  646. EXPECT_TRUE(done);
  647. EXPECT_EQ(n, 10);
  648. }
  649. // --------------------------------------------------------
  650. // The following test requires Mutex::ReaderLock to be a real shared
  651. // lock, which is not the case in all builds.
  652. #if !defined(ABSL_MUTEX_READER_LOCK_IS_EXCLUSIVE)
  653. // Test for fix of bug in UnlockSlow() that incorrectly decremented the reader
  654. // count when putting a thread to sleep waiting for a false condition when the
  655. // lock was not held.
  656. // For this bug to strike, we make a thread wait on a free mutex with no
  657. // waiters by causing its wakeup condition to be false. Then the
  658. // next two acquirers must be readers. The bug causes the lock
  659. // to be released when one reader unlocks, rather than both.
  660. struct ReaderDecrementBugStruct {
  661. bool cond; // to delay first thread (under mu)
  662. int done; // reference count (under mu)
  663. absl::Mutex mu;
  664. bool waiting_on_cond; // under mu2
  665. bool have_reader_lock; // under mu2
  666. bool complete; // under mu2
  667. absl::Mutex mu2; // > mu
  668. };
  669. // L >= mu, L < mu_waiting_on_cond
  670. static bool IsCond(void *v) {
  671. ReaderDecrementBugStruct *x = reinterpret_cast<ReaderDecrementBugStruct *>(v);
  672. x->mu2.Lock();
  673. x->waiting_on_cond = true;
  674. x->mu2.Unlock();
  675. return x->cond;
  676. }
  677. // L >= mu
  678. static bool AllDone(void *v) {
  679. ReaderDecrementBugStruct *x = reinterpret_cast<ReaderDecrementBugStruct *>(v);
  680. return x->done == 0;
  681. }
  682. // L={}
  683. static void WaitForCond(ReaderDecrementBugStruct *x) {
  684. absl::Mutex dummy;
  685. absl::MutexLock l(&dummy);
  686. x->mu.LockWhen(absl::Condition(&IsCond, x));
  687. x->done--;
  688. x->mu.Unlock();
  689. }
  690. // L={}
  691. static void GetReadLock(ReaderDecrementBugStruct *x) {
  692. x->mu.ReaderLock();
  693. x->mu2.Lock();
  694. x->have_reader_lock = true;
  695. x->mu2.Await(absl::Condition(&x->complete));
  696. x->mu2.Unlock();
  697. x->mu.ReaderUnlock();
  698. x->mu.Lock();
  699. x->done--;
  700. x->mu.Unlock();
  701. }
  702. // Test for reader counter being decremented incorrectly by waiter
  703. // with false condition.
  704. TEST(Mutex, MutexReaderDecrementBug) ABSL_NO_THREAD_SAFETY_ANALYSIS {
  705. ReaderDecrementBugStruct x;
  706. x.cond = false;
  707. x.waiting_on_cond = false;
  708. x.have_reader_lock = false;
  709. x.complete = false;
  710. x.done = 2; // initial ref count
  711. // Run WaitForCond() and wait for it to sleep
  712. std::thread thread1(WaitForCond, &x);
  713. x.mu2.LockWhen(absl::Condition(&x.waiting_on_cond));
  714. x.mu2.Unlock();
  715. // Run GetReadLock(), and wait for it to get the read lock
  716. std::thread thread2(GetReadLock, &x);
  717. x.mu2.LockWhen(absl::Condition(&x.have_reader_lock));
  718. x.mu2.Unlock();
  719. // Get the reader lock ourselves, and release it.
  720. x.mu.ReaderLock();
  721. x.mu.ReaderUnlock();
  722. // The lock should be held in read mode by GetReadLock().
  723. // If we have the bug, the lock will be free.
  724. x.mu.AssertReaderHeld();
  725. // Wake up all the threads.
  726. x.mu2.Lock();
  727. x.complete = true;
  728. x.mu2.Unlock();
  729. // TODO(delesley): turn on analysis once lock upgrading is supported.
  730. // (This call upgrades the lock from shared to exclusive.)
  731. x.mu.Lock();
  732. x.cond = true;
  733. x.mu.Await(absl::Condition(&AllDone, &x));
  734. x.mu.Unlock();
  735. thread1.join();
  736. thread2.join();
  737. }
  738. #endif // !ABSL_MUTEX_READER_LOCK_IS_EXCLUSIVE
  739. // Test that we correctly handle the situation when a lock is
  740. // held and then destroyed (w/o unlocking).
  741. #ifdef ABSL_HAVE_THREAD_SANITIZER
  742. // TSAN reports errors when locked Mutexes are destroyed.
  743. TEST(Mutex, DISABLED_LockedMutexDestructionBug) ABSL_NO_THREAD_SAFETY_ANALYSIS {
  744. #else
  745. TEST(Mutex, LockedMutexDestructionBug) ABSL_NO_THREAD_SAFETY_ANALYSIS {
  746. #endif
  747. for (int i = 0; i != 10; i++) {
  748. // Create, lock and destroy 10 locks.
  749. const int kNumLocks = 10;
  750. auto mu = absl::make_unique<absl::Mutex[]>(kNumLocks);
  751. for (int j = 0; j != kNumLocks; j++) {
  752. if ((j % 2) == 0) {
  753. mu[j].WriterLock();
  754. } else {
  755. mu[j].ReaderLock();
  756. }
  757. }
  758. }
  759. }
  760. struct True {
  761. template <class... Args>
  762. bool operator()(Args...) const {
  763. return true;
  764. }
  765. };
  766. struct DerivedTrue : True {};
  767. TEST(Mutex, FunctorCondition) {
  768. { // Variadic
  769. True f;
  770. EXPECT_TRUE(absl::Condition(&f).Eval());
  771. }
  772. { // Inherited
  773. DerivedTrue g;
  774. EXPECT_TRUE(absl::Condition(&g).Eval());
  775. }
  776. { // lambda
  777. int value = 3;
  778. auto is_zero = [&value] { return value == 0; };
  779. absl::Condition c(&is_zero);
  780. EXPECT_FALSE(c.Eval());
  781. value = 0;
  782. EXPECT_TRUE(c.Eval());
  783. }
  784. { // bind
  785. int value = 0;
  786. auto is_positive = std::bind(std::less<int>(), 0, std::cref(value));
  787. absl::Condition c(&is_positive);
  788. EXPECT_FALSE(c.Eval());
  789. value = 1;
  790. EXPECT_TRUE(c.Eval());
  791. }
  792. { // std::function
  793. int value = 3;
  794. std::function<bool()> is_zero = [&value] { return value == 0; };
  795. absl::Condition c(&is_zero);
  796. EXPECT_FALSE(c.Eval());
  797. value = 0;
  798. EXPECT_TRUE(c.Eval());
  799. }
  800. }
  801. // --------------------------------------------------------
  802. // Test for bug with pattern of readers using a condvar. The bug was that if a
  803. // reader went to sleep on a condition variable while one or more other readers
  804. // held the lock, but there were no waiters, the reader count (held in the
  805. // mutex word) would be lost. (This is because Enqueue() had at one time
  806. // always placed the thread on the Mutex queue. Later (CL 4075610), to
  807. // tolerate re-entry into Mutex from a Condition predicate, Enqueue() was
  808. // changed so that it could also place a thread on a condition-variable. This
  809. // introduced the case where Enqueue() returned with an empty queue, and this
  810. // case was handled incorrectly in one place.)
  811. static void ReaderForReaderOnCondVar(absl::Mutex *mu, absl::CondVar *cv,
  812. int *running) {
  813. std::random_device dev;
  814. std::mt19937 gen(dev());
  815. std::uniform_int_distribution<int> random_millis(0, 15);
  816. mu->ReaderLock();
  817. while (*running == 3) {
  818. absl::SleepFor(absl::Milliseconds(random_millis(gen)));
  819. cv->WaitWithTimeout(mu, absl::Milliseconds(random_millis(gen)));
  820. }
  821. mu->ReaderUnlock();
  822. mu->Lock();
  823. (*running)--;
  824. mu->Unlock();
  825. }
  826. static bool IntIsZero(int *x) { return *x == 0; }
  827. // Test for reader waiting condition variable when there are other readers
  828. // but no waiters.
  829. TEST(Mutex, TestReaderOnCondVar) {
  830. auto tp = CreateDefaultPool();
  831. absl::Mutex mu;
  832. absl::CondVar cv;
  833. int running = 3;
  834. tp->Schedule(std::bind(&ReaderForReaderOnCondVar, &mu, &cv, &running));
  835. tp->Schedule(std::bind(&ReaderForReaderOnCondVar, &mu, &cv, &running));
  836. absl::SleepFor(absl::Seconds(2));
  837. mu.Lock();
  838. running--;
  839. mu.Await(absl::Condition(&IntIsZero, &running));
  840. mu.Unlock();
  841. }
  842. // --------------------------------------------------------
  843. struct AcquireFromConditionStruct {
  844. absl::Mutex mu0; // protects value, done
  845. int value; // times condition function is called; under mu0,
  846. bool done; // done with test? under mu0
  847. absl::Mutex mu1; // used to attempt to mess up state of mu0
  848. absl::CondVar cv; // so the condition function can be invoked from
  849. // CondVar::Wait().
  850. };
  851. static bool ConditionWithAcquire(AcquireFromConditionStruct *x) {
  852. x->value++; // count times this function is called
  853. if (x->value == 2 || x->value == 3) {
  854. // On the second and third invocation of this function, sleep for 100ms,
  855. // but with the side-effect of altering the state of a Mutex other than
  856. // than one for which this is a condition. The spec now explicitly allows
  857. // this side effect; previously it did not. it was illegal.
  858. bool always_false = false;
  859. x->mu1.LockWhenWithTimeout(absl::Condition(&always_false),
  860. absl::Milliseconds(100));
  861. x->mu1.Unlock();
  862. }
  863. ABSL_RAW_CHECK(x->value < 4, "should not be invoked a fourth time");
  864. // We arrange for the condition to return true on only the 2nd and 3rd calls.
  865. return x->value == 2 || x->value == 3;
  866. }
  867. static void WaitForCond2(AcquireFromConditionStruct *x) {
  868. // wait for cond0 to become true
  869. x->mu0.LockWhen(absl::Condition(&ConditionWithAcquire, x));
  870. x->done = true;
  871. x->mu0.Unlock();
  872. }
  873. // Test for Condition whose function acquires other Mutexes
  874. TEST(Mutex, AcquireFromCondition) {
  875. auto tp = CreateDefaultPool();
  876. AcquireFromConditionStruct x;
  877. x.value = 0;
  878. x.done = false;
  879. tp->Schedule(
  880. std::bind(&WaitForCond2, &x)); // run WaitForCond2() in a thread T
  881. // T will hang because the first invocation of ConditionWithAcquire() will
  882. // return false.
  883. absl::SleepFor(absl::Milliseconds(500)); // allow T time to hang
  884. x.mu0.Lock();
  885. x.cv.WaitWithTimeout(&x.mu0, absl::Milliseconds(500)); // wake T
  886. // T will be woken because the Wait() will call ConditionWithAcquire()
  887. // for the second time, and it will return true.
  888. x.mu0.Unlock();
  889. // T will then acquire the lock and recheck its own condition.
  890. // It will find the condition true, as this is the third invocation,
  891. // but the use of another Mutex by the calling function will
  892. // cause the old mutex implementation to think that the outer
  893. // LockWhen() has timed out because the inner LockWhenWithTimeout() did.
  894. // T will then check the condition a fourth time because it finds a
  895. // timeout occurred. This should not happen in the new
  896. // implementation that allows the Condition function to use Mutexes.
  897. // It should also succeed, even though the Condition function
  898. // is being invoked from CondVar::Wait, and thus this thread
  899. // is conceptually waiting both on the condition variable, and on mu2.
  900. x.mu0.LockWhen(absl::Condition(&x.done));
  901. x.mu0.Unlock();
  902. }
  903. TEST(Mutex, DeadlockDetector) {
  904. absl::SetMutexDeadlockDetectionMode(absl::OnDeadlockCycle::kAbort);
  905. // check that we can call ForgetDeadlockInfo() on a lock with the lock held
  906. absl::Mutex m1;
  907. absl::Mutex m2;
  908. absl::Mutex m3;
  909. absl::Mutex m4;
  910. m1.Lock(); // m1 gets ID1
  911. m2.Lock(); // m2 gets ID2
  912. m3.Lock(); // m3 gets ID3
  913. m3.Unlock();
  914. m2.Unlock();
  915. // m1 still held
  916. m1.ForgetDeadlockInfo(); // m1 loses ID
  917. m2.Lock(); // m2 gets ID2
  918. m3.Lock(); // m3 gets ID3
  919. m4.Lock(); // m4 gets ID4
  920. m3.Unlock();
  921. m2.Unlock();
  922. m4.Unlock();
  923. m1.Unlock();
  924. }
  925. // Bazel has a test "warning" file that programs can write to if the
  926. // test should pass with a warning. This class disables the warning
  927. // file until it goes out of scope.
  928. class ScopedDisableBazelTestWarnings {
  929. public:
  930. ScopedDisableBazelTestWarnings() {
  931. #ifdef _WIN32
  932. char file[MAX_PATH];
  933. if (GetEnvironmentVariableA(kVarName, file, sizeof(file)) < sizeof(file)) {
  934. warnings_output_file_ = file;
  935. SetEnvironmentVariableA(kVarName, nullptr);
  936. }
  937. #else
  938. const char *file = getenv(kVarName);
  939. if (file != nullptr) {
  940. warnings_output_file_ = file;
  941. unsetenv(kVarName);
  942. }
  943. #endif
  944. }
  945. ~ScopedDisableBazelTestWarnings() {
  946. if (!warnings_output_file_.empty()) {
  947. #ifdef _WIN32
  948. SetEnvironmentVariableA(kVarName, warnings_output_file_.c_str());
  949. #else
  950. setenv(kVarName, warnings_output_file_.c_str(), 0);
  951. #endif
  952. }
  953. }
  954. private:
  955. static const char kVarName[];
  956. std::string warnings_output_file_;
  957. };
  958. const char ScopedDisableBazelTestWarnings::kVarName[] =
  959. "TEST_WARNINGS_OUTPUT_FILE";
  960. #ifdef ABSL_HAVE_THREAD_SANITIZER
  961. // This test intentionally creates deadlocks to test the deadlock detector.
  962. TEST(Mutex, DISABLED_DeadlockDetectorBazelWarning) {
  963. #else
  964. TEST(Mutex, DeadlockDetectorBazelWarning) {
  965. #endif
  966. absl::SetMutexDeadlockDetectionMode(absl::OnDeadlockCycle::kReport);
  967. // Cause deadlock detection to detect something, if it's
  968. // compiled in and enabled. But turn off the bazel warning.
  969. ScopedDisableBazelTestWarnings disable_bazel_test_warnings;
  970. absl::Mutex mu0;
  971. absl::Mutex mu1;
  972. bool got_mu0 = mu0.TryLock();
  973. mu1.Lock(); // acquire mu1 while holding mu0
  974. if (got_mu0) {
  975. mu0.Unlock();
  976. }
  977. if (mu0.TryLock()) { // try lock shouldn't cause deadlock detector to fire
  978. mu0.Unlock();
  979. }
  980. mu0.Lock(); // acquire mu0 while holding mu1; should get one deadlock
  981. // report here
  982. mu0.Unlock();
  983. mu1.Unlock();
  984. absl::SetMutexDeadlockDetectionMode(absl::OnDeadlockCycle::kAbort);
  985. }
  986. // This test is tagged with NO_THREAD_SAFETY_ANALYSIS because the
  987. // annotation-based static thread-safety analysis is not currently
  988. // predicate-aware and cannot tell if the two for-loops that acquire and
  989. // release the locks have the same predicates.
  990. TEST(Mutex, DeadlockDetectorStressTest) ABSL_NO_THREAD_SAFETY_ANALYSIS {
  991. // Stress test: Here we create a large number of locks and use all of them.
  992. // If a deadlock detector keeps a full graph of lock acquisition order,
  993. // it will likely be too slow for this test to pass.
  994. const int n_locks = 1 << 17;
  995. auto array_of_locks = absl::make_unique<absl::Mutex[]>(n_locks);
  996. for (int i = 0; i < n_locks; i++) {
  997. int end = std::min(n_locks, i + 5);
  998. // acquire and then release locks i, i+1, ..., i+4
  999. for (int j = i; j < end; j++) {
  1000. array_of_locks[j].Lock();
  1001. }
  1002. for (int j = i; j < end; j++) {
  1003. array_of_locks[j].Unlock();
  1004. }
  1005. }
  1006. }
  1007. #ifdef ABSL_HAVE_THREAD_SANITIZER
  1008. // TSAN reports errors when locked Mutexes are destroyed.
  1009. TEST(Mutex, DISABLED_DeadlockIdBug) ABSL_NO_THREAD_SAFETY_ANALYSIS {
  1010. #else
  1011. TEST(Mutex, DeadlockIdBug) ABSL_NO_THREAD_SAFETY_ANALYSIS {
  1012. #endif
  1013. // Test a scenario where a cached deadlock graph node id in the
  1014. // list of held locks is not invalidated when the corresponding
  1015. // mutex is deleted.
  1016. absl::SetMutexDeadlockDetectionMode(absl::OnDeadlockCycle::kAbort);
  1017. // Mutex that will be destroyed while being held
  1018. absl::Mutex *a = new absl::Mutex;
  1019. // Other mutexes needed by test
  1020. absl::Mutex b, c;
  1021. // Hold mutex.
  1022. a->Lock();
  1023. // Force deadlock id assignment by acquiring another lock.
  1024. b.Lock();
  1025. b.Unlock();
  1026. // Delete the mutex. The Mutex destructor tries to remove held locks,
  1027. // but the attempt isn't foolproof. It can fail if:
  1028. // (a) Deadlock detection is currently disabled.
  1029. // (b) The destruction is from another thread.
  1030. // We exploit (a) by temporarily disabling deadlock detection.
  1031. absl::SetMutexDeadlockDetectionMode(absl::OnDeadlockCycle::kIgnore);
  1032. delete a;
  1033. absl::SetMutexDeadlockDetectionMode(absl::OnDeadlockCycle::kAbort);
  1034. // Now acquire another lock which will force a deadlock id assignment.
  1035. // We should end up getting assigned the same deadlock id that was
  1036. // freed up when "a" was deleted, which will cause a spurious deadlock
  1037. // report if the held lock entry for "a" was not invalidated.
  1038. c.Lock();
  1039. c.Unlock();
  1040. }
  1041. // --------------------------------------------------------
  1042. // Test for timeouts/deadlines on condition waits that are specified using
  1043. // absl::Duration and absl::Time. For each waiting function we test with
  1044. // a timeout/deadline that has already expired/passed, one that is infinite
  1045. // and so never expires/passes, and one that will expire/pass in the near
  1046. // future.
  1047. static absl::Duration TimeoutTestAllowedSchedulingDelay() {
  1048. // Note: we use a function here because Microsoft Visual Studio fails to
  1049. // properly initialize constexpr static absl::Duration variables.
  1050. return absl::Milliseconds(150);
  1051. }
  1052. // Returns true if `actual_delay` is close enough to `expected_delay` to pass
  1053. // the timeouts/deadlines test. Otherwise, logs warnings and returns false.
  1054. ABSL_MUST_USE_RESULT
  1055. static bool DelayIsWithinBounds(absl::Duration expected_delay,
  1056. absl::Duration actual_delay) {
  1057. bool pass = true;
  1058. // Do not allow the observed delay to be less than expected. This may occur
  1059. // in practice due to clock skew or when the synchronization primitives use a
  1060. // different clock than absl::Now(), but these cases should be handled by the
  1061. // the retry mechanism in each TimeoutTest.
  1062. if (actual_delay < expected_delay) {
  1063. ABSL_RAW_LOG(WARNING,
  1064. "Actual delay %s was too short, expected %s (difference %s)",
  1065. absl::FormatDuration(actual_delay).c_str(),
  1066. absl::FormatDuration(expected_delay).c_str(),
  1067. absl::FormatDuration(actual_delay - expected_delay).c_str());
  1068. pass = false;
  1069. }
  1070. // If the expected delay is <= zero then allow a small error tolerance, since
  1071. // we do not expect context switches to occur during test execution.
  1072. // Otherwise, thread scheduling delays may be substantial in rare cases, so
  1073. // tolerate up to kTimeoutTestAllowedSchedulingDelay of error.
  1074. absl::Duration tolerance = expected_delay <= absl::ZeroDuration()
  1075. ? absl::Milliseconds(10)
  1076. : TimeoutTestAllowedSchedulingDelay();
  1077. if (actual_delay > expected_delay + tolerance) {
  1078. ABSL_RAW_LOG(WARNING,
  1079. "Actual delay %s was too long, expected %s (difference %s)",
  1080. absl::FormatDuration(actual_delay).c_str(),
  1081. absl::FormatDuration(expected_delay).c_str(),
  1082. absl::FormatDuration(actual_delay - expected_delay).c_str());
  1083. pass = false;
  1084. }
  1085. return pass;
  1086. }
  1087. // Parameters for TimeoutTest, below.
  1088. struct TimeoutTestParam {
  1089. // The file and line number (used for logging purposes only).
  1090. const char *from_file;
  1091. int from_line;
  1092. // Should the absolute deadline API based on absl::Time be tested? If false,
  1093. // the relative deadline API based on absl::Duration is tested.
  1094. bool use_absolute_deadline;
  1095. // The deadline/timeout used when calling the API being tested
  1096. // (e.g. Mutex::LockWhenWithDeadline).
  1097. absl::Duration wait_timeout;
  1098. // The delay before the condition will be set true by the test code. If zero
  1099. // or negative, the condition is set true immediately (before calling the API
  1100. // being tested). Otherwise, if infinite, the condition is never set true.
  1101. // Otherwise a closure is scheduled for the future that sets the condition
  1102. // true.
  1103. absl::Duration satisfy_condition_delay;
  1104. // The expected result of the condition after the call to the API being
  1105. // tested. Generally `true` means the condition was true when the API returns,
  1106. // `false` indicates an expected timeout.
  1107. bool expected_result;
  1108. // The expected delay before the API under test returns. This is inherently
  1109. // flaky, so some slop is allowed (see `DelayIsWithinBounds` above), and the
  1110. // test keeps trying indefinitely until this constraint passes.
  1111. absl::Duration expected_delay;
  1112. };
  1113. // Print a `TimeoutTestParam` to a debug log.
  1114. std::ostream &operator<<(std::ostream &os, const TimeoutTestParam &param) {
  1115. return os << "from: " << param.from_file << ":" << param.from_line
  1116. << " use_absolute_deadline: "
  1117. << (param.use_absolute_deadline ? "true" : "false")
  1118. << " wait_timeout: " << param.wait_timeout
  1119. << " satisfy_condition_delay: " << param.satisfy_condition_delay
  1120. << " expected_result: "
  1121. << (param.expected_result ? "true" : "false")
  1122. << " expected_delay: " << param.expected_delay;
  1123. }
  1124. std::string FormatString(const TimeoutTestParam &param) {
  1125. std::ostringstream os;
  1126. os << param;
  1127. return os.str();
  1128. }
  1129. // Like `thread::Executor::ScheduleAt` except:
  1130. // a) Delays zero or negative are executed immediately in the current thread.
  1131. // b) Infinite delays are never scheduled.
  1132. // c) Calls this test's `ScheduleAt` helper instead of using `pool` directly.
  1133. static void RunAfterDelay(absl::Duration delay,
  1134. absl::synchronization_internal::ThreadPool *pool,
  1135. const std::function<void()> &callback) {
  1136. if (delay <= absl::ZeroDuration()) {
  1137. callback(); // immediate
  1138. } else if (delay != absl::InfiniteDuration()) {
  1139. ScheduleAfter(pool, delay, callback);
  1140. }
  1141. }
  1142. class TimeoutTest : public ::testing::Test,
  1143. public ::testing::WithParamInterface<TimeoutTestParam> {};
  1144. std::vector<TimeoutTestParam> MakeTimeoutTestParamValues() {
  1145. // The `finite` delay is a finite, relatively short, delay. We make it larger
  1146. // than our allowed scheduling delay (slop factor) to avoid confusion when
  1147. // diagnosing test failures. The other constants here have clear meanings.
  1148. const absl::Duration finite = 3 * TimeoutTestAllowedSchedulingDelay();
  1149. const absl::Duration never = absl::InfiniteDuration();
  1150. const absl::Duration negative = -absl::InfiniteDuration();
  1151. const absl::Duration immediate = absl::ZeroDuration();
  1152. // Every test case is run twice; once using the absolute deadline API and once
  1153. // using the relative timeout API.
  1154. std::vector<TimeoutTestParam> values;
  1155. for (bool use_absolute_deadline : {false, true}) {
  1156. // Tests with a negative timeout (deadline in the past), which should
  1157. // immediately return current state of the condition.
  1158. // The condition is already true:
  1159. values.push_back(TimeoutTestParam{
  1160. __FILE__, __LINE__, use_absolute_deadline,
  1161. negative, // wait_timeout
  1162. immediate, // satisfy_condition_delay
  1163. true, // expected_result
  1164. immediate, // expected_delay
  1165. });
  1166. // The condition becomes true, but the timeout has already expired:
  1167. values.push_back(TimeoutTestParam{
  1168. __FILE__, __LINE__, use_absolute_deadline,
  1169. negative, // wait_timeout
  1170. finite, // satisfy_condition_delay
  1171. false, // expected_result
  1172. immediate // expected_delay
  1173. });
  1174. // The condition never becomes true:
  1175. values.push_back(TimeoutTestParam{
  1176. __FILE__, __LINE__, use_absolute_deadline,
  1177. negative, // wait_timeout
  1178. never, // satisfy_condition_delay
  1179. false, // expected_result
  1180. immediate // expected_delay
  1181. });
  1182. // Tests with an infinite timeout (deadline in the infinite future), which
  1183. // should only return when the condition becomes true.
  1184. // The condition is already true:
  1185. values.push_back(TimeoutTestParam{
  1186. __FILE__, __LINE__, use_absolute_deadline,
  1187. never, // wait_timeout
  1188. immediate, // satisfy_condition_delay
  1189. true, // expected_result
  1190. immediate // expected_delay
  1191. });
  1192. // The condition becomes true before the (infinite) expiry:
  1193. values.push_back(TimeoutTestParam{
  1194. __FILE__, __LINE__, use_absolute_deadline,
  1195. never, // wait_timeout
  1196. finite, // satisfy_condition_delay
  1197. true, // expected_result
  1198. finite, // expected_delay
  1199. });
  1200. // Tests with a (small) finite timeout (deadline soon), with the condition
  1201. // becoming true both before and after its expiry.
  1202. // The condition is already true:
  1203. values.push_back(TimeoutTestParam{
  1204. __FILE__, __LINE__, use_absolute_deadline,
  1205. never, // wait_timeout
  1206. immediate, // satisfy_condition_delay
  1207. true, // expected_result
  1208. immediate // expected_delay
  1209. });
  1210. // The condition becomes true before the expiry:
  1211. values.push_back(TimeoutTestParam{
  1212. __FILE__, __LINE__, use_absolute_deadline,
  1213. finite * 2, // wait_timeout
  1214. finite, // satisfy_condition_delay
  1215. true, // expected_result
  1216. finite // expected_delay
  1217. });
  1218. // The condition becomes true, but the timeout has already expired:
  1219. values.push_back(TimeoutTestParam{
  1220. __FILE__, __LINE__, use_absolute_deadline,
  1221. finite, // wait_timeout
  1222. finite * 2, // satisfy_condition_delay
  1223. false, // expected_result
  1224. finite // expected_delay
  1225. });
  1226. // The condition never becomes true:
  1227. values.push_back(TimeoutTestParam{
  1228. __FILE__, __LINE__, use_absolute_deadline,
  1229. finite, // wait_timeout
  1230. never, // satisfy_condition_delay
  1231. false, // expected_result
  1232. finite // expected_delay
  1233. });
  1234. }
  1235. return values;
  1236. }
  1237. // Instantiate `TimeoutTest` with `MakeTimeoutTestParamValues()`.
  1238. INSTANTIATE_TEST_SUITE_P(All, TimeoutTest,
  1239. testing::ValuesIn(MakeTimeoutTestParamValues()));
  1240. TEST_P(TimeoutTest, Await) {
  1241. const TimeoutTestParam params = GetParam();
  1242. ABSL_RAW_LOG(INFO, "Params: %s", FormatString(params).c_str());
  1243. // Because this test asserts bounds on scheduling delays it is flaky. To
  1244. // compensate it loops forever until it passes. Failures express as test
  1245. // timeouts, in which case the test log can be used to diagnose the issue.
  1246. for (int attempt = 1;; ++attempt) {
  1247. ABSL_RAW_LOG(INFO, "Attempt %d", attempt);
  1248. absl::Mutex mu;
  1249. bool value = false; // condition value (under mu)
  1250. std::unique_ptr<absl::synchronization_internal::ThreadPool> pool =
  1251. CreateDefaultPool();
  1252. RunAfterDelay(params.satisfy_condition_delay, pool.get(), [&] {
  1253. absl::MutexLock l(&mu);
  1254. value = true;
  1255. });
  1256. absl::MutexLock lock(&mu);
  1257. absl::Time start_time = absl::Now();
  1258. absl::Condition cond(&value);
  1259. bool result =
  1260. params.use_absolute_deadline
  1261. ? mu.AwaitWithDeadline(cond, start_time + params.wait_timeout)
  1262. : mu.AwaitWithTimeout(cond, params.wait_timeout);
  1263. if (DelayIsWithinBounds(params.expected_delay, absl::Now() - start_time)) {
  1264. EXPECT_EQ(params.expected_result, result);
  1265. break;
  1266. }
  1267. }
  1268. }
  1269. TEST_P(TimeoutTest, LockWhen) {
  1270. const TimeoutTestParam params = GetParam();
  1271. ABSL_RAW_LOG(INFO, "Params: %s", FormatString(params).c_str());
  1272. // Because this test asserts bounds on scheduling delays it is flaky. To
  1273. // compensate it loops forever until it passes. Failures express as test
  1274. // timeouts, in which case the test log can be used to diagnose the issue.
  1275. for (int attempt = 1;; ++attempt) {
  1276. ABSL_RAW_LOG(INFO, "Attempt %d", attempt);
  1277. absl::Mutex mu;
  1278. bool value = false; // condition value (under mu)
  1279. std::unique_ptr<absl::synchronization_internal::ThreadPool> pool =
  1280. CreateDefaultPool();
  1281. RunAfterDelay(params.satisfy_condition_delay, pool.get(), [&] {
  1282. absl::MutexLock l(&mu);
  1283. value = true;
  1284. });
  1285. absl::Time start_time = absl::Now();
  1286. absl::Condition cond(&value);
  1287. bool result =
  1288. params.use_absolute_deadline
  1289. ? mu.LockWhenWithDeadline(cond, start_time + params.wait_timeout)
  1290. : mu.LockWhenWithTimeout(cond, params.wait_timeout);
  1291. mu.Unlock();
  1292. if (DelayIsWithinBounds(params.expected_delay, absl::Now() - start_time)) {
  1293. EXPECT_EQ(params.expected_result, result);
  1294. break;
  1295. }
  1296. }
  1297. }
  1298. TEST_P(TimeoutTest, ReaderLockWhen) {
  1299. const TimeoutTestParam params = GetParam();
  1300. ABSL_RAW_LOG(INFO, "Params: %s", FormatString(params).c_str());
  1301. // Because this test asserts bounds on scheduling delays it is flaky. To
  1302. // compensate it loops forever until it passes. Failures express as test
  1303. // timeouts, in which case the test log can be used to diagnose the issue.
  1304. for (int attempt = 0;; ++attempt) {
  1305. ABSL_RAW_LOG(INFO, "Attempt %d", attempt);
  1306. absl::Mutex mu;
  1307. bool value = false; // condition value (under mu)
  1308. std::unique_ptr<absl::synchronization_internal::ThreadPool> pool =
  1309. CreateDefaultPool();
  1310. RunAfterDelay(params.satisfy_condition_delay, pool.get(), [&] {
  1311. absl::MutexLock l(&mu);
  1312. value = true;
  1313. });
  1314. absl::Time start_time = absl::Now();
  1315. bool result =
  1316. params.use_absolute_deadline
  1317. ? mu.ReaderLockWhenWithDeadline(absl::Condition(&value),
  1318. start_time + params.wait_timeout)
  1319. : mu.ReaderLockWhenWithTimeout(absl::Condition(&value),
  1320. params.wait_timeout);
  1321. mu.ReaderUnlock();
  1322. if (DelayIsWithinBounds(params.expected_delay, absl::Now() - start_time)) {
  1323. EXPECT_EQ(params.expected_result, result);
  1324. break;
  1325. }
  1326. }
  1327. }
  1328. TEST_P(TimeoutTest, Wait) {
  1329. const TimeoutTestParam params = GetParam();
  1330. ABSL_RAW_LOG(INFO, "Params: %s", FormatString(params).c_str());
  1331. // Because this test asserts bounds on scheduling delays it is flaky. To
  1332. // compensate it loops forever until it passes. Failures express as test
  1333. // timeouts, in which case the test log can be used to diagnose the issue.
  1334. for (int attempt = 0;; ++attempt) {
  1335. ABSL_RAW_LOG(INFO, "Attempt %d", attempt);
  1336. absl::Mutex mu;
  1337. bool value = false; // condition value (under mu)
  1338. absl::CondVar cv; // signals a change of `value`
  1339. std::unique_ptr<absl::synchronization_internal::ThreadPool> pool =
  1340. CreateDefaultPool();
  1341. RunAfterDelay(params.satisfy_condition_delay, pool.get(), [&] {
  1342. absl::MutexLock l(&mu);
  1343. value = true;
  1344. cv.Signal();
  1345. });
  1346. absl::MutexLock lock(&mu);
  1347. absl::Time start_time = absl::Now();
  1348. absl::Duration timeout = params.wait_timeout;
  1349. absl::Time deadline = start_time + timeout;
  1350. while (!value) {
  1351. if (params.use_absolute_deadline ? cv.WaitWithDeadline(&mu, deadline)
  1352. : cv.WaitWithTimeout(&mu, timeout)) {
  1353. break; // deadline/timeout exceeded
  1354. }
  1355. timeout = deadline - absl::Now(); // recompute
  1356. }
  1357. bool result = value; // note: `mu` is still held
  1358. if (DelayIsWithinBounds(params.expected_delay, absl::Now() - start_time)) {
  1359. EXPECT_EQ(params.expected_result, result);
  1360. break;
  1361. }
  1362. }
  1363. }
  1364. TEST(Mutex, Logging) {
  1365. // Allow user to look at logging output
  1366. absl::Mutex logged_mutex;
  1367. logged_mutex.EnableDebugLog("fido_mutex");
  1368. absl::CondVar logged_cv;
  1369. logged_cv.EnableDebugLog("rover_cv");
  1370. logged_mutex.Lock();
  1371. logged_cv.WaitWithTimeout(&logged_mutex, absl::Milliseconds(20));
  1372. logged_mutex.Unlock();
  1373. logged_mutex.ReaderLock();
  1374. logged_mutex.ReaderUnlock();
  1375. logged_mutex.Lock();
  1376. logged_mutex.Unlock();
  1377. logged_cv.Signal();
  1378. logged_cv.SignalAll();
  1379. }
  1380. // --------------------------------------------------------
  1381. // Generate the vector of thread counts for tests parameterized on thread count.
  1382. static std::vector<int> AllThreadCountValues() {
  1383. if (kExtendedTest) {
  1384. return {2, 4, 8, 10, 16, 20, 24, 30, 32};
  1385. }
  1386. return {2, 4, 10};
  1387. }
  1388. // A test fixture parameterized by thread count.
  1389. class MutexVariableThreadCountTest : public ::testing::TestWithParam<int> {};
  1390. // Instantiate the above with AllThreadCountOptions().
  1391. INSTANTIATE_TEST_SUITE_P(ThreadCounts, MutexVariableThreadCountTest,
  1392. ::testing::ValuesIn(AllThreadCountValues()),
  1393. ::testing::PrintToStringParamName());
  1394. // Reduces iterations by some factor for slow platforms
  1395. // (determined empirically).
  1396. static int ScaleIterations(int x) {
  1397. // ABSL_MUTEX_READER_LOCK_IS_EXCLUSIVE is set in the implementation
  1398. // of Mutex that uses either std::mutex or pthread_mutex_t. Use
  1399. // these as keys to determine the slow implementation.
  1400. #if defined(ABSL_MUTEX_READER_LOCK_IS_EXCLUSIVE)
  1401. return x / 10;
  1402. #else
  1403. return x;
  1404. #endif
  1405. }
  1406. TEST_P(MutexVariableThreadCountTest, Mutex) {
  1407. int threads = GetParam();
  1408. int iterations = ScaleIterations(10000000) / threads;
  1409. int operations = threads * iterations;
  1410. EXPECT_EQ(RunTest(&TestMu, threads, iterations, operations), operations);
  1411. #if !defined(ABSL_MUTEX_ENABLE_INVARIANT_DEBUGGING_NOT_IMPLEMENTED)
  1412. iterations = std::min(iterations, 10);
  1413. operations = threads * iterations;
  1414. EXPECT_EQ(RunTestWithInvariantDebugging(&TestMu, threads, iterations,
  1415. operations, CheckSumG0G1),
  1416. operations);
  1417. #endif
  1418. }
  1419. TEST_P(MutexVariableThreadCountTest, Try) {
  1420. int threads = GetParam();
  1421. int iterations = 1000000 / threads;
  1422. int operations = iterations * threads;
  1423. EXPECT_EQ(RunTest(&TestTry, threads, iterations, operations), operations);
  1424. #if !defined(ABSL_MUTEX_ENABLE_INVARIANT_DEBUGGING_NOT_IMPLEMENTED)
  1425. iterations = std::min(iterations, 10);
  1426. operations = threads * iterations;
  1427. EXPECT_EQ(RunTestWithInvariantDebugging(&TestTry, threads, iterations,
  1428. operations, CheckSumG0G1),
  1429. operations);
  1430. #endif
  1431. }
  1432. TEST_P(MutexVariableThreadCountTest, R20ms) {
  1433. int threads = GetParam();
  1434. int iterations = 100;
  1435. int operations = iterations * threads;
  1436. EXPECT_EQ(RunTest(&TestR20ms, threads, iterations, operations), 0);
  1437. }
  1438. TEST_P(MutexVariableThreadCountTest, RW) {
  1439. int threads = GetParam();
  1440. int iterations = ScaleIterations(20000000) / threads;
  1441. int operations = iterations * threads;
  1442. EXPECT_EQ(RunTest(&TestRW, threads, iterations, operations), operations / 2);
  1443. #if !defined(ABSL_MUTEX_ENABLE_INVARIANT_DEBUGGING_NOT_IMPLEMENTED)
  1444. iterations = std::min(iterations, 10);
  1445. operations = threads * iterations;
  1446. EXPECT_EQ(RunTestWithInvariantDebugging(&TestRW, threads, iterations,
  1447. operations, CheckSumG0G1),
  1448. operations / 2);
  1449. #endif
  1450. }
  1451. TEST_P(MutexVariableThreadCountTest, Await) {
  1452. int threads = GetParam();
  1453. int iterations = ScaleIterations(500000);
  1454. int operations = iterations;
  1455. EXPECT_EQ(RunTest(&TestAwait, threads, iterations, operations), operations);
  1456. }
  1457. TEST_P(MutexVariableThreadCountTest, SignalAll) {
  1458. int threads = GetParam();
  1459. int iterations = 200000 / threads;
  1460. int operations = iterations;
  1461. EXPECT_EQ(RunTest(&TestSignalAll, threads, iterations, operations),
  1462. operations);
  1463. }
  1464. TEST(Mutex, Signal) {
  1465. int threads = 2; // TestSignal must use two threads
  1466. int iterations = 200000;
  1467. int operations = iterations;
  1468. EXPECT_EQ(RunTest(&TestSignal, threads, iterations, operations), operations);
  1469. }
  1470. TEST(Mutex, Timed) {
  1471. int threads = 10; // Use a fixed thread count of 10
  1472. int iterations = 1000;
  1473. int operations = iterations;
  1474. EXPECT_EQ(RunTest(&TestCVTimeout, threads, iterations, operations),
  1475. operations);
  1476. }
  1477. TEST(Mutex, CVTime) {
  1478. int threads = 10; // Use a fixed thread count of 10
  1479. int iterations = 1;
  1480. EXPECT_EQ(RunTest(&TestCVTime, threads, iterations, 1),
  1481. threads * iterations);
  1482. }
  1483. TEST(Mutex, MuTime) {
  1484. int threads = 10; // Use a fixed thread count of 10
  1485. int iterations = 1;
  1486. EXPECT_EQ(RunTest(&TestMuTime, threads, iterations, 1), threads * iterations);
  1487. }
  1488. } // namespace