Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 6 Jul 2001 10:14:16 +1000 (EST)
From:      Darren Reed <darrenr@reed.wattle.id.au>
To:        bright@sneakerz.org (Alfred Perlstein)
Cc:        gibbs@scsiguy.com, jhb@FreeBSD.org, jake@FreeBSD.org, cvs-committers@FreeBSD.org, cvs-all@FreeBSD.org, dillon@earth.backplane.com, mjacob@feral.com, dfr@nlsystems.com
Subject:   Re: cvs commit: src/sys/sys systm.h condvar.h src/sys/kern kern_
Message-ID:  <200107060014.KAA16514@avalon.reed.wattle.id.au>
In-Reply-To: <20010705174135.A79818@sneakerz.org> from Alfred Perlstein at "Jul 5, 1 05:41:35 pm"

next in thread | previous in thread | raw e-mail | index | archive | help
> * Justin T. Gibbs <gibbs@scsiguy.com> [010705 17:28] wrote:
> > >It happens with SMP, too, not just preemption.  The calls are an optimization
> > >to avoid problems with releasing the lock after the wakeup.  The contention
> > >can be avoided if we release the lock before calling wakeup(), but doing that
> > >leaves a window open for another CPU to alter the data that the lock protects
> > >possibly invalidating the wakeup that then gets sent.
> > 
> > This window exists anyway.  The locked mutex it not passed to the woken
> > up thread, so there will always be a race between the woken up thread
> > acquiring the mutex and some other thread on some other CPU acquiring it
> > first and making the wakeup invalid.

I would have thought that this paragraph made the solution to the problem
obvious - pass a mutex someone along the way.

Or you use an interface like solaris has:

     #include <sys/ksynch.h>

     void cv_init(kcondvar_t *cvp, char *name,  kcv_type_t  type,
     void *arg);

     voidcv_destroy(kcondvar_t *cvp);

     void cv_wait(kcondvar_t *cvp, kmutex_t *mp);

     void cv_signal(kcondvar_t *cvp);

     void cv_broadcast(kcondvar_t *cvp);

     int cv_wait_sig(kcondvar_t *cvp, kmutex_t *mp);

     clock_t cv_timedwait(kcondvar_t *cvp, kmutex_t *mp,  clock_t
     timeout);

     clock_t  cv_timedwait_sig(kcondvar_t  *cvp,  kmutex_t   *mp,
     clock_t timeout);

The important thing to look for here is a mutex is passed to cv_*wait*().

Obviously the same one should be passed by all callers waiting on a
particular signal.

Darren

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe cvs-all" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200107060014.KAA16514>