diff options
author | Sergei Golubchik <serg@mysql.com> | 2008-08-06 21:30:05 +0200 |
---|---|---|
committer | Sergei Golubchik <serg@mysql.com> | 2008-08-06 21:30:05 +0200 |
commit | 3971e262e99366fa4bc9b454e69cf48daac9be85 (patch) | |
tree | b56353bb1faa6894eddf63228e16dcb2b0621f39 /mysys/waiting_threads.c | |
parent | 7ca3fc4ff0ab53835da9f57af7f630f4c65868b7 (diff) | |
download | mariadb-git-3971e262e99366fa4bc9b454e69cf48daac9be85.tar.gz |
maria: deadlock detection when waiting on unique key (useless until we can rollback)
include/my_pthread.h:
cleanup
include/waiting_threads.h:
header guard
mysys/waiting_threads.c:
bug - kill strategy were not applied to deadlocks of length 1.
cast timeout to ulonglong.
storage/maria/ma_static.c:
declare WT_RESOURCE_TYPE ma_rc_dup_unique
storage/maria/ma_write.c:
deadlock detection when waiting on unique key (useless until we can rollback)
storage/maria/maria_def.h:
deadlock detection when waiting on unique key (useless until we can rollback)
storage/maria/trnman.c:
use deadlock detector.
protect state transitions of a TRN with a mutex.
trnman_trid_to_trn() function.
storage/maria/trnman.h:
trnman_trid_to_trn() function
protect state transitions of a TRN with a mutex
use deadlock detector.
storage/maria/trnman_public.h:
trnman_trid_to_trn()
Diffstat (limited to 'mysys/waiting_threads.c')
-rw-r--r-- | mysys/waiting_threads.c | 36 |
1 files changed, 22 insertions, 14 deletions
diff --git a/mysys/waiting_threads.c b/mysys/waiting_threads.c index 1c87886f405..491e7c3a726 100644 --- a/mysys/waiting_threads.c +++ b/mysys/waiting_threads.c @@ -227,6 +227,20 @@ struct deadlock_arg { WT_RESOURCE *rc; }; +static void change_victim(WT_THD* found, struct deadlock_arg *arg) +{ + if (found->weight < arg->victim->weight) + { + if (arg->victim != arg->thd) + { + rc_unlock(arg->victim->waiting_for); /* release the previous victim */ + DBUG_ASSERT(arg->rc == found->waiting_for); + } + arg->victim= found; + arg->rc= 0; + } +} + /* loop detection in a wait-for graph with a limited search depth. */ @@ -294,16 +308,8 @@ retry: break; case WT_DEADLOCK: ret= WT_DEADLOCK; - if (cursor->weight < arg->victim->weight) - { - if (arg->victim != arg->thd) - { - rc_unlock(arg->victim->waiting_for); /* release the previous victim */ - DBUG_ASSERT(arg->rc == cursor->waiting_for); - } - arg->victim= cursor; - } - else if (arg->rc) + change_victim(cursor, arg); + if (arg->rc) rc_unlock(arg->rc); goto end; case WT_OK: @@ -329,13 +335,15 @@ static int deadlock(WT_THD *thd, WT_THD *blocker, uint depth, int ret; DBUG_ENTER("deadlock"); ret= deadlock_search(&arg, blocker, depth); - if (arg.rc) - rc_unlock(arg.rc); if (ret == WT_DEPTH_EXCEEDED) { increment_cycle_stats(WT_CYCLE_STATS, max_depth); ret= WT_OK; } + if (ret == WT_DEADLOCK && depth) + change_victim(blocker, &arg); + if (arg.rc) + rc_unlock(arg.rc); if (ret == WT_DEADLOCK && arg.victim != thd) { DBUG_PRINT("wt", ("killing %s", arg.victim->name)); @@ -570,7 +578,7 @@ int wt_thd_cond_timedwait(WT_THD *thd, pthread_mutex_t *mutex) ret= WT_OK; rc_unlock(rc); - set_timespec_time_nsec(timeout, starttime, wt_timeout_short*1000); + set_timespec_time_nsec(timeout, starttime, wt_timeout_short*ULL(1000)); if (ret == WT_TIMEOUT) ret= pthread_cond_timedwait(&rc->cond, mutex, &timeout); if (ret == WT_TIMEOUT) @@ -579,7 +587,7 @@ int wt_thd_cond_timedwait(WT_THD *thd, pthread_mutex_t *mutex) ret= WT_DEADLOCK; else if (wt_timeout_long > wt_timeout_short) { - set_timespec_time_nsec(timeout, starttime, wt_timeout_long*1000); + set_timespec_time_nsec(timeout, starttime, wt_timeout_long*ULL(1000)); if (!thd->killed) ret= pthread_cond_timedwait(&rc->cond, mutex, &timeout); } |