From owner-freebsd-questions Wed Jan 12 18:32:41 2000 Delivered-To: freebsd-questions@freebsd.org Received: from alpha.pit.adelphia.net (alpha.pit.adelphia.net [24.48.44.2]) by hub.freebsd.org (Postfix) with ESMTP id 5268314E29 for ; Wed, 12 Jan 2000 18:32:30 -0800 (PST) (envelope-from evstiounin@adelphia.net) Received: from evstiouninadelphia ([24.48.53.252]) by alpha.pit.adelphia.net (8.9.2/8.9.2) with SMTP id VAA18079; Wed, 12 Jan 2000 21:31:46 -0500 (EST) Message-ID: <001601bf5d6e$b2ac8660$fc353018@evstiouninadelphia.net.pit.adelphia.net> From: "Mikhail Evstiounin" To: , "Laurence Berland" Cc: Subject: Re: Volatile variables (was: Giving a sighandler more information) Date: Wed, 12 Jan 2000 21:34:12 -0500 MIME-Version: 1.0 Content-Type: text/plain; charset="koi8-r" Content-Transfer-Encoding: 7bit X-Priority: 3 X-MSMail-Priority: Normal X-Mailer: Microsoft Outlook Express 4.72.3110.1 X-MimeOLE: Produced By Microsoft MimeOLE V4.72.3110.3 Sender: owner-freebsd-questions@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.ORG -----Original Message----- From: Giorgos Keramidas To: Laurence Berland Cc: 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 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