]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
spinlock: add generic spinlock implementation 1008/head
authorNoah Watkins <noahwatkins@gmail.com>
Sun, 21 Jul 2013 01:41:40 +0000 (18:41 -0700)
committerNoah Watkins <noahwatkins@gmail.com>
Sat, 28 Dec 2013 22:43:14 +0000 (14:43 -0800)
Adds a ceph_spinlock_t implementation that will use pthread_spinlock_t
if available, and otherwise reverts to pthread_mutex_t. Note that this
spinlock is not intended to be used in process-shared memory.

Switches implementation in:

  ceph_context
  SimpleMessenger
  atomic_t

Only ceph_context initialized its spinlock with PTHREAD_PROCESS_SHARED.
However, there does not appear to be any instance in which CephContext
is allocated in shared memory, and thus can use the default private
memory space behavior.

Signed-off-by: Noah Watkins <noahwatkins@gmail.com>
configure.ac
src/common/ceph_context.cc
src/common/ceph_context.h
src/include/Spinlock.h
src/include/atomic.h
src/msg/SimpleMessenger.cc
src/msg/SimpleMessenger.h

index 3520acf1213203d5193e0858d14e85599298790d..8ed663dc1b83b7fb065ee1c18329447dc08d7aa1 100644 (file)
@@ -664,6 +664,18 @@ AC_DEFINE([HAVE_FDATASYNC], 1, [Define to 1 if you have fdatasync.])
 AC_MSG_RESULT([no])
 ])
 
+#
+# Check for pthread spinlock (depends on ACX_PTHREAD)
+#
+saved_LIBS="$LIBS"
+saved_CFLAGS="$CFLAGS"
+LIBS="$PTHREAD_LIBS $LIBS"
+CFLAGS="$PTHREAD_CFLAGS $CFLAGS"
+AC_CHECK_FUNC([pthread_spin_init],
+  [AC_DEFINE(HAVE_PTHREAD_SPINLOCK, 1, [Define if you have pthread_spin_init])])
+LIBS="$saved_LIBS"
+CFLAGS="$saved_CFLAGS"
+
 # Checks for typedefs, structures, and compiler characteristics.
 #AC_HEADER_STDBOOL
 #AC_C_CONST
index 3116abc3ff6d228b10e904898a2f8b73023b44c7..f7c2df5537e7c819eaa335a79cd4ba2e25ad87f9 100644 (file)
@@ -33,6 +33,8 @@
 #include <iostream>
 #include <pthread.h>
 
+#include "include/Spinlock.h"
+
 using ceph::HeartbeatMap;
 
 class CephContextServiceThread : public Thread
