Subject: Re: bus_space and barriers
To: (Chris G. Demetriou) <>
From: Witold J. Wnuk <>
List: tech-kern
Date: 10/21/2000 00:12:31
On 20-Oct-00, 21:20:57 Chris G. Demetriou wrote:
>  "Witold J. Wnuk" <> writes:
> > And, I am more convinced now, bus_space_read should do read from
> > the bus
> > POV, bus_space_write should do write from the bus POV. C guarantes
> > that
> > functions are executed in order. We should mimic that behaviour.
> > 
> > This is what bus_space is for, right?
>  _no_.  bus_space does _not_ exist to provide C semantics for bus
>  access.
>  It exists to provide machine-independent access to bus space, with
>  whatever semantics are defined by it.  C semantics are pretty much
>  irrelevant, except inasmuch as C mandates that if you manipulate
>  data
>  after reading it, you'll actually have read it.

I understand it in different way. bus_space is to help _programmers_,
not compilers nor processors. It is matter of providing programmers
with interface that:

a) is easy to understand
b) is easy to use
c) helps to manage code

It solves above by providing abstraction with regard to actual accesses
on the bus. Current semantics introduce much overhead to simplify
programmers life. If it was computer who writes the code, he could avoid
this overhead by (for example) writing separate drivers for each bus.

So if we are going to provide interface to the bus - that abstracts
actual operations on the bus, that is intuitive (and programmers really
do expect that functions execute in order - in this case operations on
the bus are executed in order) that is in my opinion good idea.

Of course it is more philosophical problem, not technical - problem of
names - and I can live with any names for this functions.

> > It is possible to save "mb" between writes:
> > 
> > something like:
> > 
> > extern int readsp;
> > 
> > #define write() do {                            \
> >                 if (readsp) asm("mb");          \
> >                 else asm("wmb");                \
> >                 readsp = 0;                     \
> >                 asm("write");                   \
> >         } while (0)
> > 
> > 
> > #define read() do {                             \
> >                 asm("mb");                      \
> >                 asm("read");                    \
> >                 readsp = 1;                     \
> >         } while (0)
>  except, in truly generic macros like this, you cannot reasonably use
>  'extern int' unless you know that the macros will be used without
>  any
>  possibility of taking an interrupt or exception.  you really should
>  be
>  using volatile int, and in that case, because if you do not you
>  _might_ lose.  (actually, even if you do, you might lose, since
>  there's no atomicity of access.)

I have analyzed few cases already.

Interrupts are asynchronous anyway. They can happen between read() and
write(), they can happen in read() or write(). But I can not see
them break anything. Function that is interrupted will still have its
reads and writes ordered. Interrupt may mess with device state but
it is independent of this optimization. I see volatile version more
questionable. Interrupt may clear readsp that is used in function
causing function to have its reads not ordered. But clearing of readsp
happens only after issuing mb - so it does not matter. Interrupt may set
readsp between "mb" and "readsp = 0" - but interrupt accesses don't have
to be ordered with function accesses.

Am I missing anything here?


        Witold J. Wnuk