Date: Tue, 9 Dec 2008 00:45:56 +0100 From: "=?ISO-8859-1?Q?Marius_N=FCnnerich?=" <marius@nuenneri.ch> To: "John Baldwin" <jhb@freebsd.org> Cc: freebsd-hackers@freebsd.org Subject: Re: Why safe using msleep with timeout=0 but not tsleep? Message-ID: <b649e5e0812081545s21b17534ya822e2de0acc9c0a@mail.gmail.com> In-Reply-To: <200812081517.39375.jhb@freebsd.org> References: <b649e5e0812071100v2bf7b377n63e85b3f2b123c24@mail.gmail.com> <200812081517.39375.jhb@freebsd.org>
next in thread | previous in thread | raw e-mail | index | archive | help
On Mon, Dec 8, 2008 at 9:17 PM, John Baldwin <jhb@freebsd.org> 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!
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?b649e5e0812081545s21b17534ya822e2de0acc9c0a>