Skip to content

Commit

Permalink
ovs-thread: Add pthread spin lock support.
Browse files Browse the repository at this point in the history
The patch adds the basic spin lock functions:
ovs_spin_{lock, try_lock, unlock, init, destroy}.
OSX does not support pthread spin lock, so make it
linux only.

Signed-off-by: William Tu <u9012063@gmail.com>
Signed-off-by: 0-day Robot <robot@bytheb.org>
  • Loading branch information
williamtu authored and ovsrobot committed Jul 9, 2019
1 parent cfc06fb commit a03f917
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 0 deletions.
22 changes: 22 additions & 0 deletions include/openvswitch/thread.h
Expand Up @@ -33,6 +33,13 @@ struct OVS_LOCKABLE ovs_mutex {
const char *where; /* NULL if and only if uninitialized. */
};

#ifdef __linux__
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, \
Expand Down Expand Up @@ -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 __linux__
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

/* Convenient once-only execution.
*
Expand Down
31 changes: 31 additions & 0 deletions lib/ovs-thread.c
Expand Up @@ -75,6 +75,9 @@ static bool multithreaded;
LOCK_FUNCTION(mutex, lock);
LOCK_FUNCTION(rwlock, rdlock);
LOCK_FUNCTION(rwlock, wrlock);
#ifdef __linux__
LOCK_FUNCTION(spin, lock);
#endif

#define TRY_LOCK_FUNCTION(TYPE, FUN) \
int \
Expand Down Expand Up @@ -103,6 +106,9 @@ LOCK_FUNCTION(rwlock, wrlock);
TRY_LOCK_FUNCTION(mutex, trylock);
TRY_LOCK_FUNCTION(rwlock, tryrdlock);
TRY_LOCK_FUNCTION(rwlock, trywrlock);
#ifdef __linux__
TRY_LOCK_FUNCTION(spin, trylock);
#endif

#define UNLOCK_FUNCTION(TYPE, FUN, WHERE) \
void \
Expand All @@ -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 __linux__
UNLOCK_FUNCTION(spin, unlock, "<unlocked>");
UNLOCK_FUNCTION(spin, destroy, NULL);
#endif

#define XPTHREAD_FUNC1(FUNCTION, PARAM1) \
void \
Expand Down Expand Up @@ -268,6 +278,27 @@ ovs_mutex_cond_wait(pthread_cond_t *cond, const struct ovs_mutex *mutex_)
}
}

#ifdef __linux__
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_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
Expand Down

0 comments on commit a03f917

Please sign in to comment.