From owner-freebsd-hackers@FreeBSD.ORG Sat Apr 12 11:49:05 2014 Return-Path: Delivered-To: freebsd-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 74FB474E; Sat, 12 Apr 2014 11:49:05 +0000 (UTC) Received: from mail-ee0-x235.google.com (mail-ee0-x235.google.com [IPv6:2a00:1450:4013:c00::235]) (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 B40AC1CEF; Sat, 12 Apr 2014 11:49:04 +0000 (UTC) Received: by mail-ee0-f53.google.com with SMTP id b57so4908255eek.40 for ; Sat, 12 Apr 2014 04:49:03 -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=N3JqdEjND7Lpk27VD8hWbhznsqNt5dvPqpP2PR6VA8w=; b=UW6EwKK7HpM1j3ZglD8kwC+aVQ+sV4IC4u6W1zsjiPZN8/iXTOjG0nqF3NfotOaquL K/0fZLYvmqSDybhO8M2j3oFNe2ugwrCbMsl+/F/u/NXAyZ7pgfUR1RNeCken38c3Bu34 JXvFCnVRh52vBz/6a/SJFqT8kuwTqxfoRsPVjqApL07WENwLqDZTh8dZNko19GC133d0 QzjpHfZaHnePGWTwU0yXYsJjMS1JXr2lMKfnBNl9kkoSLH8As3PXYfUaGsGaee/olKSf RQ8d0tku2l7EzE6kGwz9jcrNwMe0Kw7jPnDQmjcjXxyBCtL5gh4oSOvVhEhQmsbkH/oV 9VrQ== X-Received: by 10.15.54.137 with SMTP id t9mr36638326eew.39.1397303343092; Sat, 12 Apr 2014 04:49:03 -0700 (PDT) Received: from strashydlo.home (aebc231.neoplus.adsl.tpnet.pl. [79.186.28.231]) by mx.google.com with ESMTPSA id m44sm24829529eep.14.2014.04.12.04.49.01 for (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Sat, 12 Apr 2014 04:49:02 -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: <201404081412.10066.jhb@freebsd.org> Date: Sat, 12 Apr 2014 13:48:59 +0200 Content-Transfer-Encoding: quoted-printable Message-Id: <418DC7A6-443C-4494-AFDB-1358F63564DE@freebsd.org> References: <0D69A6A8-43D1-41FB-8C2D-00F5CAD9C86E@FreeBSD.org> <201404081001.31219.jhb@freebsd.org> <201404081412.10066.jhb@freebsd.org> To: John Baldwin X-Mailer: Apple Mail (2.1283) Cc: freebsd-hackers@freebsd.org, 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: Sat, 12 Apr 2014 11:49:05 -0000 Wiadomo=B6=E6 napisana przez John Baldwin w dniu 8 kwi 2014, o godz. = 20:12: > On Tuesday, April 08, 2014 12:45:49 pm Edward Tomasz Napiera=B3a = wrote: >> Wiadomo=B6=E6 napisana przez John Baldwin w dniu 8 kwi 2014, o godz. = 16:01: >>=20 >>> On Tuesday, April 08, 2014 2:34:30 am Edward Tomasz Napiera=B3a = 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 >>> All our sleep primitives in the kernel only accept a single wait = channel. >>> It sounds like you want something more like select() or poll() where = you >>> can specify multiple wait channels. There isn't a good way to do = that >>> currently. You could write one, but it would be a bit hard to do >>> correctly. >>=20 >> Perhaps I should have been more clear: I'm ok with a single wait >> channel. The problem is that there is no way to pass more than one >> mutex to the sleep() function, so we can miss wakeup for the list >> protected by the second lock, if something gets enqueued between >> releasing mtx2 and calling sleep(). >>=20 >>> In practice you'd end up implementing something that boiled >>> down to having a single wait channel with a common lock that = protected >>> it so you could do something like: >>=20 >> The whole purpose of this is to avoid locking mtx1 in the the enqueue >> routine for the second list, for contention reasons. >=20 > Ah, but note that I didn't lock mtx1 in the enqueue routine, I marked > the 'combo_mtx' which is only used for the sleep/wakeup. Ah, now I get it. Nifty!