Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 15 Jan 2000 22:27:40 -0500
From:      "Mikhail Evstiounin" <evstiounin@adelphia.net>
To:        <freebsd-questions@FreeBSD.ORG>
Subject:   Re: Volatile variables
Message-ID:  <004501bf5fd1$a52481e0$f8353018@evstiouninadelphia.net.pit.adelphia.net>

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

-----Original Message-----
From: Oliver Fromme <olli@dorifer.heim3.tu-clausthal.de>
To: freebsd-questions@FreeBSD.ORG <freebsd-questions@FreeBSD.ORG>
Date: Saturday, January 15, 2000 2:50 PM
Subject: Re: Volatile variables


>Mikhail Evstiounin <evstiounin@adelphia.net> wrote in
list.freebsd-questions:
> > From: Oliver Fromme <olli@dorifer.heim3.tu-clausthal.de>
> >>You _do_ need "volatile" in that case.  It is necessary for
> >>all variables whose contents can change asynchronously, i.e.
> >>outside of the normal program flow.  For example, this is true
> >>for variables which are mapped to hardware registers, and for
> >>variables which are located in a shared memory reagion (which
> >>is shared with other processes), and for variables which are
> >
> > that is - in ways not specified by the language.
> >
> >>accessed from within signal handlers.
> >
> > This is, in my mind, slightly different.
>
>No, it's _exactly_ the same, as far as the compiler is
>concerned.  The meaning of "volatile" is to prevent the
>compiler's optimizer stage from assuming that the content
>of a variable cannot change _asynchronously_ between
>C statements.  The important word is ``asynchronously''.
>It means changes to variables outside of the control flow
>which is known to the compiler at compile-time.  This
>includes signal handlers just as well as hardware registers,
>shared memory etc.


Wrong, wrong and wrong. Hardware generates interrupts,
changes statues and value in hardware registers totaly async
and this process is out of your control. Hardware register
can change its value even during totally masked status of CPU.
Sighandler is a function written by a programmer, and sharing
resources between two asyn processes is totally diferent.
This is SYNCHRONIZATION problem. THERE IS NO DIFFERENCE
to get access from two async processes and your process and
sighandler. Moreover, your process will be stopped as soon as
sighandler gets its control. This process is totally under your control
and could and should use process sync mechanism such as
semphores, monitors or critical intervals, etc to solve this problem.
Take a look at the following example:

int allocated = 0;
char *mem = NULL;


void Sigusr1Handler( int siganl )
{
    if ( allocateded )
    {
        sleep( 60 );    // just for fun
        mem[ 2 ] = 'F';
        ...

    }
}

void Sigusr2Handler( int siganl )
{
    if ( allocated )
    {
        free( mem );
        mem = NULL;
        opened = 0;
    }
}

int main( int argc, char* argv[] )
{
    mem = ( char* )malloc( 20 );
    opend = 1;
    ...

    return 0;
}


I added sleep( 60 ) just to show, that even if you declare both of mem and
opened as a vilotile  there is a period of time (if you remove sleep,
then you can reduce it, but you cannot eliminate it at all) when
your sighandler is vulnerable to a typical error in a typical situation.
And vilotale doesn't help a bit!!!
Again, I let myself to cite BS book (p. 808) - "an object can change its
value
in ways not specified by the language". In my mind, this is very careful
and strict statement.


>
>I think the explanation which Giorgos gave is pretty good.

>
> > Could you explain me how it helps in your example? I pointed, that
> > you can get signal between two assembler commands and it
> > does destroys all your assumptions.
>
>The assembler commands do not matter.  Only C statements
>matter, because this is the smallest separable execution
>unit of a C program.


Wrong wrong and wrong again - what about expressions and
function calls? Example

extern const vilotile clock;

int main( int argc, char* argv[] )
{
    int snap_shot;
    ...

    if ( 18000 < clock && clock < 18002 )
    {
        snap_shot = clock * clock;
    }

    return 0;
}

In this example, you have to declare clock as a vilotile. It means no
copies,
I agree here with you. But 'if' statement is ill-formed and multiplication
is ill formed also - because vilotaile means that two sequential accesses
to the same variable can give you different results. In other words,
there is no warranty that you will enter inside 'if', because first time you
get
access to the clock it will retturn 18001, but for the seconf 19003. The
same is
true about multiplication. There is a good probability, that you will not
have a square of the clock. For compiler that means, that instead of
(for multiplication)

    mov    clock,%eax
    mult    %eax,%eax
    mov    %eax,snap_shot

It sgould generate

    mov    clock,%eax
    mult    %eax,clock
    mov    %eax,snap_shot

and you can do nothing about it. And all this is true for one C/C++
statement.
This is difference between bin vilotile and async access to a global
resource.

>
>Without "volatile", the programmer would be unable to write
>his program in such a way that asynchronous changes work


Yes, (s)he would. Consider, please, traditional methods for async
communications and process synchronizations. There is an excellent
book by C.A.R. Hoare - Communicating Sequential Processes
(Prentice-Hall) - very mathematical and strict book. You can go
to one of the first works by E. Dijkstra in the book named
Programming Languges, NATO Advanced Study Institute, 1968,
Academic Press, London and New York. You can take a look
at much more later articles and books (I personally, like Tony Hoar
book) - "An introduction to Operating Systems" by Harvey Deitel,
"The design of operating systems for small computer systems"
by Stphen H. Kaisler, "Operating Systems" by Show, "Practical
UNIX Programming. A guide to Concurrency, Communication
and Multithreading" by Kay A. Robbins and Steven Robbins,
"Thread Primer. A guide to multithreaded programming" by
Bil Lewis and Daniel J. Berg.

Any ofthis book or article will show you how to live without
vilotile in async process environment.


One more thing about smallest separable execution of the
language - almost none of language gearantees that statement
could not be interrupted by signal, message or schedular.
And this is another reason for vilotile existense - no synonyms
inside an expression.

>with register optimizations.  This is why "volatile" exists,
>and this is why a compiler _must_ obey it.
>

That's why vilotile exists and why a a compiler _must obey
it in way to provide integrity, but not synch access to a variable.

>All of the above is (formally) specified in the standard,
>I'd suggest that you read it carefully.


I did it for 12 years of my life while I was writing compilers and
operating systems. Now I am pretty far away from this and
trying to follow all standard in my spare time and for my own
pleasure.

>
>Regards
>   Oliver
>
>--
>Oliver Fromme, Leibnizstr. 18/61, 38678 Clausthal, Germany
>(Info: finger userinfo:olli@dorifer.heim3.tu-clausthal.de)
>
>"In jedem Stück Kohle wartet ein Diamant auf seine Geburt"
>                                         (Terry Pratchett)
>
>
>To Unsubscribe: send mail to majordomo@FreeBSD.org
>with "unsubscribe freebsd-questions" in the body of the message



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




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?004501bf5fd1$a52481e0$f8353018>