https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99341
Bug ID: 99341 Summary: [11 Regression] new std::call_once is not backwards compatible Product: gcc Version: 11.0 Status: UNCONFIRMED Keywords: ABI Severity: blocker Priority: P3 Component: libstdc++ Assignee: unassigned at gcc dot gnu.org Reporter: redi at gcc dot gnu.org Target Milestone: --- Target: *-*-*linux* Creating a new bug for bug 66146 comment 41 increased visibility, and to deal with it separately from the exception-handling bug that is the topic of bug 66146. Quoting from there: The new std::call_once using a futex is not backwards compatible, so I think it needs to be reverted, or hidden behind an ABI-breaking flag. The new std::once_flag::_M_activate() function sets _M_once=1 when an initialization is in progress. With glibc, if a call to the new std::call_once happens before a call to the old version of std::call_once, then glibc's pthread_once will find no fork generation value in _M_once and so will think it should run the init_function itself. Both threads will run their init_function, instead of the second one waiting for the first to finish. With musl, if a call to the old std::call_once happens before a call to the new std::call_once, then the second thread won't set _M_once=3 and so musl's pthread_once won't wake the second thread when the first finishes. The second thread will sleep forever (or until a spurious wake from the futex wait).