Commit 7bfe699d authored by John Esmet's avatar John Esmet Committed by Yoni Fogel

close[t:4284] the non blocking mutex implementation is now a wrapper of the...

close[t:4284] the non blocking mutex implementation is now a wrapper of the rwlock implementation. the non blocking mutex api uses only the writer portion of the rwlock api


git-svn-id: file:///svn/toku/tokudb@39143 c7de825b-a66e-492c-adef-691d508d4ae1
parent 2b70bb19
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
extern "C" { extern "C" {
#endif #endif
//Use case: #include "rwlock.h"
//Use case: //Use case:
// General purpose non blocking mutex with properties: // General purpose non blocking mutex with properties:
...@@ -24,74 +24,53 @@ extern "C" { ...@@ -24,74 +24,53 @@ extern "C" {
typedef struct nb_mutex *NB_MUTEX; typedef struct nb_mutex *NB_MUTEX;
struct nb_mutex { struct nb_mutex {
int writer; // the number of writers struct rwlock lock;
int want_write; // the number of blocked writers
toku_pthread_cond_t wait_write;
}; };
// initialize a read write lock // initialize an nb mutex
static __attribute__((__unused__)) static __attribute__((__unused__))
void void
nb_mutex_init(NB_MUTEX nb_mutex) { nb_mutex_init(NB_MUTEX nb_mutex) {
int r; rwlock_init(&nb_mutex->lock);
nb_mutex->writer = nb_mutex->want_write = 0;
r = toku_pthread_cond_init(&nb_mutex->wait_write, 0); assert(r == 0);
} }
// destroy a read write lock // destroy a read write lock
static __attribute__((__unused__)) static __attribute__((__unused__))
void void
nb_mutex_destroy(NB_MUTEX nb_mutex) { nb_mutex_destroy(NB_MUTEX nb_mutex) {
int r; rwlock_destroy(&nb_mutex->lock);
assert(nb_mutex->writer == 0 && nb_mutex->want_write == 0);
r = toku_pthread_cond_destroy(&nb_mutex->wait_write); assert(r == 0);
} }
// obtain a write lock // obtain a write lock
// expects: mutex is locked // expects: mutex is locked
static inline void nb_mutex_write_lock(NB_MUTEX nb_mutex,
static inline void nb_mutex_write_lock(NB_MUTEX nb_mutex, toku_pthread_mutex_t *mutex) { toku_pthread_mutex_t *mutex) {
if (nb_mutex->writer) { rwlock_write_lock(&nb_mutex->lock, mutex);
nb_mutex->want_write++;
while (nb_mutex->writer) {
int r = toku_pthread_cond_wait(&nb_mutex->wait_write, mutex); assert(r == 0);
}
nb_mutex->want_write--;
}
nb_mutex->writer++;
} }
// release a write lock // release a write lock
// expects: mutex is locked // expects: mutex is locked
static inline void nb_mutex_write_unlock(NB_MUTEX nb_mutex) { static inline void nb_mutex_write_unlock(NB_MUTEX nb_mutex) {
assert(nb_mutex->writer == 1); rwlock_write_unlock(&nb_mutex->lock);
nb_mutex->writer--;
if (nb_mutex->want_write) {
int r = toku_pthread_cond_signal(&nb_mutex->wait_write); assert(r == 0);
}
} }
// returns: the number of writers who are waiting for the lock // returns: the number of writers who are waiting for the lock
static inline int nb_mutex_blocked_writers(NB_MUTEX nb_mutex) { static inline int nb_mutex_blocked_writers(NB_MUTEX nb_mutex) {
return nb_mutex->want_write; return rwlock_blocked_writers(&nb_mutex->lock);
} }
// returns: the number of writers // returns: the number of writers
static inline int nb_mutex_writers(NB_MUTEX nb_mutex) { static inline int nb_mutex_writers(NB_MUTEX nb_mutex) {
return nb_mutex->writer; return rwlock_writers(&nb_mutex->lock);
} }
// returns: the sum of the number of readers, pending readers, writers, and // returns: the sum of the number of readers, pending readers,
// pending writers // writers, and pending writers
static inline int nb_mutex_users(NB_MUTEX nb_mutex) { static inline int nb_mutex_users(NB_MUTEX nb_mutex) {
return nb_mutex->writer + nb_mutex->want_write; return rwlock_users(&nb_mutex->lock);
} }
#if defined(__cplusplus) || defined(__cilkplusplus) #if defined(__cplusplus) || defined(__cilkplusplus)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment