Skip to content

Instantly share code, notes, and snippets.

@danlark1
Created January 11, 2020 23:29
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save danlark1/bb31e87b01d6b617d5ae55de3fcbd940 to your computer and use it in GitHub Desktop.
Save danlark1/bb31e87b01d6b617d5ae55de3fcbd940 to your computer and use it in GitHub Desktop.
// 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);
}
// If not atomic fittable type, use mutex implementation.
template <typename T,
typename std::enable_if<
!flags_internal::IsAtomicFlagTypeTrait<T>::value, int>::type = 0>
ABSL_MUST_USE_RESULT T GetFlag(const absl::Flag<T>& flag) {
return flag.Get();
}
// If it is a trivially copyable type, use atomic hack.
template <typename T,
typename std::enable_if<
flags_internal::IsAtomicFlagTypeTrait<T>::value, int>::type = 0>
ABSL_MUST_USE_RESULT T GetFlag(const absl::Flag<T>& flag) {
// T might not be default constructible.
union U {
T value;
U() {}
};
U result;
if (flag.AtomicGet(&result.value)) {
return result.value;
}
return flag.Get();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment