Programmer's Heaven - For C C++ Pascal Delphi Visual Basic Assembler C# .Net java JSP ASP ASP.NET Javascript developers!

Members
Username:

Password:

Auto-login

Register
Why register?
Forgot Password?
Blogs new Blog section
Jobs
Webtools
Message Boards
FAQ
CodePedia
Free Magazines
User search
What's New
Top lists
RSS Feeds RSS Feed

Submit content
Contact Us
Link To Us
Help



Advanced Search
Newsletter
E-mail:


More information
Current area: HOME -> Use of volatile

Use of volatile

The compilation system tries to reduce code size and execution time on all machines, by optimizing code. It is programmer responsibility to inform compilation system that certain code (or variable) should not be optimized. Many programmers do not understand when to use volatile to inform compilation system that certain code should not be optimized or what it does. Although (no doubt) their program work, they do not exploit the full power of the language.

A variable should be declared volatile whenever its value can be changed by something beyond the control of the program in which it appears, such as a concurrently executing thread. Volatile, can appear only once in a declaration with any type specifier; however, they cannot appear after the first comma in a multiple item declaration. For example, the following declarations are legal

/* Let T denotes some data type */
typedef volatile T i; 
volatile T i;
T volatile   i ; 
And the following declaration is illegal
T i, volatile vi ;
Volatile qualifiers can be used to change the behavior of a type. For example,
volatile int p = 3;
declares and initializes an object with type volatile int whose value will be always read from memory.

Syntax

Keyword volatile can be placed before or after the data type in the variable definition. For example following declaration are identical:
Volatile T a =3;
T volatile a=3; 
The declaration declares and initializes an objet with type volatile T whose value will be always read from memory

Pointer declaration

Volatile T * ptr; 
T volatile * ptr; 
Ptr is a a pointer to a volatile T:
volatile pointer to a volatile variable  
int volatile * volatile ptr; 
volatile can be applied to derived types such as an array type ,in that case, the element is qualified, not the array type. When applied to struct types entire contents of the struct become volatile. You can apply the volatile qualifier to the individual members of the struct. Type qualifiers are relevant only when accessing identifiers as l-values in expressions. volatile does not affects the range of values or arithmetic properties of the object.. To declare the item pointed to by the pointer as volatile, use a declaration of the form:
volatile T *vptr;


To declare the value of the pointer - that is, the actual address stored in the pointer - as volatile, use a declaration of the form:
T* volatile ptrv;

Use of volatile

- An object that is a memory-mapped I/O port
- An object variable that is shared between multiple concurrent processes
- An object that is modified by an interrupt service routine
- An automatic object declared in a function that calls setjmp and whose value is-changed between the call to setjmp and a corresponding call to longjmp

# An object that is a memory-mapped I/O port

an 8 bit , memory -mapped I/O port at physical address 0X15 can be declared as
char const ptr=(char*)0X15 ;
*ptr access the port consider following code fragment to set the third bit of the output port at periodic intervals
*ptr = 0;
while(*ptr){
     *ptr = 4 ;
     *ptr = 0 ;
}
the above code may be optimize as
*ptr = 0
while(0) {
}
*ptr is assigned 0 before value 4 is used ( and value of *ptr never changes ( same constant is always assigned to it)
volatile keyword is used to suppress these optimization the compiler assumes that the value can change any time , even if no explicit code modify it to suppress all optimization declare ptr as
 volatile char * const ptr = (volatile char*)0x16
this declaration say the object at which ptr points can change without notice , but that ptr itself is a constant whose value never change

# An object that is shared between multiple concurrent processes

if two threads/tasks concurrently assign distinct values to the same shared non-volatile variable, a subsequent use of that variable may obtain a value that is not equal to either of the assigned values, but some implementation-dependent mixture of the two values. so a global variable references by multiple thread programmers must declare shared variable as volatile.
#include
#include
volatile int num ;
void* foo()
{
while(1) {
      ++num ;
      sleep(1000);
      }
}

main()
{
 int p ;
 void *targ =NULL ;
 thread_t id ;
 num = 0;
 p = thr_create((void*)NULL , 0,foo,targ,0,&id);
 if(!p)  printf(" can not create thread ");

 while(1) 
 {
   printf("%d" , num ) ;
 }
}
the compiler may use a register to store the num variable in the main thread , so the change to the value by the second thread are ignored . The volatile modifier is a away of telling the compiler that no optimization applied to the variable its value be not placed in register and value may change outside influence during evaluation

# An automatic object declared in a function that calls setjmp and whose value is-changed between the call to setjmp and a corresponding call to longjmp

Variables local to functions that call setjmp is most often used. When an automatic object is declared in a function that calls setjmp, the compilation system knows that it has to produce code that exactly matches what the programmer wrote. Therefore, the most recent value for such an automatic object will always be in memory (not just in a register) and as such will be guaranteed to be up-to-date when longjmp is called. Without volatile variable is undefined by the standard whether the result one see differs with or without optimization simply reflects that fact Consider following code
#include
static jmp_buf  buf ;
main( )
{
        volatile  int b;
        b =3 ;
        if(setjmp(buf)!=0)  {
        printf("%d ", b) ;  
        exit(0);
        }
        b=5;
       longjmp(buf , 1) ;
 }
volatile variable isn't affected by the optimization. So value of b is after the longjump is the last value variable assigned. Without volatile b may or may not be restored to its last value when the longjmp occurs. For clear understanding assembly listing of above program by cc compiler has been given below.
/*Listing1: Assembly code fragment of above program
   Produced by cc compiler  when volatile is used*/



.file	"vol.c"
main:
	pushl	%ebp
	movl	%esp, %ebp
	subl	$20, %esp
	movl	$3, -4(%ebp)
	pushl	$buf
	call	_setjmp
	addl	$16, %esp
	testl	%eax, %eax
	je	.L18
	subl	$8, %esp
	movl	-4(%ebp), %eax
	pushl	%eax
	pushl	$.LC0
	call	printf
	movl	$0, (%esp)
	call	exit
	.p2align 2
.L18:
	movl	$5, -4(%ebp)
	subl	$8, %esp
	pushl	$1
	pushl	$buf
	call	longjmp

 /*Listing 2:Assemply code fragment of  above program
   produced by cc compile witout volatile keword */

.file	"wvol.c"
main:
	pushl	%ebp
	movl	%esp, %ebp
	subl	$20, %esp
	pushl	$buf
	call	_setjmp
	addl	$16, %esp
	testl	%eax, %eax
	je	.L18
	subl	$8, %esp
	pushl	$3
	pushl	$.LC0
	call	printf
	movl	$0, (%esp)
	call	exit
	.p2align 2
.L18:
	subl	$8, %esp
	pushl	$1
	pushl	$buf
	call	longjmp

/listing 3: difference between listing 1 and listing 3 ***/

< .file	"vol.c"
---
> .file	"wvol.c"
< 	movl	$3, -4(%ebp) 
< 	movl	-4(%ebp), %eax
< 	pushl	%eax
> 	pushl	$3
< 	movl	$5, -4(%ebp) / * store in stack */

From above listing 3 it is clear that when you use setjmp and longjmp, the only automatic variables guaranteed to remain valid are those declared volatile.

# An object modified by an interrupt service routine

Interrupt service routines often set variables that are tested in main line code. One problem that arises as soon as you use interrupt is that interrupt routines need to communicate with rest of the code .A interrupt may update a variable num that is used in main line of code .An incorrect implementation of this might be:
static lon int  num ;
void interrupt update(void)
{
++num ;
}
main()
{
long  val ;
val  = num ;
while(val !=num)
val = num ;
rturn val ;
}
When compilation system execute while statement, the optimizer in compiler may notice that it read the value num once already and that value is still in the register. Instead of re reading the value from memory, compiler may produce code to use the (possibly messed up) value in the register defeating purpose of original C program. Some compiler may optimize entire while loop assuming that since the value of num was just assigned to val , the two must be equal and condition in while statement will therefore always be false .To avoid this ,you have to declare num to be volatile that warns compilers that certain variables may change because of interrupt routines.
static volatile  long int num ;
With volatile keyword in the declaration the compiler knows that the value of num must b read from memory every time it is referenced.

Conclusion

When using exact semantics is necessary, volatile should be used. If you are given a piece of touchy code given as above. It is a good idea in any case to look the compiler outputting listing at the assembly language to be sure that compiler produce code that makes sense.

About the author

Ashok K. Pathak a member ( Research Staff ) at Bharat Electronics Limited (CRL) , Ghaziabad .He has been developing embedded application for the past five years. Ashok holds a M.E in computer science and engineering . Ashok recently completed a book about' "Advanced Test in C and Embedded System Programming" , Published by BPB , ND .He can be reached at pathak@indiya.com.


  User Comments
Anonymous

From AZ
(Report as abusive)
Good explanation of 'volatile'
This explanation was well written, and had useful examples and counter-examples.
Vishal Sisodia

From India(Gurgaon)
(Report as abusive)
Totally new and awesome piece of code
I found the code really interesting and usefull In the article i found knowledgeable stuff and I salutes for the author knowledge.

gaurav

(Report as abusive)
Better
It is worth to read once.
anirudh

From bangalore
(Report as abusive)
good
well explained with appropriate example
vishnu

From new delhi
(Report as abusive)
between good and better
it is as precise as possible in explanation and example
  View all   Rate and comment this article

Advertisement

  Free Magazine  
Free Magazines
Enterprise Open Source Journal Enterprise Open Source Journal is the first magazine designed solely to focus on open source strategies in the enterprise.
subscribe now


 

Sponsored Links 
Build IT Knowledge with Current & Trusted Content
Helps Employees Develop & Hone New Technical Programming Skills. Sign Up & Get Full Access.
Check Out IT Certification Preparation Materials
Sign Up With SkillSoft & Get Access to Training Materials for Over 50 Professional Certifications.
Six Sigma Certification
100% Online-Six Sigma Certificate from Villanova - Find Out More Now.
Virtual File System SDK
Create your own file systems in Windows and .NET applications
PureCM Software Configuration Management
Version control and integrated issue tracking - powerful and easy to use. Get your FREE trial now!
Buy a link now

Newsletter Submit Content About Advertising Awards Contact Us Link to us    
© 1996-2008 Community Networks Ltd All rights reserved. Reproduction in whole or in part, in any form or medium without express written permission is prohibited. Violators of this policy may be subject to legal action. Please read Terms Of Use and Privacy Statement for more information. Development by .NET konsult - Synchron Data.