]> git.proxmox.com Git - mirror_ovs.git/commitdiff
ovs-thread: Add pthread spin lock support.
authorWilliam Tu <u9012063@gmail.com>
Wed, 17 Jul 2019 20:23:33 +0000 (13:23 -0700)
committerIlya Maximets <i.maximets@samsung.com>
Fri, 19 Jul 2019 12:14:18 +0000 (15:14 +0300)
The patch adds the basic spin lock functions:
ovs_spin_{lock, try_lock, unlock, init, destroy}.

Signed-off-by: William Tu <u9012063@gmail.com>
Acked-by: Ilya Maximets <i.maximets@samsung.com>
Acked-by: Ben Pfaff <blp@ovn.org>
Signed-off-by: Ilya Maximets <i.maximets@samsung.com>
configure.ac
include/openvswitch/thread.h
lib/ovs-thread.c

index a9f0a06dc1404aeadd123299069d0ca7735611e2..0bbcc5ee93305506ddda6638a2ee90efe492c650 100644 (file)
@@ -79,6 +79,8 @@ AC_SEARCH_LIBS([clock_gettime], [rt])
 AC_SEARCH_LIBS([timer_create], [rt])
 AC_SEARCH_LIBS([pthread_rwlock_tryrdlock], [pthread])
 AC_SEARCH_LIBS([pthread_rwlockattr_destroy], [pthread])
+AC_SEARCH_LIBS([pthread_spin_lock], [pthread])
+AC_CHECK_FUNCS([pthread_spin_lock])
 AC_FUNC_STRERROR_R
 
 OVS_CHECK_WIN64
index 2987db37c9dcbaebb8b5baba5115e11eb1d899e0..acc822904847a3bc5146932477ccf6d7225fa306 100644 (file)
@@ -33,6 +33,13 @@ struct OVS_LOCKABLE ovs_mutex {
     const char *where;          /* NULL if and only if uninitialized. */
 };
 
+#ifdef HAVE_PTHREAD_SPIN_LOCK
+struct OVS_LOCKABLE ovs_spin {
+    pthread_spinlock_t lock;
+    const char *where;          /* NULL if and only if uninitialized. */
+};
+#endif
+
 /* "struct ovs_mutex" initializer. */
 #ifdef PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP
 #define OVS_MUTEX_INITIALIZER { PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP, \
@@ -70,6 +77,21 @@ int ovs_mutex_trylock_at(const struct ovs_mutex *mutex, const char *where)
 
 void ovs_mutex_cond_wait(pthread_cond_t *, const struct ovs_mutex *mutex)
     OVS_REQUIRES(mutex);
+
+#ifdef HAVE_PTHREAD_SPIN_LOCK
+void ovs_spin_init(const struct ovs_spin *);
+void ovs_spin_destroy(const struct ovs_spin *);
+void ovs_spin_unlock(const struct ovs_spin *spin) OVS_RELEASES(spin);
+void ovs_spin_lock_at(const struct ovs_spin *spin, const char *where)
+    OVS_ACQUIRES(spin);
+#define ovs_spin_lock(spin) \
+        ovs_spin_lock_at(spin, OVS_SOURCE_LOCATOR)
+
+int ovs_spin_trylock_at(const struct ovs_spin *spin, const char *where)
+    OVS_TRY_LOCK(0, spin);
+#define ovs_spin_trylock(spin) \
+        ovs_spin_trylock_at(spin, OVS_SOURCE_LOCATOR)
+#endif
 \f
 /* Convenient once-only execution.
  *
index 159d87e5b0cad62ff686f2e15375816caf83fe4c..b686e454812735ce48a82b775aae36629de63302 100644 (file)
@@ -75,6 +75,9 @@ static bool multithreaded;
 LOCK_FUNCTION(mutex, lock);
 LOCK_FUNCTION(rwlock, rdlock);
 LOCK_FUNCTION(rwlock, wrlock);
+#ifdef HAVE_PTHREAD_SPIN_LOCK
+LOCK_FUNCTION(spin, lock);
+#endif
 
 #define TRY_LOCK_FUNCTION(TYPE, FUN) \
     int \
@@ -103,6 +106,9 @@ LOCK_FUNCTION(rwlock, wrlock);
 TRY_LOCK_FUNCTION(mutex, trylock);
 TRY_LOCK_FUNCTION(rwlock, tryrdlock);
 TRY_LOCK_FUNCTION(rwlock, trywrlock);
+#ifdef HAVE_PTHREAD_SPIN_LOCK
+TRY_LOCK_FUNCTION(spin, trylock);
+#endif
 
 #define UNLOCK_FUNCTION(TYPE, FUN, WHERE) \
     void \
@@ -125,6 +131,10 @@ UNLOCK_FUNCTION(mutex, unlock, "<unlocked>");
 UNLOCK_FUNCTION(mutex, destroy, NULL);
 UNLOCK_FUNCTION(rwlock, unlock, "<unlocked>");
 UNLOCK_FUNCTION(rwlock, destroy, NULL);
+#ifdef HAVE_PTHREAD_SPIN_LOCK
+UNLOCK_FUNCTION(spin, unlock, "<unlocked>");
+UNLOCK_FUNCTION(spin, destroy, NULL);
+#endif
 
 #define XPTHREAD_FUNC1(FUNCTION, PARAM1)                \
     void                                                \
@@ -268,6 +278,27 @@ ovs_mutex_cond_wait(pthread_cond_t *cond, const struct ovs_mutex *mutex_)
     }
 }
 
+#ifdef HAVE_PTHREAD_SPIN_LOCK
+static void
+ovs_spin_init__(const struct ovs_spin *l_, int pshared)
+{
+    struct ovs_spin *l = CONST_CAST(struct ovs_spin *, l_);
+    int error;
+
+    l->where = "<unlocked>";
+    error = pthread_spin_init(&l->lock, pshared);
+    if (OVS_UNLIKELY(error)) {
+        ovs_abort(error, "pthread_spin_init failed");
+    }
+}
+
+void
+ovs_spin_init(const struct ovs_spin *spin)
+{
+    ovs_spin_init__(spin, PTHREAD_PROCESS_PRIVATE);
+}
+#endif
+
 /* Initializes the 'barrier'.  'size' is the number of threads
  * expected to hit the barrier. */
 void