@@ -260,7 +262,7 @@ CephContext::CephContext(uint32_t module_type_)
     _crypto_none(NULL),
     _crypto_aes(NULL)
 {
-  pthread_spin_init(&_service_thread_lock, PTHREAD_PROCESS_SHARED);
+  ceph_spin_init(&_service_thread_lock);
 
   _log = new ceph::log::Log(&_conf->subsys);
   _log->start();
@@ -330,7 +332,7 @@ CephContext::~CephContext()
   _log = NULL;
 
   delete _conf;
-  pthread_spin_destroy(&_service_thread_lock);
+  ceph_spin_destroy(&_service_thread_lock);
 
   delete _crypto_none;
   delete _crypto_aes;
@@ -338,14 +340,14 @@ CephContext::~CephContext()
 
 void CephContext::start_service_thread()
 {
-  pthread_spin_lock(&_service_thread_lock);
+  ceph_spin_lock(&_service_thread_lock);
   if (_service_thread) {
-    pthread_spin_unlock(&_service_thread_lock);
+    ceph_spin_unlock(&_service_thread_lock);
     return;
   }
   _service_thread = new CephContextServiceThread(this);
   _service_thread->create();
-  pthread_spin_unlock(&_service_thread_lock);
+  ceph_spin_unlock(&_service_thread_lock);
 
   // make logs flush on_exit()
   if (_conf->log_flush_on_exit)
@@ -363,22 +365,22 @@ void CephContext::start_service_thread()
 
 void CephContext::reopen_logs()
 {
-  pthread_spin_lock(&_service_thread_lock);
+  ceph_spin_lock(&_service_thread_lock);
   if (_service_thread)
     _service_thread->reopen_logs();
-  pthread_spin_unlock(&_service_thread_lock);
+  ceph_spin_unlock(&_service_thread_lock);
 }
 
 void CephContext::join_service_thread()
 {
-  pthread_spin_lock(&_service_thread_lock);
+  ceph_spin_lock(&_service_thread_lock);
   CephContextServiceThread *thread = _service_thread;
   if (!thread) {
-    pthread_spin_unlock(&_service_thread_lock);
+    ceph_spin_unlock(&_service_thread_lock);
     return;
   }
   _service_thread = NULL;
-  pthread_spin_unlock(&_service_thread_lock);
+  ceph_spin_unlock(&_service_thread_lock);
 
   thread->exit_thread();
   thread->join();
index 08efeceaa674b4b63eb12c3623899fec42db26f9..ba6062032e7df177fabcf8ce04bd1bf144388cb5 100644 (file)
@@ -21,6 +21,7 @@
 #include "include/buffer.h"
 #include "include/atomic.h"
 #include "common/cmdparse.h"
+#include "include/Spinlock.h"
 
 class AdminSocket;
 class CephContextServiceThread;
@@ -126,7 +127,7 @@ private:
   AdminSocket *_admin_socket;
 
   /* lock which protects service thread creation, destruction, etc. */
-  pthread_spinlock_t _service_thread_lock;
+  ceph_spinlock_t _service_thread_lock;
 
   /* The collection of profiling loggers associated with this context */
   PerfCountersCollection *_perf_counters_collection;
index 6154ae1124b5ab6fde2fb8c353c70804018bb796..d0584c5953dee7e094a5a43dee694b38cf691425 100644 (file)
 #ifndef CEPH_SPINLOCK_H
 #define CEPH_SPINLOCK_H
 
+#include "acconfig.h"
+
 #include <pthread.h>
 
+typedef struct {
+#ifdef HAVE_PTHREAD_SPINLOCK
+  pthread_spinlock_t lock;
+#else
+  pthread_mutex_t lock;
+#endif
+} ceph_spinlock_t;
+
+#ifdef HAVE_PTHREAD_SPINLOCK
+
+static inline int ceph_spin_init(ceph_spinlock_t *l)
+{
+  return pthread_spin_init(&l->lock, PTHREAD_PROCESS_PRIVATE);
+}
+
+static inline int ceph_spin_destroy(ceph_spinlock_t *l)
+{
+  return pthread_spin_destroy(&l->lock);
+}
+
+static inline int ceph_spin_lock(ceph_spinlock_t *l)
+{
+  return pthread_spin_lock(&l->lock);
+}
+
+static inline int ceph_spin_unlock(ceph_spinlock_t *l)
+{
+  return pthread_spin_unlock(&l->lock);
+}
+
+#else /* !HAVE_PTHREAD_SPINLOCK */
+
+static inline int ceph_spin_init(ceph_spinlock_t *l)
+{
+  return pthread_mutex_init(&l->lock, NULL);
+}
+
+static inline int ceph_spin_destroy(ceph_spinlock_t *l)
+{
+  return pthread_mutex_destroy(&l->lock);
+}
+
+static inline int ceph_spin_lock(ceph_spinlock_t *l)
+{
+  return pthread_mutex_lock(&l->lock);
+}
+
+static inline int ceph_spin_unlock(ceph_spinlock_t *l)
+{
+  return pthread_mutex_unlock(&l->lock);
+}
+
+#endif
+
 class Spinlock {
-  mutable pthread_spinlock_t _lock;
+  mutable ceph_spinlock_t _lock;
 
 public:
   Spinlock() {
-    pthread_spin_init(&_lock, PTHREAD_PROCESS_PRIVATE);
+    ceph_spin_init(&_lock);
   }
   ~Spinlock() {
-    pthread_spin_destroy(&_lock);
+    ceph_spin_destroy(&_lock);
   }
 
   // don't allow copying.
@@ -35,11 +91,11 @@ public:
 
   /// acquire spinlock
   void lock() const {
-    pthread_spin_lock(&_lock);
+    ceph_spin_lock(&_lock);
   }
   /// release spinlock
   void unlock() const {
-    pthread_spin_unlock(&_lock);
+    ceph_spin_unlock(&_lock);
   }
 
   class Locker {
index 3ecbd28737634a61c06c040f9bcf7f4b682d5eb7..537fa989cd3f6f9357710f23d23a2eb3ba23ff07 100644 (file)
@@ -67,53 +67,52 @@ namespace ceph {
 /*
  * crappy slow implementation that uses a pthreads spinlock.
  */
-#include <pthread.h>
-#include "include/assert.h"
+#include "include/Spinlock.h"
 
 namespace ceph {
   class atomic_t {
-    mutable pthread_spinlock_t lock;
+    mutable ceph_spinlock_t lock;
     signed long val;
   public:
     atomic_t(int i=0)
       : val(i) {
-      pthread_spin_init(&lock, PTHREAD_PROCESS_PRIVATE);
+      ceph_spin_init(&lock);
     }
     ~atomic_t() {
-      pthread_spin_destroy(&lock);
+      ceph_spin_destroy(&lock);
     }
     void set(size_t v) {
-      pthread_spin_lock(&lock);
+      ceph_spin_lock(&lock);
       val = v;
-      pthread_spin_unlock(&lock);
+      ceph_spin_unlock(&lock);
     }
     int inc() {
-      pthread_spin_lock(&lock);
+      ceph_spin_lock(&lock);
       int r = ++val;
-      pthread_spin_unlock(&lock);
+      ceph_spin_unlock(&lock);
       return r;
     }
     int dec() {
-      pthread_spin_lock(&lock);
+      ceph_spin_lock(&lock);
       int r = --val;
-      pthread_spin_unlock(&lock);
+      ceph_spin_unlock(&lock);
       return r;
     }
     void add(int d) {
-      pthread_spin_lock(&lock);
+      ceph_spin_lock(&lock);
       val += d;
-      pthread_spin_unlock(&lock);
+      ceph_spin_unlock(&lock);
     }
     void sub(int d) {
-      pthread_spin_lock(&lock);
+      ceph_spin_lock(&lock);
       val -= d;
-      pthread_spin_unlock(&lock);
+      ceph_spin_unlock(&lock);
     }
     int read() const {
       signed long ret;
-      pthread_spin_lock(&lock);
+      ceph_spin_lock(&lock);
       ret = val;
-      pthread_spin_unlock(&lock);
+      ceph_spin_unlock(&lock);
       return ret;
     }
   private:
index 441ed432af00bf57c085482cde46a8290262c110..a80b39c71ea8582aa3849d341e1dd2ec4ae83f72 100644 (file)
@@ -23,6 +23,7 @@
 #include "common/Timer.h"
 #include "common/errno.h"
 #include "auth/Crypto.h"
+#include "include/Spinlock.h"
 
 #define dout_subsys ceph_subsys_ms
 #undef dout_prefix
@@ -53,7 +54,7 @@ SimpleMessenger::SimpleMessenger(CephContext *cct, entity_name_t name,
     timeout(0),
     local_connection(new Connection(this))
 {
-  pthread_spin_init(&global_seq_lock, PTHREAD_PROCESS_PRIVATE);
+  ceph_spin_init(&global_seq_lock);
   init_local_connection();
 }
 
index 6860c6c21a3a76f23fd9f57b7a3a17dffb88f93c..6c29999344959200e501e9de73692898dab5af78 100644 (file)
@@ -38,6 +38,7 @@ using namespace __gnu_cxx;
 
 #include "Pipe.h"
 #include "Accepter.h"
+#include "include/Spinlock.h"
 
 /*
  * This class handles transmission and reception of messages. Generally
@@ -308,7 +309,7 @@ private:
   /// counter for the global seq our connection protocol uses
   __u32 global_seq;
   /// lock to protect the global_seq
-  pthread_spinlock_t global_seq_lock;
+  ceph_spinlock_t global_seq_lock;
 
   /**
    * hash map of addresses to Pipes
@@ -388,11 +389,11 @@ public:
    * @return a global sequence ID that nobody else has seen.
    */
   __u32 get_global_seq(__u32 old=0) {
-    pthread_spin_lock(&global_seq_lock);
+    ceph_spin_lock(&global_seq_lock);
     if (old > global_seq)
       global_seq = old;
     __u32 ret = ++global_seq;
-    pthread_spin_unlock(&global_seq_lock);
+    ceph_spin_unlock(&global_seq_lock);
     return ret;
   }
   /**