Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 12 Jan 2000 21:34:12 -0500
From:      "Mikhail Evstiounin" <evstiounin@adelphia.net>
To:        <keramida@ceid.upatras.gr>, "Laurence Berland" <stuyman@confusion.net>
Cc:        <freebsd-questions@FreeBSD.ORG>
Subject:   Re: Volatile variables (was: Giving a sighandler more information)
Message-ID:  <001601bf5d6e$b2ac8660$fc353018@evstiouninadelphia.net.pit.adelphia.net>

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

-----Original Message-----
From: Giorgos Keramidas <charon@hades.hell.gr>
To: Laurence Berland <stuyman@confusion.net>
Cc: freebsd-questions@FreeBSD.ORG <freebsd-questions@FreeBSD.ORG>
Date: Wednesday, January 12, 2000 9:23 AM
Subject: Volatile variables (was: Giving a sighandler more information)


>On Tue, Jan 11, 2000 at 06:54:47PM -0500, Laurence Berland wrote:
>>
>>
>> Oliver Fromme wrote:
>> >
>> > Laurence Berland <stuyman@confusion.net> wrote in
list.freebsd-questions:
>> >  > Oliver Fromme wrote:
>> >  >>
>> >  >> I'm afraid there is no other way than using global variables.
>> >  >> Be sure to declare them as ``volatile sig_atomic_t''.
>> >  >>
>> >  > What does this do as compared to declaring them normally?
>> >
>> > It makes them work, as opposed to not work.  :-)
>> >
>> > Seriously.  You _must_ declare global variables which are
>> > accessed from a signal handler as ``volatile sig_atomic_t''.
>> > Everything else is _not_ guaranteed to work (and if it works,
>> > then it's just pure luck).
>> >
>> > Regards
>> >    Oliver
>> >
>>
>> Does this have something to do with the signal being caught while
>> we're in the signal routine?  Am I on the right track?
>
>Almost.  AFAIK, when you use `volatile' each time the variable is
>referenced, the compiler will generate a memory reference, not relying
>on the value being saved in a register, etc.  The same if true for when
>the variable is `written', i.e. the memory copy is kept up to date.
>
>For the simple program:
>
> volatile int k;
>
> int main (void)
> {
> k = 0;
> k = 1;
> return 0;
> }
>
>the command `cc -S' will generate the following (slightly edited)
>assembler code.  The comments are there to help you understand which
>lines of the assembler code correspond to C code.
>
> .text
>         .p2align 2
> .globl main
>         .type    main,@function
> main:
>         pushl %ebp /* { */
>         movl %esp,%ebp
>
>         movl $0,k /* k = 0; */
>
>         movl k,%eax /* k = 1; */
>         incl %eax


Oliver, first of all, this is optimization already nad compiler tries to
keep value in register to have fast access to the value. I told that this is
optimization
you used I386 commands and I386 has increment in memory. If you want to turn
optimization completely it should look like this
            incl k
Remember, that k is global and located in a special segment. Take a look at
my quote
- in another e-mail - A volatile specifier is a hint to a compiler that an
object may change
its value in ways not specified by the language.

That's it, a compiler will try to keep everything in memory, no assumption
about registers.
And a timer is a good example when "foreign" force can change the value of
timer - not
a program. BTW, it's a good rool for global variables - do not optimize too
much - a
value could be change in procedure, allocated in another compilation unit
and compiler
has zero knolwledge about this "another" compilation unit. This is
especially true in
C++ world. A global variable could be changed even you do not have explicit
calls
of another functions - block try-catch creates a dynamic frame and all other
functions
called from inside try block are working inside this frame - any problem and
control
goes to the catch block and this block could change the variable.

Declaring vilotile in this particular case doesn't help a lot - you could
get a signal
between incl eax and movl %eax,k - and you are done - value in register
doesn't correspond to the value in memory. Moreover, if you change global
variable in
your signal handler, this value will be lost after movl %eax,k command. What
it's important is that these two operation should be atomic ones. In other
words,
incl k could not be interrupted, or you should provide uninterruptable
sequence of
command and, I believe, sig_atomic_t does it.


>         movl %eax,k
>
>         xorl %eax,%eax /* return 0; */
>
>         leave /* } */
>         ret
> .Lfe1:
>         .size    main,.Lfe1-main
>         .comm   k,4,4 /* volatile int k; */
>
>You can see that although %eax is used as an intermediate register for
>increasing the C variable called `k', the value of %eax is saved to the
>memory location of `k' before the end of the k = 1; statement.
>
>This is exactly what volatile means.  The memory value is always
>updated to reflect changes to the value of every volatile identifier.
>

Like I told above it should be done in atomic way, but vilotale means -
avoid
optimiozations. And again it's a hint - just a hint. Some aggresive
optimizers
could ignore it. For example, if commands cli/sti could be used by compiler
and works like it  work in 8086, optimizer could do the following:

 volatile int k;

 int main (void)
 {
    int m = 4;
     k = 0;
     k = 1;
    m = k;
     return 0;
 }

         pushl %ebp /* { */
         movl %esp,%ebp

          mov %edx,4    - compiler was able to figure out that it could
allocate variable in reg.
          cli
          xor    %eax,%eax
        movl %eax,k /* k = 0; */

         incl %eax  - k =1

        movl %eax,%edx  - m =k;
         movl %eax,k  - synchronize k

        sti

         xorl %eax,%eax /* return 0; */

         leave /* } */
         ret
 .Lfe1:
         .size    main,.Lfe1-main
         .comm   k,4,4 /* volatile int k; */



>--
>Giorgos Keramidas, < keramida @ ceid . upatras . gr >
>"What we have to learn to do, we learn by doing." [Aristotle]
>
>
>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?001601bf5d6e$b2ac8660$fc353018>