Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 16 Dec 2000 09:58:53 +0100 (CET)
From:      =?ISO-8859-1?Q?G=E9rard_Roudier?= <groudier@club-internet.fr>
To:        John Baldwin <jhb@FreeBSD.org>
Cc:        freebsd-alpha@FreeBSD.org, Bernd Walter <ticso@cicely5.cicely.de>
Subject:   RE: mb and wmb in atomic_
Message-ID:  <Pine.LNX.4.10.10012160938330.918-100000@linux.local>
In-Reply-To: <XFMail.001215142610.jhb@FreeBSD.org>

next in thread | previous in thread | raw e-mail | index | archive | help


On Fri, 15 Dec 2000, John Baldwin wrote:

>=20
> On 15-Dec-00 G=E9rard Roudier wrote:
> >=20
> >=20
> > On Fri, 15 Dec 2000, John Baldwin wrote:
> >=20
> >>=20
> >> On 15-Dec-00 Bernd Walter wrote:
> >> > Why are the mb and wmb operations needed in the atomic_ functions?
> >> > If I understood it correctly the locked operations are in synced
> >> > with others CPUs and there is no memory operation beside the variabl=
e
> >> > itself.
> >>=20
> >> They should probably only be used with the 'acq' and 'rel' variants.  =
Hmm,
> >> btw,
> >> it looks like I have the order of the barriers in the 'acq' and 'rel'
> >> variants
> >> wrong.  The barriers should be on the inside, not the outside.  Anyone
> >> disagree?
> >=20
> > The mb() inside the atomic_ operations are obviously seriously
> > miscommented:
> >=20
> > For example:
> >=20
> > static __inline void atomic_set_32(volatile u_int32_t *p, u_int32_t v)
> > {
> >       u_int32_t temp;
> >=20
> >       __asm __volatile (
> >               "1:\tldl_l %0, %2\n\t"          /* load old value */
> >               "bis %0, %3, %0\n\t"            /* calculate new value */
> >               "stl_c %0, %1\n\t"              /* attempt to store */
> >               "beq %0, 2f\n\t"                /* spin if failed */
> >               "mb\n\t"                        /* drain to memory */
> >               ".section .text3,\"ax\"\n"      /* improve branch predict=
ion */
> >               "2:\tbr 1b\n"                   /* try again */
> >               ".previous\n"
> >               : "=3D&r" (temp), "=3Dm" (*p)
> >               : "m" (*p), "r" (v)
> >               : "memory");
> > }
> >=20
> > There is obviously no relevance here in trying to drain something to
> > memory. Note that thinking about a mb() as something that drains to mem=
ory
> > is a serious mistake in my opinion. We want to order there, not to drai=
n
> > anything anywhere.
> >=20
> > However, the mb() above does have the effect of throwing away any read=
=20
> > that may have been prefetched by the CPU. If we need that here, we must
> > not remove the mb(), otherwise the mb() can be removed.
>=20
> What does NetBSD use for their atomic operations?

Duno.
=20
> Also, note that in FreeBSD,
> we have specific variants of atomic operations that include memory barrie=
rs
> (see the atomic(9) manpage in -current).  If the actual atomicity of the
> operation doesn't need the mb, they should be removed.

Atomicity seems here for both Alpha and i386.
=20
About Alpha, I doubt that using wmb() is a good idea, given that its does
not guarantee ordering of memory-like with respect to non memory-like and
this may lead to incorrect assumption from programmer when the both kinds=
=20
of memory are used (device drivers for example).

About i386 I donnot seem to see the promised read barrier for the
atomic_load_acq_X() primitives. Note that I also donnot see where such
primitive might be useful. :-)
Anyway, they seems wrong to me given that Pentia II and above may reorder
LOADs and LOADs against STOREs. We are only guaranteed STOREs to be
carried out to system BUS in processor order when cachable is involved,
and hitting non-cachable to insert implicit barriers.

  G=E9rard.



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




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?Pine.LNX.4.10.10012160938330.918-100000>