summaryrefslogtreecommitdiff
path: root/mysys/waiting_threads.c
diff options
context:
space:
mode:
authorSergei Golubchik <serg@mysql.com>2008-08-06 21:30:05 +0200
committerSergei Golubchik <serg@mysql.com>2008-08-06 21:30:05 +0200
commit3971e262e99366fa4bc9b454e69cf48daac9be85 (patch)
treeb56353bb1faa6894eddf63228e16dcb2b0621f39 /mysys/waiting_threads.c
parent7ca3fc4ff0ab53835da9f57af7f630f4c65868b7 (diff)
downloadmariadb-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.c36
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);
}