]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
crimson, common: introduce ceph::atomic and apply it on bufferlist. 32766/head
authorRadoslaw Zarzynski <rzarzyns@redhat.com>
Mon, 20 Jan 2020 15:48:06 +0000 (16:48 +0100)
committerRadoslaw Zarzynski <rzarzyns@redhat.com>
Tue, 21 Jan 2020 18:53:38 +0000 (19:53 +0100)
Signed-off-by: Radoslaw Zarzynski <rzarzyns@redhat.com>
src/common/buffer.cc
src/common/ceph_atomic.h [new file with mode: 0644]
src/crimson/CMakeLists.txt
src/include/buffer_raw.h

index 01a3dc82f0d8a41676a918161b1c9b2999b1ff5c..a77be1e7943bff8c4c41e5a9d31eaf9f5acda428 100644 (file)
@@ -50,9 +50,9 @@ static ceph::spinlock debug_lock;
 # define bendl std::endl; }
 #endif
 
-  static std::atomic<unsigned> buffer_cached_crc { 0 };
-  static std::atomic<unsigned> buffer_cached_crc_adjusted { 0 };
-  static std::atomic<unsigned> buffer_missed_crc { 0 };
+  static ceph::atomic<unsigned> buffer_cached_crc { 0 };
+  static ceph::atomic<unsigned> buffer_cached_crc_adjusted { 0 };
+  static ceph::atomic<unsigned> buffer_missed_crc { 0 };
 
   static bool buffer_track_crc = get_env_bool("CEPH_BUFFER_TRACK");
 
diff --git a/src/common/ceph_atomic.h b/src/common/ceph_atomic.h
new file mode 100644 (file)
index 0000000..26a20ee
--- /dev/null
@@ -0,0 +1,85 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+
+#pragma once
+
+#include <atomic>
+
+// What and why
+// ============
+//
+// ceph::atomic – thin wrapper to differentiate behavior of atomics.
+//
+// Not all users of the common truly need costly atomic operations to
+// synchronize data between CPUs and threads. Some, like crimson-osd,
+// stick to shared-nothing approach. Enforcing issue of atomics in
+// such cases is wasteful – on x86 any locked instruction works actually
+// like a full memory barrier stalling execution till CPU's store and
+// load buffers are drained.
+
+#ifdef WITH_SEASTAR
+
+#include <type_traits>
+
+namespace ceph {
+  template <class T>
+  class dummy_atomic {
+    T value;
+
+  public:
+    dummy_atomic() = default;
+    dummy_atomic(const dummy_atomic&) = delete;
+    dummy_atomic(T value) : value(std::move(value)) {
+    }
+    bool is_lock_free() const noexcept {
+      return true;
+    }
+    void store(T desired, std::memory_order) noexcept {
+      value = std::move(desired);
+    }
+    T load(std::memory_order = std::memory_order_seq_cst) const noexcept {
+      return value;
+    }
+    T operator=(T desired) noexcept {
+      value = std::move(desired);
+    }
+    operator T() const noexcept {
+      return value;
+    }
+
+    // We need to differentiate with SFINAE as std::atomic offers beefier
+    // interface for integral types.
+    std::enable_if_t<std::is_integral_v<T>, T> operator++() {
+      return ++value;
+    }
+    std::enable_if_t<std::is_integral_v<T>, T> operator++(int) {
+      return value++;
+    }
+    std::enable_if_t<std::is_integral_v<T>, T> operator--() {
+      return --value;
+    }
+    std::enable_if_t<std::is_integral_v<T>, T> operator--(int) {
+      return value--;
+    }
+    std::enable_if_t<std::is_integral_v<T>, T> operator+=(const dummy_atomic& b) {
+      value += b;
+      return value;
+    }
+    std::enable_if_t<std::is_integral_v<T>, T> operator-=(const dummy_atomic& b) {
+      value -= b;
+      return value;
+    }
+
+    static constexpr bool is_always_lock_free = true;
+  };
+
+  template <class T> using atomic = dummy_atomic<T>;
+} // namespace ceph
+
+#else  // WITH_SEASTAR
+
+namespace ceph {
+  template <class T> using atomic = ::std::atomic<T>;
+} // namespace ceph
+
+#endif // WITH_SEASTAR
index 25092fb84fe22cfeaa62dd3bbd7255ce83cb872e..3d2ffc066efb609e4b14aa4652f125b38f82352b 100644 (file)
@@ -18,6 +18,7 @@ add_library(crimson-common STATIC
   ${PROJECT_SOURCE_DIR}/src/common/admin_socket_client.cc
   ${PROJECT_SOURCE_DIR}/src/common/bit_str.cc
   ${PROJECT_SOURCE_DIR}/src/common/bloom_filter.cc
+  ${PROJECT_SOURCE_DIR}/src/common/buffer.cc
   ${PROJECT_SOURCE_DIR}/src/common/ceph_argparse.cc
   ${PROJECT_SOURCE_DIR}/src/common/ceph_context.cc
   ${PROJECT_SOURCE_DIR}/src/common/ceph_crypto.cc
@@ -95,7 +96,6 @@ add_library(crimson-common STATIC
   ${PROJECT_SOURCE_DIR}/src/osd/PGPeeringEvent.cc
   ${crimson_common_srcs}
   $<TARGET_OBJECTS:crimson-auth>
-  $<TARGET_OBJECTS:common_buffer_obj>
   $<TARGET_OBJECTS:common_mountcephfs_objs>
   $<TARGET_OBJECTS:crimson-crush>)
 
index a79afedbec514e67d75f055b24d21e50ecb237c0..a0483115782118d30fe31cf450f943f69d32d19e 100644 (file)
 #ifndef CEPH_BUFFER_RAW_H
 #define CEPH_BUFFER_RAW_H
 
-#include <atomic>
 #include <map>
 #include <utility>
 #include <type_traits>
+#include "common/ceph_atomic.h"
 #include "include/buffer.h"
 #include "include/mempool.h"
 #include "include/spinlock.h"
@@ -34,7 +34,7 @@ inline namespace v14_2_0 {
                         alignof(ptr_node)>::type bptr_storage;
     char *data;
     unsigned len;
-    std::atomic<unsigned> nref { 0 };
+    ceph::atomic<unsigned> nref { 0 };
     int mempool;
 
     std::pair<size_t, size_t> last_crc_offset {std::numeric_limits<size_t>::max(), std::numeric_limits<size_t>::max()};