Date: Mon, 8 Dec 2008 15:17:39 -0500 From: John Baldwin <jhb@freebsd.org> To: freebsd-hackers@freebsd.org Cc: Marius =?iso-8859-1?q?N=FCnnerich?= <marius@nuenneri.ch> Subject: Re: Why safe using msleep with timeout=0 but not tsleep? Message-ID: <200812081517.39375.jhb@freebsd.org> In-Reply-To: <b649e5e0812071100v2bf7b377n63e85b3f2b123c24@mail.gmail.com> References: <b649e5e0812071100v2bf7b377n63e85b3f2b123c24@mail.gmail.com>
next in thread | previous in thread | raw e-mail | index | archive | help
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 has= =20 seen 'flag =3D=3D 0' but before it has put the thread to sleep in tsleep().= Even=20 on UP systems with preemption you can still get this race if you get=20 preempted by an interrupt (which runs foo()) in between the 'flag =3D=3D 0'= test=20 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. =2D-=20 John Baldwin
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200812081517.39375.jhb>