Commit 85457b33 authored by Rich Prohaska's avatar Rich Prohaska Committed by Yoni Fogel

#4753 simplify pthread rwlocks interface closes[t:4753]

git-svn-id: file:///svn/toku/tokudb@43670 c7de825b-a66e-492c-adef-691d508d4ae1
parent b624dcb4
......@@ -5460,7 +5460,7 @@ int toku_brt_init(void (*ydb_lock_callback)(void),
if (r==0)
r = toku_portability_init();
if (r==0)
r = toku_checkpoint_init(ydb_lock_callback, ydb_unlock_callback);
toku_checkpoint_init(ydb_lock_callback, ydb_unlock_callback);
if (r == 0)
r = toku_brt_serialize_init();
return r;
......@@ -5471,7 +5471,7 @@ int toku_brt_destroy(void) {
if (r == 0)
r = toku_brt_serialize_destroy();
if (r==0)
r = toku_checkpoint_destroy();
toku_checkpoint_destroy();
//Portability must be cleaned up last
if (r==0)
r = toku_portability_destroy();
......
......@@ -130,7 +130,7 @@ static volatile BOOL locked_cs = FALSE; // true when the checkpoint_safe w
// and use the "writer" calls for locking and unlocking.
static int
static void
multi_operation_lock_init(void) {
pthread_rwlockattr_t attr;
pthread_rwlockattr_init(&attr);
......@@ -140,61 +140,49 @@ multi_operation_lock_init(void) {
// TODO: need to figure out how to make writer-preferential rwlocks
// happen on osx
#endif
int r = toku_pthread_rwlock_init(&multi_operation_lock, &attr);
toku_pthread_rwlock_init(&multi_operation_lock, &attr);
pthread_rwlockattr_destroy(&attr);
assert(r == 0);
locked_mo = FALSE;
return r;
}
static int
static void
multi_operation_lock_destroy(void) {
int r = toku_pthread_rwlock_destroy(&multi_operation_lock);
assert(r == 0);
return r;
toku_pthread_rwlock_destroy(&multi_operation_lock);
}
static void
multi_operation_checkpoint_lock(void) {
int r = toku_pthread_rwlock_wrlock(&multi_operation_lock);
assert(r == 0);
toku_pthread_rwlock_wrlock(&multi_operation_lock);
locked_mo = TRUE;
}
static void
multi_operation_checkpoint_unlock(void) {
locked_mo = FALSE;
int r = toku_pthread_rwlock_wrunlock(&multi_operation_lock);
assert(r == 0);
toku_pthread_rwlock_wrunlock(&multi_operation_lock);
}
static int
static void
checkpoint_safe_lock_init(void) {
int r = toku_pthread_rwlock_init(&checkpoint_safe_lock, NULL);
assert(r == 0);
toku_pthread_rwlock_init(&checkpoint_safe_lock, NULL);
locked_cs = FALSE;
return r;
}
static int
static void
checkpoint_safe_lock_destroy(void) {
int r = toku_pthread_rwlock_destroy(&checkpoint_safe_lock);
assert(r == 0);
return r;
toku_pthread_rwlock_destroy(&checkpoint_safe_lock);
}
static void
checkpoint_safe_checkpoint_lock(void) {
int r = toku_pthread_rwlock_wrlock(&checkpoint_safe_lock);
assert(r == 0);
toku_pthread_rwlock_wrlock(&checkpoint_safe_lock);
locked_cs = TRUE;
}
static void
checkpoint_safe_checkpoint_unlock(void) {
locked_cs = FALSE;
int r = toku_pthread_rwlock_wrunlock(&checkpoint_safe_lock);
assert(r == 0);
toku_pthread_rwlock_wrunlock(&checkpoint_safe_lock);
}
......@@ -205,58 +193,45 @@ void
toku_multi_operation_client_lock(void) {
if (locked_mo)
(void) __sync_fetch_and_add(&STATUS_VALUE(CP_CLIENT_WAIT_ON_MO), 1);
int r = toku_pthread_rwlock_rdlock(&multi_operation_lock);
assert(r == 0);
toku_pthread_rwlock_rdlock(&multi_operation_lock);
}
void
toku_multi_operation_client_unlock(void) {
int r = toku_pthread_rwlock_rdunlock(&multi_operation_lock);
assert(r == 0);
toku_pthread_rwlock_rdunlock(&multi_operation_lock);
}
void
toku_checkpoint_safe_client_lock(void) {
if (locked_cs)
(void) __sync_fetch_and_add(&STATUS_VALUE(CP_CLIENT_WAIT_ON_CS), 1);
int r = toku_pthread_rwlock_rdlock(&checkpoint_safe_lock);
assert(r == 0);
toku_pthread_rwlock_rdlock(&checkpoint_safe_lock);
toku_multi_operation_client_lock();
}
void
toku_checkpoint_safe_client_unlock(void) {
int r = toku_pthread_rwlock_rdunlock(&checkpoint_safe_lock);
assert(r == 0);
toku_pthread_rwlock_rdunlock(&checkpoint_safe_lock);
toku_multi_operation_client_unlock();
}
// Initialize the checkpoint mechanism, must be called before any client operations.
int
void
toku_checkpoint_init(void (*ydb_lock_callback)(void), void (*ydb_unlock_callback)(void)) {
int r = 0;
ydb_lock = ydb_lock_callback;
ydb_unlock = ydb_unlock_callback;
if (r==0)
r = multi_operation_lock_init();
if (r==0)
r = checkpoint_safe_lock_init();
if (r==0)
multi_operation_lock_init();
checkpoint_safe_lock_init();
initialized = TRUE;
return r;
}
int
void
toku_checkpoint_destroy(void) {
int r = 0;
if (r==0)
r = multi_operation_lock_destroy();
if (r==0)
r = checkpoint_safe_lock_destroy();
multi_operation_lock_destroy();
checkpoint_safe_lock_destroy();
initialized = FALSE;
return r;
}
#define SET_CHECKPOINT_FOOTPRINT(x) STATUS_VALUE(CP_FOOTPRINT) = footprint_offset + x
......
......@@ -57,9 +57,9 @@ void toku_multi_operation_client_unlock(void);
// Initialize the checkpoint mechanism, must be called before any client operations.
// Must pass in function pointers to take/release ydb lock.
int toku_checkpoint_init(void (*ydb_lock_callback)(void), void (*ydb_unlock_callback)(void));
void toku_checkpoint_init(void (*ydb_lock_callback)(void), void (*ydb_unlock_callback)(void));
int toku_checkpoint_destroy(void);
void toku_checkpoint_destroy(void);
typedef enum {SCHEDULED_CHECKPOINT = 0, // "normal" checkpoint taken on checkpoint thread
CLIENT_CHECKPOINT = 1, // induced by client, such as FLUSH LOGS or SAVEPOINT
......
......@@ -145,34 +145,40 @@ toku_pthread_self(void) {
}
#if 1
static inline int
static inline void
toku_pthread_rwlock_init(toku_pthread_rwlock_t *__restrict rwlock, const toku_pthread_rwlockattr_t *__restrict attr) {
return pthread_rwlock_init(rwlock, attr);
int r = pthread_rwlock_init(rwlock, attr);
assert_zero(r);
}
static inline int
static inline void
toku_pthread_rwlock_destroy(toku_pthread_rwlock_t *rwlock) {
return pthread_rwlock_destroy(rwlock);
int r = pthread_rwlock_destroy(rwlock);
assert_zero(r);
}
static inline int
static inline void
toku_pthread_rwlock_rdlock(toku_pthread_rwlock_t *rwlock) {
return pthread_rwlock_rdlock(rwlock);
int r = pthread_rwlock_rdlock(rwlock);
assert_zero(r);
}
static inline int
static inline void
toku_pthread_rwlock_rdunlock(toku_pthread_rwlock_t *rwlock) {
return pthread_rwlock_unlock(rwlock);
int r = pthread_rwlock_unlock(rwlock);
assert_zero(r);
}
static inline int
static inline void
toku_pthread_rwlock_wrlock(toku_pthread_rwlock_t *rwlock) {
return pthread_rwlock_wrlock(rwlock);
int r = pthread_rwlock_wrlock(rwlock);
assert_zero(r);
}
static inline int
static inline void
toku_pthread_rwlock_wrunlock(toku_pthread_rwlock_t *rwlock) {
return pthread_rwlock_unlock(rwlock);
int r = pthread_rwlock_unlock(rwlock);
assert_zero(r);
}
#endif
......
......@@ -5,15 +5,14 @@
#include <unistd.h>
int test_main(int argc __attribute__((__unused__)), char *const argv[] __attribute__((__unused__))) {
int r;
toku_pthread_rwlock_t rwlock;
r = toku_pthread_rwlock_init(&rwlock, NULL); assert(r == 0);
r = toku_pthread_rwlock_rdlock(&rwlock); assert(r == 0);
r = toku_pthread_rwlock_rdlock(&rwlock); assert(r == 0);
r = toku_pthread_rwlock_rdunlock(&rwlock); assert(r == 0);
r = toku_pthread_rwlock_rdunlock(&rwlock); assert(r == 0);
r = toku_pthread_rwlock_destroy(&rwlock); assert(r == 0);
toku_pthread_rwlock_init(&rwlock, NULL);
toku_pthread_rwlock_rdlock(&rwlock);
toku_pthread_rwlock_rdlock(&rwlock);
toku_pthread_rwlock_rdunlock(&rwlock);
toku_pthread_rwlock_rdunlock(&rwlock);
toku_pthread_rwlock_destroy(&rwlock);
return 0;
}
......
......@@ -11,13 +11,12 @@ volatile int state = 0;
int verbose = 0;
static void *f(void *arg) {
int r;
toku_pthread_rwlock_t *mylock = arg;
sleep(2);
assert(state==42); state = 16; if (verbose) printf("%s:%d\n", __FUNCTION__, __LINE__);
r = toku_pthread_rwlock_wrlock(mylock); assert(r == 0);
toku_pthread_rwlock_wrlock(mylock);
assert(state==49); state = 17; if (verbose) printf("%s:%d\n", __FUNCTION__, __LINE__);
r = toku_pthread_rwlock_wrunlock(mylock); assert(r == 0);
toku_pthread_rwlock_wrunlock(mylock);
sleep(10);
assert(state==52); state = 20; if (verbose) printf("%s:%d\n", __FUNCTION__, __LINE__);
return arg;
......@@ -34,27 +33,27 @@ int test_main(int argc , char *const argv[] ) {
toku_pthread_t tid;
void *retptr;
r = toku_pthread_rwlock_init(&rwlock, NULL); assert(r == 0);
toku_pthread_rwlock_init(&rwlock, NULL);
state = 37; if (verbose) printf("%s:%d\n", __FUNCTION__, __LINE__);
r = toku_pthread_rwlock_rdlock(&rwlock); assert(r == 0);
toku_pthread_rwlock_rdlock(&rwlock);
r = toku_pthread_create(&tid, NULL, f, &rwlock); assert(r == 0);
assert(state==37); state = 42; if (verbose) printf("%s:%d\n", __FUNCTION__, __LINE__);
sleep(4);
assert(state==16); state = 44; if (verbose) printf("%s:%d\n", __FUNCTION__, __LINE__);
r = toku_pthread_rwlock_rdlock(&rwlock); assert(r == 0);
toku_pthread_rwlock_rdlock(&rwlock);
assert(state==44); state = 46; if (verbose) printf("%s:%d\n", __FUNCTION__, __LINE__);
r = toku_pthread_rwlock_rdunlock(&rwlock); assert(r == 0);
toku_pthread_rwlock_rdunlock(&rwlock);
sleep(4);
assert(state==46); state=49; if (verbose) printf("%s:%d\n", __FUNCTION__, __LINE__); // still have a read lock
r = toku_pthread_rwlock_rdunlock(&rwlock); assert(r == 0);
toku_pthread_rwlock_rdunlock(&rwlock);
sleep(6);
assert(state==17); state=52; if (verbose) printf("%s:%d\n", __FUNCTION__, __LINE__);
r = toku_pthread_join(tid, &retptr); assert(r == 0);
r = toku_pthread_rwlock_destroy(&rwlock); assert(r == 0);
toku_pthread_rwlock_destroy(&rwlock);
return 0;
}
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