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
#if __cplusplus >= 201703 && __has_include(<optional>) | |
#include <optional> | |
namespace absl { | |
using std::bad_optional_access; | |
using std::optional; | |
using std::make_optional; | |
using std::nullopt_t; | |
using std::nullopt; |
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
// Very bad because the destruction order is not specified. | |
// From experience, these are one of the hardest to debug bugs. | |
template <class T> | |
T BadSingleton() { | |
static T t; | |
return t; | |
} | |
// Better. It is NOT a leak because the compiler will clear it after the shutdown. | |
// Downside -- destuctors are not called. But you should never do complicated |
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
// ABSL_CONST_INIT | |
// | |
// A variable declaration annotated with the `ABSL_CONST_INIT` attribute will | |
// not compile (on supported platforms) unless the variable has a constant | |
// initializer. This is useful for variables with static and thread storage | |
// duration, because it guarantees that they will not suffer from the so-called | |
// "static init order fiasco". Prefer to put this attribute on the most visible | |
// declaration of the variable, if there's more than one, because code that | |
// accesses the variable can then use the attribute for optimization. | |
// Note that this attribute is redundant if the variable is declared constexpr. |
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 is reserved space for an absl::Mutex to guard flag data. It will be | |
// initialized in FlagImpl::Init via placement new. | |
// We can't use "absl::Mutex data_guard_", since this class is not literal. | |
// We do not want to use "absl::Mutex* data_guard_", since this would require | |
// heap allocation during initialization, which is both slows program startup | |
// and can fail. Using reserved space + placement new allows us to avoid both | |
// problems. | |
alignas(absl::Mutex) mutable char data_guard_[sizeof(absl::Mutex)]; |
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 macro is the "source of truth" for the list of supported flag types we | |
// expect to perform lock free operations on. Specifically it generates code, | |
// a one argument macro operating on a type, supplied as a macro argument, for | |
// each type in the list. | |
#define ABSL_FLAGS_INTERNAL_FOR_EACH_LOCK_FREE(A) \ | |
A(bool) \ | |
A(short) \ | |
A(unsigned short) \ | |
A(int) \ | |
A(unsigned int) \ |
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
#include <type_traits> | |
#include "testing/benchmark.h" | |
#include "testing/gmock.h" | |
#include "testing/gunit.h" | |
#include "absl/flags/flag.h" | |
#include "absl/time/time.h" | |
// Updater threads + reverse frequency 1/128. | |
#define BENCHMARK_FLAG(func) BENCHMARK(func)->ThreadRange(1, 32) | |
template <class T, class Flag> |
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
movq (%rdi), %rax # load from the input | |
xorl %ecx, %ecx | |
movabsq $-6076574518398440533, %rdx # imm = 0xABABABABABABABAB | |
cmpq %rdx, %rax # Check with a garbage value | |
cmovel %ecx, %eax # return it in %rax | |
retq |
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
// The minimum atomic size we believe to generate lock free code, i.e. all | |
// trivially copyable types not bigger this size generate lock free code. | |
static constexpr int kMinLockFreeAtomicSize = 8; | |
template <typename T> | |
struct IsAtomicFlagTypeTrait { | |
static constexpr bool value = (sizeof(T) <= kMinLockFreeAtomicSize | |
&& std::is_trivially_copyable<T>::value); | |
} |
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
struct empty_struct {}; | |
struct dummy_type { | |
static_assert(sizeof(T) % sizeof(empty_struct) == 0, ""); | |
// Use an array to avoid GCC 6 placement-new warning. | |
empty_struct data[sizeof(T) / sizeof(empty_struct)]; | |
}; | |
// Data storage | |
union { |
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
// The minimum atomic size we believe to generate lock free code, i.e. all | |
// trivially copyable types not bigger this size generate lock free code. | |
static constexpr int kMinLockFreeAtomicSize = 8; | |
template <typename T> | |
struct IsAtomicFlagTypeTrait { | |
static constexpr bool value = (sizeof(T) <= kMinLockFreeAtomicSize | |
&& std::is_trivially_copyable<T>::value); | |
} |
OlderNewer