From owner-freebsd-hackers@FreeBSD.ORG Mon Dec 8 23:45:57 2008 Return-Path: Delivered-To: freebsd-hackers@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id E3AD5106567D for ; Mon, 8 Dec 2008 23:45:57 +0000 (UTC) (envelope-from marius@nuenneri.ch) Received: from rn-out-0910.google.com (rn-out-0910.google.com [64.233.170.185]) by mx1.freebsd.org (Postfix) with ESMTP id A39008FC1B for ; Mon, 8 Dec 2008 23:45:57 +0000 (UTC) (envelope-from marius@nuenneri.ch) Received: by rn-out-0910.google.com with SMTP id j71so1541783rne.12 for ; Mon, 08 Dec 2008 15:45:56 -0800 (PST) Received: by 10.90.28.12 with SMTP id b12mr1496671agb.115.1228779956189; Mon, 08 Dec 2008 15:45:56 -0800 (PST) Received: by 10.90.73.15 with HTTP; Mon, 8 Dec 2008 15:45:56 -0800 (PST) Message-ID: Date: Tue, 9 Dec 2008 00:45:56 +0100 From: "=?ISO-8859-1?Q?Marius_N=FCnnerich?=" To: "John Baldwin" In-Reply-To: <200812081517.39375.jhb@freebsd.org> MIME-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable Content-Disposition: inline References: <200812081517.39375.jhb@freebsd.org> Cc: freebsd-hackers@freebsd.org Subject: Re: Why safe using msleep with timeout=0 but not tsleep? X-BeenThere: freebsd-hackers@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Technical Discussions relating to FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 08 Dec 2008 23:45:58 -0000 On Mon, Dec 8, 2008 at 9:17 PM, John Baldwin wrote: > On Sunday 07 December 2008 02:00:30 pm Marius N=FCnnerich wrote: >> See subject. >> Interesting commit: >> http://svn.freebsd.org/viewvc/base?view=3Drevision&revision=3D77059 > > Lost wakeups. If you have code like so that doesn't use any locks: > > int flag; > > void > foo(void) > { > > flag =3D 1; > wakeup(&flag); > } > > void > bar(void) > { > > if (flag =3D=3D 0) > tsleep(&foo, ..., 0); > } > > Then one CPU may run the 'foo' routine to completion after another CPU ha= s > seen 'flag =3D=3D 0' but before it has put the thread to sleep in tsleep(= ). Even > on UP systems with preemption you can still get this race if you get > preempted by an interrupt (which runs foo()) in between the 'flag =3D=3D = 0' test > and calling tsleep(). Using an interlock avoid this: > > struct mtx lock; > int flag; > > void > foo(void) > { > > mtx_lock(&lock); > flag =3D 1; > mtx_unlock(&lock); > wakeup(&flag); > } > > void > bar(void) > { > > mtx_lock(&lock); > if (flag =3D=3D 0) > mtx_sleep(&foo, &lock, ..., 0); > mtx_unlock(&lock); > } > > In this case 'lock' closes the SMP/preemption races. > > -- > John Baldwin > Thank you for the explanation, John!