<table border="1" cellspacing="0" cellpadding="8">
    <tr>
        <th>Issue</th>
        <td>
            <a href=https://github.com/llvm/llvm-project/issues/95944>95944</a>
        </td>
    </tr>

    <tr>
        <th>Summary</th>
        <td>
            [libc++][test] thread.condition.condvar/notify_all.pass.cpp has a flaky timing assumption
        </td>
    </tr>

    <tr>
      <th>Labels</th>
      <td>
            libc++
      </td>
    </tr>

    <tr>
      <th>Assignees</th>
      <td>
      </td>
    </tr>

    <tr>
      <th>Reporter</th>
      <td>
          StephanTLavavej
      </td>
    </tr>
</table>

<pre>
    After #91530 refactored some condvar tests to pass reliably, @Arup-Chauhan helped MSVC's STL by re-enabling the condvar tests that we had been skipping (https://github.com/microsoft/STL/pull/4721). However, our CI system immediately encountered sporadic failures in `thread.condition.condvar/notify_all.pass.cpp`. #91530 didn't change that test, so this isn't new, we just didn't realize this had a distinct cause until the other tests were fixed.

The assertions we saw (on different test runs) were:

```
Assertion failed: test1 == 0, file D:\a\_work\1\s\llvm-project\libcxx\test\std\thread\thread.condition\thread.condition.condvar\notify_all.pass.cpp, line 35

Assertion failed: test2 == 0, file D:\a\_work\1\s\llvm-project\libcxx\test\std\thread\thread.condition\thread.condition.condvar\notify_all.pass.cpp, line 45
```

The test code is clearly using `sleep_for` 100ms as a synchronization primitive:

https://github.com/llvm/llvm-project/blob/3eb4128eb0cb4a42b912ee352c120a9c0f2ddbd6/libcxx/test/std/thread/thread.condition/thread.condition.condvar/notify_all.pass.cpp#L32-L35
https://github.com/llvm/llvm-project/blob/3eb4128eb0cb4a42b912ee352c120a9c0f2ddbd6/libcxx/test/std/thread/thread.condition/thread.condition.condvar/notify_all.pass.cpp#L42-L45
https://github.com/llvm/llvm-project/blob/3eb4128eb0cb4a42b912ee352c120a9c0f2ddbd6/libcxx/test/std/thread/thread.condition/thread.condition.condvar/notify_all.pass.cpp#L52-L61

Under heavy load, it's entirely possible for the new threads `t1` and `t2` running `f1` and `f2` respectively to not get started before the `main` thread gets through its 100ms sleep, acquires `mut`, and sets `test1` and `test2` to `1`. This causes `f1` and `f2` to assert when they discover this.

A deterministic mechanism needs to be used here.
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJzcVk2P2zYQ_TX0ZWBDoiR7ffDBkSG0gHvaba8BJY4sJhSpcig7zq8vhvZm3SZpkWMDCLZIkcN5bz4eFZE5OcSdqN6J6rBQcxx82D1HnAblXo7qrM74YdF6fd3t-4gBhCy2eVVkELBXXfQBNZAfETrv9FkFiEiRIHqYFBEEtEa19ipkDaLM9mGelvWg5kE5GNBOqOG35z9qITcEzy9HaK8QcIlOtda4E8ThK8ODinBBGJSGFtEBfTTTxGuFfBpinEgUeyEbIZuTicPcrjo_CtmMpguefB-FbJ5fjkI202ytkE25kbmQ2xX84i94xsCe-jlA_SvQlSKOYMYRtVER7RXQdX52ERPsyQelTQe9MnYOSGAciHUWh4BKr9hvE413qzsCIRvno-mv75W1K6Zn1U2TWGerN1a10U7ITYRuUO6EN7iMnN0iD3EwBIZuaxxeePqC8GGm-LY3oLLmM94WM1EKtKFoXBehUzMhzC4am9j1ccBXbi8YEHrzCfVKZAeR7W-_LwOCIsLAYHgVkLow3d6BNn2PAd3NSQizIyG3yRLH4cGKWGf3Jw33rwYTe6hFsU8mchDFQRQHyBhabyzCgS1VtRJV_f7iw0dR1bmoahJVbe15XE7Bf8Au8tC03adPoqoTY1VNUfMgxePLy1tgvjH1JVZV_a1YyRqscQhF9Qjte1jk_wJLWX0zQG-xT5HtvEYwBJ1FFewVZko1t87IIk7vex_EOoM8y0YCRaCArq4bgnfms0rUTMGMJprzP_PiX2qWGbn_fSFGNq31rZBNgW2Zyydss64tVSnbbS4Ri0p2uczUtst6qXWr12zgRqVsboXUMJWyuVP5-vJA5ddT_1HCsjgWcnl8zYqfBFIpl8fy54JUyeVxnT-m3-9OY4AB1fkK1vNJNZiY9AhdNIGb_uSJTGsReh9S03R4gdvhlBp-zrmvnE4DyYMwO3cvkP7xa3_7ijRhx8VgryyVzkc4YQSKKkRkYet9wHSUWGejMo533U7khSyDwc-nAUyke9GlOmTvVffnbFiNeOscuaB51mkg3skucp99dJl7VTrB8zBPkvTC4pHUgr6DIvq7LMBlQMfeXllnOn9mRRkM_U1F9qAxYhiNYynqYESWOEMjOESdbgwtwkyoYcCAq4XeFXpbbNUCd_kmf9rIsqo2i2FXtFj1Mu9lUWK2zlC3qtddlSuZocL1emF2MpNlts6f8kpu881KF6oolN5WKqu6bdaLMsNRGbvinF35cFoYohl322pblgurWrSUbkRSclIK-S49km9IYZcSvZ1PJMrMGor0ZiaaaNNd6mFbdRDVu1sPP8CPZSwMqZP2Vn28QjQjJ5QimseJ9y7mYHc_XJcJKQnZ3MCed_KvAAAA__-_skYx">