From owner-freebsd-hackers@FreeBSD.ORG Tue Apr 8 16:38:24 2014 Return-Path: Delivered-To: hackers@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) (using TLSv1 with cipher ADH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id 6309CA2D for ; Tue, 8 Apr 2014 16:38:24 +0000 (UTC) Received: from mail-ee0-x230.google.com (mail-ee0-x230.google.com [IPv6:2a00:1450:4013:c00::230]) (using TLSv1 with cipher ECDHE-RSA-RC4-SHA (128/128 bits)) (Client CN "smtp.gmail.com", Issuer "Google Internet Authority G2" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id EB1101608 for ; Tue, 8 Apr 2014 16:38:23 +0000 (UTC) Received: by mail-ee0-f48.google.com with SMTP id b57so887284eek.7 for ; Tue, 08 Apr 2014 09:38:22 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=sender:subject:mime-version:content-type:from:in-reply-to:date:cc :content-transfer-encoding:message-id:references:to; bh=Ey011hqycGAA0W3hxCrdJVvRGZhN1FjZ93TjlEN3xqU=; b=YSsqtEmrDPZSBf/fXo/sfB8kpVaiFLbzFEFpebsURoTumBsHgeA0QUmoUrwX12tkV4 +UobM/tV83l51VKd+eijifXdV7Gim8tO9XHVnO6AFlceYflD0ybxwO2eUI9Ii0V7vU5b uND9xWmMt5OUZjvw7nD0rD3nkholKU1w3jI18O+/N6Z80Imf95nLPyNKXoLLsKlMZAG1 htRBHyyidqhNzzUpDgStNy4m6zNkokKdMD2c6esxOn2RscR/UcudyAYM+6A4Gn8eTkSE GPc+vPy6ZuDQ+3S2l78lP6y1fLtNbkJcO+yaNCqC/JVKPSJS9ZnmS+RejhR1v/h3yrV/ n5EQ== X-Received: by 10.14.6.195 with SMTP id 43mr1820061een.101.1396975102274; Tue, 08 Apr 2014 09:38:22 -0700 (PDT) Received: from strashydlo.home (adbf56.neoplus.adsl.tpnet.pl. [79.184.5.56]) by mx.google.com with ESMTPSA id u1sm5588792eex.31.2014.04.08.09.38.21 for (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Tue, 08 Apr 2014 09:38:21 -0700 (PDT) Sender: =?UTF-8?Q?Edward_Tomasz_Napiera=C5=82a?= Subject: Re: Multiple locks and missing wakeup. Mime-Version: 1.0 (Apple Message framework v1283) Content-Type: text/plain; charset=iso-8859-2 From: =?iso-8859-2?Q?Edward_Tomasz_Napiera=B3a?= In-Reply-To: <20140408085156.GR21331@kib.kiev.ua> Date: Tue, 8 Apr 2014 18:38:19 +0200 Content-Transfer-Encoding: quoted-printable Message-Id: References: <0D69A6A8-43D1-41FB-8C2D-00F5CAD9C86E@FreeBSD.org> <20140408085156.GR21331@kib.kiev.ua> To: Konstantin Belousov X-Mailer: Apple Mail (2.1283) Cc: hackers@freebsd.org X-BeenThere: freebsd-hackers@freebsd.org X-Mailman-Version: 2.1.17 Precedence: list List-Id: Technical Discussions relating to FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 08 Apr 2014 16:38:24 -0000 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.