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, \
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.
*
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 \
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 \
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 \
}
}
+#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