0

W Richard Stevens, Stephen A Rago Advanced Programming in the Unix Environment, 3rd Edn 2013 (APUE) Chapter 10, section 10 "The alarm and pause functions", includes this example:

#include "apue.h"

unsigned int    sleep2(unsigned int);
static void     sig_int(int);

int
main(void)
{
    unsigned int    unslept;

    if (signal(SIGINT, sig_int) == SIG_ERR)
        err_sys("signal(SIGINT) error");
    unslept = sleep2(5);
    printf("sleep2 returned: %u\n", unslept);
    exit(0);
}

static void
sig_int(int signo)
{
    int             i, j;
    volatile int    k;

    /*
     * Tune these loops to run for more than 5 seconds
     * on whatever system this test program is run.
     */
    printf("\nsig_int starting\n");
    for (i = 0; i < 300000; i++)
        for (j = 0; j < 4000; j++)
            k += i * j;
    printf("sig_int finished\n");
}

sleep2 uses setjmp and longjmp; if the SIGALRM interrupts some other signal handler, then when we call longjmp, we abort the other signal handler.

What I do not understand is the following paragraph:  

“The integer k is declared as volatile to prevent an optimizing compiler from discarding the loop.”

I wrote the test program here:

#include <time.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int main()
{
    clock_t begin = clock();
    int i, j;
    //volatile int  k;
    int k;
    /*
     * Tune these loops to run for more than 5 seconds
     * on whatever system this test program is run.
     */

    for (i = 0; i < 300000; i++)
        for (j = 0; j < 4000; j++)
            k += i * j;

    clock_t end = clock();
    double time_spent = (double)(end - begin) / CLOCKS_PER_SEC;
    printf("time spent %f\n",time_spent);
    return 0;
}

I test the program with or without volatile — there seems to be no change.

[root c++]#gcc volatile.c
[root c++]#./a.out
time spent 3.168064
[root c++]#gcc -O0 volatile.c
[root c++]#./a.out
time spent 3.162101
[root c++]#vi volatile.c
[root c++]#
[root c++]#
[root c++]#gcc volatile.c
[root c++]#./a.out
time spent 3.177379
[root c++]#gcc -O0 volatile.c
[root c++]#
[root c++]#./a.out
time spent 3.184255

How to understand the meaning of that paragraph in the book and implement it in the program?   As @PiRocks said, I got the compile options wrong

[root c++]#gcc -O3 volatile.c
[root c++]#
[root c++]#./a.out
time spent 2.766854
[root c++]#./a.out
time spent 2.772181
[root c++]#
[root c++]#
[root c++]#vi volatile.c
[root c++]#
[root c++]#gcc -O3 volatile.c
[root c++]#
[root c++]#./a.out
time spent 0.000002
[root c++]#./a.out
time spent 0.000003

without volatile with -O3, it just runs in 0.0000x second.

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
J.Doe
  • 319
  • 1
  • 8

0 Answers0