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