Haopeng
Haopeng

Reputation: 1

Why does libc++ call_once uses a shared mutex for all calls?

I'm reading the source code of call_once in libc++, and curious about the usage of a shared mutex. Here's the implementation inside mutex.cpp. Doesn't this mean call_once(f1) and call_once(f2) compete for the same mutex even if they are different functions. Thanks.

#ifndef _LIBCPP_HAS_NO_THREADS
_LIBCPP_SAFE_STATIC static __libcpp_mutex_t mut = _LIBCPP_MUTEX_INITIALIZER;
_LIBCPP_SAFE_STATIC static __libcpp_condvar_t cv = _LIBCPP_CONDVAR_INITIALIZER;
#endif

void __call_once(volatile once_flag::_State_type& flag, void* arg,
                 void (*func)(void*)) {
  __libcpp_mutex_lock(&mut);
  ...
}

I'm hoping someone one can clarify if this is intended, and if so what's the reason behind.

Upvotes: 0

Views: 163

Answers (1)

Alan Birtles
Alan Birtles

Reputation: 36479

It does use a single mutex for all calls to std::call_once but it's only locked for as long as it takes to set or check the once flag. Unless you have hundreds of calls to std::call_once I can't see this having a significant performance impact.

It was probably implemented this way for both simplicity and the performance of the usual case of only having a small number of uses of call_once. It'd me much more complex (or even impossible) to implement a separate mutex for each flag.

Upvotes: 1

Related Questions