In the section titled "Special-purpose mutex types," we launched a task in a separate thread and then needed to wait until a certain bit of initialization was done before continuing. We used a polling loop around a std::atomic<bool> in that case. But there are better ways to wait!
The problem with our 50-millisecond polling loop is that it never spends the right amount of time asleep. Sometimes our thread will wake up, but the condition it's waiting for hasn't been satisfied, so it'll go back to sleep--that means we didn't sleep long enough the first time. Sometimes our thread will wake up and see that the condition it's waiting for has been satisfied, sometime in the past 50 milliseconds, but we don't know how long ago--that means we've overslept by about 25 milliseconds on average. Whatever happens, the...