aboutsummaryrefslogtreecommitdiffhomepage
path: root/absl/flags/internal/flag.h
diff options
context:
space:
mode:
Diffstat (limited to 'absl/flags/internal/flag.h')
-rw-r--r--absl/flags/internal/flag.h20
1 files changed, 18 insertions, 2 deletions
diff --git a/absl/flags/internal/flag.h b/absl/flags/internal/flag.h
index a84f7fa..1633038 100644
--- a/absl/flags/internal/flag.h
+++ b/absl/flags/internal/flag.h
@@ -16,12 +16,16 @@
#ifndef ABSL_FLAGS_INTERNAL_FLAG_H_
#define ABSL_FLAGS_INTERNAL_FLAG_H_
+#include <cstring>
+
#include "absl/flags/internal/commandlineflag.h"
#include "absl/flags/internal/registry.h"
namespace absl {
namespace flags_internal {
+constexpr int64_t AtomicInit() { return 0xababababababababll; }
+
// Signature for the mutation callback used by watched Flags
// The callback is noexcept.
// TODO(rogeeff): add noexcept after C++17 support is added.
@@ -44,6 +48,7 @@ class Flag final : public flags_internal::CommandLineFlag {
initial_value_gen,
/*def=*/nullptr,
/*cur=*/nullptr),
+ atomic_(flags_internal::AtomicInit()),
callback_(nullptr) {}
T Get() const {
@@ -76,8 +81,8 @@ class Flag final : public flags_internal::CommandLineFlag {
bool AtomicGet(T* v) const {
const int64_t r = atomic_.load(std::memory_order_acquire);
- if (r != flags_internal::CommandLineFlag::kAtomicInit) {
- memcpy(v, &r, sizeof(T));
+ if (r != flags_internal::AtomicInit()) {
+ std::memcpy(v, &r, sizeof(T));
return true;
}
@@ -108,7 +113,18 @@ class Flag final : public flags_internal::CommandLineFlag {
delete locks_;
}
+ void StoreAtomic() override {
+ if (sizeof(T) <= sizeof(int64_t)) {
+ int64_t t = 0;
+ std::memcpy(&t, cur_, (std::min)(sizeof(T), sizeof(int64_t)));
+ atomic_.store(t, std::memory_order_release);
+ }
+ }
+
// Flag's data
+ // For some types, a copy of the current value is kept in an atomically
+ // accessible field.
+ std::atomic<int64_t> atomic_;
FlagCallback callback_; // Mutation callback
};