https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110016
--- Comment #9 from Andrew Pinski <pinskia at gcc dot gnu.org> --- So I think this is a bug in your code: Inside substrate::threadPool_t::finish, we have: finished = true; haveWork.notify_all(); If I change it to: { std::lock_guard<std::mutex> lock{workMutex}; finished = true; haveWork.notify_all(); } Then I don't get a deadlock at all. As I mentioned, I did think there was a race condition. Here is what I think happened: Thread26: thread 1 checks finished, still false sets finished to be true calls wait calls notify_all ... notify_all happens finally gets into futex_wait syscall .... And then thread26 never got the notification. With my change the check for finished has to wait till thread1 lets go of the mutex (and the other way around).