Project

General

Profile

Bug #4696 » 0001-new-deadlock-check.patch

kosaki (Motohiro KOSAKI), 05/15/2011 04:23 PM

View differences:

thread.c
334 334
    rb_thread_lock_t lock;
335 335
    rb_thread_cond_t cond;
336 336
    struct rb_thread_struct volatile *th;
337
    volatile int cond_waiting, cond_notified;
337
    int cond_waiting;
338 338
    struct rb_mutex_struct *next_mutex;
339 339
} mutex_t;
340 340

  
......
3425 3425
lock_func(rb_thread_t *th, mutex_t *mutex, int timeout_ms)
3426 3426
{
3427 3427
    int interrupted = 0;
3428

  
3428
    int err = 0;
3429 3429
    native_mutex_lock(&mutex->lock);
3430 3430
    th->transition_for_lock = 0;
3431
    mutex->cond_waiting++;
3432

  
3431 3433
    for (;;) {
3432 3434
	if (!mutex->th) {
3433 3435
	    mutex->th = th;
3434 3436
	    break;
3435 3437
	}
3438
	if (RUBY_VM_INTERRUPTED(th)) {
3439
	    interrupted = 1;
3440
	    break;
3441
	}
3442
	if (err == ETIMEDOUT) {
3443
	    interrupted = 2;
3444
	    break;
3445
	}
3436 3446

  
3437
	mutex->cond_waiting++;
3438 3447
	if (timeout_ms) {
3439
	    int ret;
3440 3448
	    struct timespec timeout_rel;
3441 3449
	    struct timespec timeout;
3442 3450

  
3443 3451
	    timeout_rel.tv_sec = 0;
3444 3452
	    timeout_rel.tv_nsec = timeout_ms * 1000 * 1000;
3445 3453
	    timeout = native_cond_timeout(&mutex->cond, timeout_rel);
3446
	    ret = native_cond_timedwait(&mutex->cond, &mutex->lock, &timeout);
3447
	    if (ret == ETIMEDOUT) {
3448
		interrupted = 2;
3449
		mutex->cond_waiting--;
3450
		break;
3451
	    }
3454
	    err = native_cond_timedwait(&mutex->cond, &mutex->lock, &timeout);
3452 3455
	}
3453 3456
	else {
3454 3457
	    native_cond_wait(&mutex->cond, &mutex->lock);
3455
	}
3456
	mutex->cond_notified--;
3457

  
3458
	if (RUBY_VM_INTERRUPTED(th)) {
3459
	    interrupted = 1;
3460
	    break;
3458
	    err = 0;
3461 3459
	}
3462 3460
    }
3461
    mutex->cond_waiting--;
3463 3462
    th->transition_for_lock = 1;
3464 3463
    native_mutex_unlock(&mutex->lock);
3465 3464

  
......
3471 3470
{
3472 3471
    mutex_t *mutex = (mutex_t *)ptr;
3473 3472
    native_mutex_lock(&mutex->lock);
3474
    if (mutex->cond_waiting > 0) {
3473
    if (mutex->cond_waiting > 0)
3475 3474
	native_cond_broadcast(&mutex->cond);
3476
	mutex->cond_notified = mutex->cond_waiting;
3477
	mutex->cond_waiting = 0;
3478
    }
3479 3475
    native_mutex_unlock(&mutex->lock);
3480 3476
}
3481 3477

  
......
3562 3558
    }
3563 3559
    else {
3564 3560
	mutex->th = 0;
3565
	if (mutex->cond_waiting > 0) {
3566
	    /* waiting thread */
3561
	if (mutex->cond_waiting > 0)
3567 3562
	    native_cond_signal(&mutex->cond);
3568
	    mutex->cond_waiting--;
3569
	    mutex->cond_notified++;
3570
	}
3571 3563
    }
3572 3564

  
3573 3565
    native_mutex_unlock(&mutex->lock);
......
4710 4702
	GetMutexPtr(th->locking_mutex, mutex);
4711 4703

  
4712 4704
	native_mutex_lock(&mutex->lock);
4713
	if (mutex->th == th || (!mutex->th && mutex->cond_notified)) {
4705
	if (mutex->th == th || (!mutex->th && mutex->cond_waiting)) {
4714 4706
	    *found = 1;
4715 4707
	}
4716 4708
	native_mutex_unlock(&mutex->lock);
......
4719 4711
    return (*found) ? ST_STOP : ST_CONTINUE;
4720 4712
}
4721 4713

  
4722
#if 0 /* for debug */
4714
#ifdef DEBUG_DEADLOCK_CHECK
4723 4715
static int
4724 4716
debug_i(st_data_t key, st_data_t val, int *found)
4725 4717
{
......
4733 4725
	GetMutexPtr(th->locking_mutex, mutex);
4734 4726

  
4735 4727
	native_mutex_lock(&mutex->lock);
4736
	printf(" %p %d\n", mutex->th, mutex->cond_notified);
4728
	printf(" %p %d\n", mutex->th, mutex->cond_waiting);
4737 4729
	native_mutex_unlock(&mutex->lock);
4738 4730
    }
4739
    else puts("");
4731
    else
4732
	puts("");
4740 4733

  
4741 4734
    return ST_CONTINUE;
4742 4735
}
......
4756 4749
	VALUE argv[2];
4757 4750
	argv[0] = rb_eFatal;
4758 4751
	argv[1] = rb_str_new2("deadlock detected");
4759
#if 0 /* for debug */
4752
#ifdef DEBUG_DEADLOCK_CHECK
4760 4753
	printf("%d %d %p %p\n", vm->living_threads->num_entries, vm->sleeper, GET_THREAD(), vm->main_thread);
4761 4754
	st_foreach(vm->living_threads, debug_i, (st_data_t)0);
4762 4755
#endif
4763
-