views:

1906

answers:

4

Hi,

for a paper I'm looking for an real-life C function which uses volatile variables. That in itself is not hard to find, but I am looking for a function in which the value of the volatile variable must change during the course of the execution of the function, for a particular branch of the function to be reached. Something like this:

typedef struct {
    unsigned       :6;
    unsigned FLAG1 :1;
    unsigned FLAG2 :1;
} __attribute__ ((packed)) REGISTER;

volatile REGISTER * io_ = 0x1234;

int write_to_io()
{
    while (io_->FLAG1) {};
    //io_->FLAG1 is now 0

    io_->FLAG2 = 1;

    sleep(10);

    if (io->FLAG1)  
        return 1;  //io->FLAG1 has changed from 0 to 1
    else
        return 0;  //io->FLAG1 has not changed
 }

It would be sufficient if different bits of the structure changed during the execution of the function, but my main criterion is that for a certain branch to be reached, the value of a volatile variable changes during the execution of the function.

I'd be very grateful for any real-life examples. I haven't been able to find many examples using volatile on the web.

+3  A: 

Pick your favorite open source operating system, and look for old device drivers, you'll find some who have no other way of working.

mat
+1  A: 

Some example of my teacher, which worked without volatile with one compiler (lcc), but breaked when i run it with my gcc port for that processor. I had to put volatile in.

static int volatile busTimeoutSeen;

int busTimeoutISR(int irq) {
  busTimeoutSeen = 1;
  return 1;  /* skip offending instruction */
}


int memsize(void) {
  unsigned char volatile *ptr;
  unsigned char b;
  ISR oldService;

  busTimeoutSeen = 0;
  oldService = getISR(16);
  setISR(16, busTimeoutISR);
  ptr = (unsigned char *) 0xC0000000;
  while (1) {
    b = *ptr;
    if (busTimeoutSeen) {
      break;
    }
    ptr += (1 << 12);
  }
  setISR(16, oldService);
  return (ptr - (unsigned char *) 0xC0000000) >> 12;
}

It reads continuously from all pages, until we get past the last page, which causes an interrupt, which will set busTimeoutSeen to 1. As that happens behind the scenes, we tell the compiler to read and write the data always to memory.

Johannes Schaub - litb
Many thanks litb, this example will do nicely. In the function memsize, the busTimeoutSeen has to change from 0 to non-zero __during the execution of the function__, for the function to complete.
Ham
+6  A: 

The canonical (and portable) example is handling an asynchronous signal. (You can probably deliver SIGINT to your program with Ctrl-C).

#include <signal.h>
#include <stdio.h>

volatile sig_atomic_t quit;

void signal_handler(int sig)
{
    signal(sig, signal_handler);
    quit = 1;
}

int main(void)
{
    signal(SIGINT, signal_handler);
    puts("Hit return to poll quit flag");
    while (!quit) getchar();
    return 0;
}
fizzer
A: 

Memory mapped IO is an example where a value in memory may actually represent reading from a device such as a COM port. When I learned C, this was one of the examples given for the use of the volatile keyword.

Daniel Paull