Multiple locks and missing wakeup.
Edward Tomasz Napierała
trasz at FreeBSD.org
Tue Apr 8 06:34:36 UTC 2014
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);
More information about the freebsd-hackers
mailing list