about summary refs log tree commit diff
path: root/absl/flags
diff options
context:
space:
mode:
Diffstat (limited to 'absl/flags')
-rw-r--r--absl/flags/internal/commandlineflag.cc11
-rw-r--r--absl/flags/internal/commandlineflag.h12
-rw-r--r--absl/flags/internal/flag.h20
3 files changed, 23 insertions, 20 deletions
diff --git a/absl/flags/internal/commandlineflag.cc b/absl/flags/internal/commandlineflag.cc
index ae6a8d70fbf1..53e2b84ecc13 100644
--- a/absl/flags/internal/commandlineflag.cc
+++ b/absl/flags/internal/commandlineflag.cc
@@ -261,13 +261,6 @@ bool CommandLineFlag::SetFromString(absl::string_view value,
   return true;
 }
 
-void CommandLineFlag::StoreAtomic(size_t size) {
-  int64_t t = 0;
-  assert(size <= sizeof(int64_t));
-  memcpy(&t, cur_, size);
-  atomic_.store(t, std::memory_order_release);
-}
-
 void CommandLineFlag::CheckDefaultValueParsingRoundtrip() const {
   std::string v = DefaultValue();
 
@@ -305,8 +298,6 @@ bool CommandLineFlag::ValidateInputValue(absl::string_view value) const {
   return result;
 }
 
-const int64_t CommandLineFlag::kAtomicInit;
-
 void CommandLineFlag::Read(void* dst,
                            const flags_internal::FlagOpFn dst_op) const {
   absl::ReaderMutexLock l(InitFlagIfNecessary());
@@ -369,7 +360,7 @@ std::string HelpText::GetHelpText() const {
 void UpdateCopy(CommandLineFlag* flag) {
 #define STORE_ATOMIC(T)           \
   else if (flag->IsOfType<T>()) { \
-    flag->StoreAtomic(sizeof(T)); \
+    flag->StoreAtomic();          \
   }
 
   if (false) {
diff --git a/absl/flags/internal/commandlineflag.h b/absl/flags/internal/commandlineflag.h
index 572568b93711..284286b6be18 100644
--- a/absl/flags/internal/commandlineflag.h
+++ b/absl/flags/internal/commandlineflag.h
@@ -207,7 +207,6 @@ class CommandLineFlag {
         def_(def),
         cur_(cur),
         counter_(0),
-        atomic_(kAtomicInit),
         locks_(nullptr) {}
 
   // Virtual destructor
@@ -235,6 +234,10 @@ class CommandLineFlag {
   std::string DefaultValue() const;
   std::string CurrentValue() const;
 
+  // Interface to store the value in atomic if one used. This is short term
+  // interface. To be reworked once cur_ is moved.
+  virtual void StoreAtomic() {}
+
   // Interfaces to operate on validators.
   virtual bool HasValidatorFn() const { return false; }
   virtual bool InvokeValidator(const void* /*value*/) const { return true; }
@@ -276,8 +279,6 @@ class CommandLineFlag {
                      flags_internal::FlagSettingMode set_mode,
                      flags_internal::ValueSource source, std::string* error);
 
-  void StoreAtomic(size_t size);
-
   void CheckDefaultValueParsingRoundtrip() const;
 
   // Constant configuration for a particular flag.
@@ -300,11 +301,6 @@ class CommandLineFlag {
   void* cur_;             // Lazily initialized pointer to current value
   int64_t counter_;         // Mutation counter
 
-  // For some types, a copy of the current value is kept in an atomically
-  // accessible field.
-  static const int64_t kAtomicInit = 0xababababababababll;
-  std::atomic<int64_t> atomic_;
-
   // Lazily initialized mutexes for this flag value.  We cannot inline a
   // SpinLock or Mutex here because those have non-constexpr constructors and
   // so would prevent constant initialization of this type.
diff --git a/absl/flags/internal/flag.h b/absl/flags/internal/flag.h
index a84f7fa8d304..16330380f548 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
 };