Date: Tue, 8 Apr 2014 18:38:19 +0200 From: =?iso-8859-2?Q?Edward_Tomasz_Napiera=B3a?= <trasz@FreeBSD.org> To: Konstantin Belousov <kostikbel@gmail.com> Cc: hackers@freebsd.org Subject: Re: Multiple locks and missing wakeup. Message-ID: <E9777F0E-DC5B-43B1-B741-AF1804FBE335@FreeBSD.org> In-Reply-To: <20140408085156.GR21331@kib.kiev.ua> References: <0D69A6A8-43D1-41FB-8C2D-00F5CAD9C86E@FreeBSD.org> <20140408085156.GR21331@kib.kiev.ua>
next in thread | previous in thread | raw e-mail | index | archive | help
Wiadomo=B6=E6 napisana przez Konstantin Belousov w dniu 8 kwi 2014, o = godz. 10:51: > On Tue, Apr 08, 2014 at 08:34:30AM +0200, Edward Tomasz Napiera?a = wrote: >> Let's say I have a kernel thread processing elements from a queue, >> sleeping until there is work to do; something like this: >>=20 >> mtx_lock(&mtx1); >> for (;;) { >> while (!LIST_EMPTY(&list1)) { >> elt =3D LIST_FIRST(&list1); >> do_stuff(elt); >> LIST_REMOVE(&list1, elt); >> } >> sleep(&list1, &mtx1); >> } >> mtx_unlock(&mtx1); >>=20 >> 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: >>=20 >> mtx_lock(&mtx1); >> for (;;) { >> while (!LIST_EMPTY(&list1)) { >> elt =3D LIST_FIRST(&list1); >> do_stuff(elt); >> LIST_REMOVE(&list1, elt); >> } > mtx_unlock(&mtx1);, right ? Yes. Well, there is no exit condition in that loop, but anyway. >> mtx_lock(&mtx2); >> while (!LIST_EMPTY(&list2)) { >> elt =3D LIST_FIRST(&list2); >> do_other_stuff(elt); >> LIST_REMOVE(&list2, elt); >> } >> mtx_unlock(&mtx2); >>=20 >> sleep(&list1, &mtx1); >> } >> mtx_unlock(&mtx1); >=20 > You should clarify your intent. Do you need to sleep waiting for the = work > items to appear for list2 ? What wakeup do you miss in the = pseudo-code > you posted ? Yes, I need to sleep waiting for a new element on either of the lists. = The missing wakeup is in the second list - it's possible that the element = will be added (under mtx2 lock) and the wakeup called after the = LIST_EMPTY(&list2) returns true, but before calling sleep(). > If you do need the notification for the list2, use &list1 as the = wakeup > channel for it. Sure, but it still doesn't fix the problem above.
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?E9777F0E-DC5B-43B1-B741-AF1804FBE335>