View | Details | Raw Unified | Return to bug 198014 | Differences between
and this patch

Collapse All | Expand All

(-)b/sys/kern/kern_umtx.c (-2 / +29 lines)
Lines 1445-1450 umtx_pi_setowner(struct umtx_pi *pi, struct thread *owner) Link Here
1445
	TAILQ_INSERT_TAIL(&uq_owner->uq_pi_contested, pi, pi_link);
1445
	TAILQ_INSERT_TAIL(&uq_owner->uq_pi_contested, pi, pi_link);
1446
}
1446
}
1447
1447
1448
1449
/*
1450
 * Disown a PI mutex, and remove it from the owned list.
1451
 */
1452
static void
1453
umtx_pi_disown(struct umtx_pi *pi)
1454
{
1455
1456
	mtx_assert(&umtx_lock, MA_OWNED);
1457
	TAILQ_REMOVE(&pi->pi_owner->td_umtxq->uq_pi_contested, pi, pi_link);
1458
	pi->pi_owner = NULL;
1459
}
1460
1448
/*
1461
/*
1449
 * Claim ownership of a PI mutex.
1462
 * Claim ownership of a PI mutex.
1450
 */
1463
 */
Lines 1861-1868 do_unlock_pi(struct thread *td, struct umutex *m, uint32_t flags) Link Here
1861
			return (EPERM);
1874
			return (EPERM);
1862
		}
1875
		}
1863
		uq_me = curthread->td_umtxq;
1876
		uq_me = curthread->td_umtxq;
1864
		pi->pi_owner = NULL;
1877
		umtx_pi_disown(pi);
1865
		TAILQ_REMOVE(&uq_me->uq_pi_contested, pi, pi_link);
1866
		/* get highest priority thread which is still sleeping. */
1878
		/* get highest priority thread which is still sleeping. */
1867
		uq_first = TAILQ_FIRST(&pi->pi_blocked);
1879
		uq_first = TAILQ_FIRST(&pi->pi_blocked);
1868
		while (uq_first != NULL && 
1880
		while (uq_first != NULL && 
Lines 1883-1888 do_unlock_pi(struct thread *td, struct umutex *m, uint32_t flags) Link Here
1883
		mtx_unlock_spin(&umtx_lock);
1895
		mtx_unlock_spin(&umtx_lock);
1884
		if (uq_first)
1896
		if (uq_first)
1885
			umtxq_signal_thread(uq_first);
1897
			umtxq_signal_thread(uq_first);
1898
	} else {
1899
		pi = umtx_pi_lookup(&key);
1900
		if (pi != NULL) {
1901
			/*
1902
			 * This can happen if a signal or timeout removed the
1903
			 * last waiter from the umtxq, but there is still
1904
			 * a thread in do_lock_pi() holding the umtx_pi.
1905
			 * This thread might not own the umtx_pi in this case,
1906
			 * but if it does, it must disown it.
1907
			 */
1908
			mtx_lock_spin(&umtx_lock);
1909
			if (pi->pi_owner == td)
1910
				umtx_pi_disown(pi);
1911
			mtx_unlock_spin(&umtx_lock);
1912
		}
1886
	}
1913
	}
1887
	umtxq_unlock(&key);
1914
	umtxq_unlock(&key);
1888
1915

Return to bug 198014