-
Notifications
You must be signed in to change notification settings - Fork 11.8k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Fix PR27658 - Make ~mutex trivial when possible.
Currently std::mutex has a constexpr constructor, but a non-trivial destruction. The constexpr constructor is required to ensure the construction of a mutex with static storage duration happens at compile time, during constant initialization, and not during dynamic initialization. This means that static mutex's are always initialized and can be used safely during dynamic initialization without the "static initialization order fiasco". A trivial destructor is important for similar reasons. If a mutex is used during dynamic initialization it might also be used during program termination. If a static mutex has a non-trivial destructor it will be invoked during termination. This can introduce the "static deinitialization order fiasco". Additionally, function-local statics emit a guard variable around non-trivially destructible types. This results in horrible codegen and adds a runtime cost to every call to that function. non-local static's also result in slightly worse codegen but it's not as big of a problem. Example codegen can be found here: https://goo.gl/3CSzbM Note: This optimization is not safe with every pthread implementation. Some implementations allocate on the first call to pthread_mutex_lock and free the allocation in pthread_mutex_destroy. Also, changing the triviality of the destructor is not an ABI break. At least to the best of my knowledge :-) llvm-svn: 365273
- Loading branch information
Showing
6 changed files
with
73 additions
and
20 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
//===--------------------- mutex_destructor.cpp ---------------------------===// | ||
// | ||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | ||
// See https://llvm.org/LICENSE.txt for license information. | ||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||
// | ||
//===----------------------------------------------------------------------===// | ||
|
||
// Define ~mutex. | ||
// | ||
// On some platforms ~mutex has been made trivial and the definition is only | ||
// provided for ABI compatibility. | ||
// | ||
// In order to avoid ODR violations within libc++ itself, we need to ensure | ||
// that *nothing* sees the non-trivial mutex declaration. For this reason | ||
// we re-declare the entire class in this file instead of using | ||
// _LIBCPP_BUILDING_LIBRARY to change the definition in the headers. | ||
|
||
#include "__config" | ||
#include "__threading_support" | ||
|
||
#if !defined(_LIBCPP_HAS_NO_THREADS) | ||
#if _LIBCPP_ABI_VERSION == 1 || !defined(_LIBCPP_HAS_TRIVIAL_MUTEX_DESTRUCTION) | ||
#define NEEDS_MUTEX_DESTRUCTOR | ||
#endif | ||
#endif | ||
|
||
_LIBCPP_BEGIN_NAMESPACE_STD | ||
|
||
#ifdef NEEDS_MUTEX_DESTRUCTOR | ||
class _LIBCPP_TYPE_VIS mutex | ||
{ | ||
__libcpp_mutex_t __m_ = _LIBCPP_MUTEX_INITIALIZER; | ||
|
||
public: | ||
_LIBCPP_ALWAYS_INLINE _LIBCPP_INLINE_VISIBILITY | ||
constexpr mutex() = default; | ||
mutex(const mutex&) = delete; | ||
mutex& operator=(const mutex&) = delete; | ||
~mutex() noexcept; | ||
}; | ||
|
||
|
||
mutex::~mutex() _NOEXCEPT | ||
{ | ||
__libcpp_mutex_destroy(&__m_); | ||
} | ||
|
||
#endif // !_LIBCPP_HAS_NO_THREADS | ||
_LIBCPP_END_NAMESPACE_STD | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
8baf838
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
godbolt short link for the goo.gl one: https://godbolt.org/z/YxW44PdjP