Commit 5703873e authored by Rich Prohaska's avatar Rich Prohaska Committed by Yoni Fogel

#4437 fix race in the bdb deadlock tests refs[t:4437]


git-svn-id: file:///svn/toku/tokudb@39188 c7de825b-a66e-492c-adef-691d508d4ae1
parent 97e85670
......@@ -4,10 +4,9 @@
//
// A write locks L
// B write locks M
// A tries to write lock M, gets blocked
// B tries to write lock L, gets DEADLOCK error
// B releases its lock on M
// A resumes
// A tries to write lock M && B tries to write lock L
// One of A or B gets the DEADLOCK error, the other waits
// A and B release their locks
#include "test.h"
#include "toku_pthread.h"
......@@ -51,6 +50,7 @@ static void test_seq_next_state(struct test_seq *seq) {
struct locker_args {
DB_ENV *db_env;
struct test_seq *test_seq;
int *deadlock_count;
};
static void *run_locker_a(void *arg) {
......@@ -72,11 +72,20 @@ static void *run_locker_a(void *arg) {
test_seq_sleep(test_seq, 2);
DB_LOCK lock_a_m;
r = db_env->lock_get(db_env, locker_a, 0, &object_m, DB_LOCK_WRITE, &lock_a_m); assert(r == 0);
bool m_locked = false;
r = db_env->lock_get(db_env, locker_a, 0, &object_m, DB_LOCK_WRITE, &lock_a_m);
assert(r == 0 || r == DB_LOCK_DEADLOCK);
if (r == 0)
m_locked = true;
r = db_env->lock_put(db_env, &lock_a_l); assert(r == 0);
if (m_locked) {
r = db_env->lock_put(db_env, &lock_a_m); assert(r == 0);
} else {
(void) __sync_fetch_and_add(locker_args->deadlock_count, 1);
if (verbose) printf("%s:%u m deadlock\n", __FUNCTION__, __LINE__);
}
r = db_env->lock_id_free(db_env, locker_a); assert(r == 0);
......@@ -102,10 +111,21 @@ static void *run_locker_b(void *arg) {
test_seq_sleep(test_seq, 2);
DB_LOCK lock_b_l;
r = db_env->lock_get(db_env, locker_b, 0, &object_l, DB_LOCK_WRITE, &lock_b_l); assert(r == DB_LOCK_DEADLOCK);
bool l_locked = false;
r = db_env->lock_get(db_env, locker_b, 0, &object_l, DB_LOCK_WRITE, &lock_b_l);
assert(r == 0 || r == DB_LOCK_DEADLOCK);
if (r == 0)
l_locked = true;
r = db_env->lock_put(db_env, &lock_b_m); assert(r == 0);
if (l_locked) {
r = db_env->lock_put(db_env, &lock_b_l); assert(r == 0);
} else {
(void) __sync_fetch_and_add(locker_args->deadlock_count, 1);
if (verbose) printf("%s:%u l deadlock\n", __FUNCTION__, __LINE__);
}
r = db_env->lock_id_free(db_env, locker_b); assert(r == 0);
return arg;
......@@ -116,12 +136,14 @@ static void simple_deadlock(DB_ENV *db_env) {
struct test_seq test_seq; test_seq_init(&test_seq);
int deadlock_count = 0 ;
toku_pthread_t tid_a;
struct locker_args args_a = { db_env, &test_seq };
struct locker_args args_a = { db_env, &test_seq, &deadlock_count };
r = toku_pthread_create(&tid_a, NULL, run_locker_a, &args_a); assert(r == 0);
toku_pthread_t tid_b;
struct locker_args args_b = { db_env, &test_seq };
struct locker_args args_b = { db_env, &test_seq, &deadlock_count };
r = toku_pthread_create(&tid_b, NULL, run_locker_b, &args_b); assert(r == 0);
while (1) {
......@@ -138,6 +160,8 @@ static void simple_deadlock(DB_ENV *db_env) {
r = toku_pthread_join(tid_a, &ret); assert(r == 0);
r = toku_pthread_join(tid_b, &ret); assert(r == 0);
assert(deadlock_count == 1);
test_seq_destroy(&test_seq);
}
......
......@@ -4,10 +4,9 @@
//
// A write locks L
// B write locks M
// A tries to write lock M, gets blocked
// B tries to write lock L, gets DEADLOCK error
// B releases its lock on M
// A resumes
// A tries to write lock M && B tries to write lock L
// One of A or B should get the DEADLOCK error, the other waits
// A and B release their locks
#include "test.h"
#include "toku_pthread.h"
......@@ -51,6 +50,7 @@ static void test_seq_next_state(struct test_seq *seq) {
struct locker_args {
DB_ENV *db_env;
struct test_seq *test_seq;
int *deadlock_count;
};
static void *run_locker_a(void *arg) {
......@@ -72,11 +72,20 @@ static void *run_locker_a(void *arg) {
test_seq_sleep(test_seq, 2);
DB_LOCK lock_a_m;
r = db_env->lock_get(db_env, locker_a, 0, &object_m, DB_LOCK_WRITE, &lock_a_m); assert(r == 0);
bool m_locked = false;
r = db_env->lock_get(db_env, locker_a, 0, &object_m, DB_LOCK_WRITE, &lock_a_m);
assert(r == 0 || r == DB_LOCK_DEADLOCK);
if (r == 0)
m_locked = true;
r = db_env->lock_put(db_env, &lock_a_l); assert(r == 0);
if (m_locked) {
r = db_env->lock_put(db_env, &lock_a_m); assert(r == 0);
} else {
(void) __sync_fetch_and_add(locker_args->deadlock_count, 1);
if (verbose) printf("%s:%u m deadlock\n", __FUNCTION__, __LINE__);
}
r = db_env->lock_id_free(db_env, locker_a); assert(r == 0);
......@@ -102,10 +111,21 @@ static void *run_locker_b(void *arg) {
test_seq_sleep(test_seq, 2);
DB_LOCK lock_b_l;
r = db_env->lock_get(db_env, locker_b, 0, &object_l, DB_LOCK_WRITE, &lock_b_l); assert(r == DB_LOCK_DEADLOCK);
bool l_locked = false;
r = db_env->lock_get(db_env, locker_b, 0, &object_l, DB_LOCK_WRITE, &lock_b_l);
assert(r == 0 || r == DB_LOCK_DEADLOCK);
if (r == 0)
l_locked = true;
r = db_env->lock_put(db_env, &lock_b_m); assert(r == 0);
if (l_locked) {
r = db_env->lock_put(db_env, &lock_b_l); assert(r == 0);
} else {
(void) __sync_fetch_and_add(locker_args->deadlock_count, 1);
if (verbose) printf("%s:%u l deadlock\n", __FUNCTION__, __LINE__);
}
r = db_env->lock_id_free(db_env, locker_b); assert(r == 0);
return arg;
......@@ -113,21 +133,24 @@ static void *run_locker_b(void *arg) {
static void simple_deadlock(DB_ENV *db_env) {
int r;
int deadlock_count = 0;
struct test_seq test_seq; test_seq_init(&test_seq);
toku_pthread_t tid_a;
struct locker_args args_a = { db_env, &test_seq };
struct locker_args args_a = { db_env, &test_seq, &deadlock_count };
r = toku_pthread_create(&tid_a, NULL, run_locker_a, &args_a); assert(r == 0);
toku_pthread_t tid_b;
struct locker_args args_b = { db_env, &test_seq };
struct locker_args args_b = { db_env, &test_seq, &deadlock_count };
r = toku_pthread_create(&tid_b, NULL, run_locker_b, &args_b); assert(r == 0);
void *ret = NULL;
r = toku_pthread_join(tid_a, &ret); assert(r == 0);
r = toku_pthread_join(tid_b, &ret); assert(r == 0);
assert(deadlock_count == 1);
test_seq_destroy(&test_seq);
}
......
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