Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 8 Apr 2014 08:34:30 +0200
From:      =?iso-8859-2?Q?Edward_Tomasz_Napiera=B3a?= <trasz@FreeBSD.org>
To:        hackers@freebsd.org
Subject:   Multiple locks and missing wakeup.
Message-ID:  <0D69A6A8-43D1-41FB-8C2D-00F5CAD9C86E@FreeBSD.org>

next in thread | raw e-mail | index | archive | help
Let's say I have a kernel thread processing elements from a queue,
sleeping until there is work to do; something like this:

mtx_lock(&mtx1);
for (;;) {
	while (!LIST_EMPTY(&list1)) {
		elt = LIST_FIRST(&list1);
		do_stuff(elt);
		LIST_REMOVE(&list1, elt);
	}
	sleep(&list1, &mtx1);
}
mtx_unlock(&mtx1);

Now, is there some way to make it work with two lists, protected
by different mutexes?  The mutex part is crucial here; the whole
point of this is to reduce lock contention on one of the lists.  The
following code would result in a missing wakeup:

mtx_lock(&mtx1);
for (;;) {
	while (!LIST_EMPTY(&list1)) {
		elt = LIST_FIRST(&list1);
		do_stuff(elt);
		LIST_REMOVE(&list1, elt);
	}

	mtx_lock(&mtx2);
	while (!LIST_EMPTY(&list2)) {
		elt = LIST_FIRST(&list2);
		do_other_stuff(elt);
		LIST_REMOVE(&list2, elt);
	}
	mtx_unlock(&mtx2);

	sleep(&list1, &mtx1);
}
mtx_unlock(&mtx1);




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?0D69A6A8-43D1-41FB-8C2D-00F5CAD9C86E>