nalin kanoongo
nalin kanoongo

Reputation: 33

set jump and long jump codeflow in c

I am trying to learn setjump and longjump in C. Can anyone help me with the output of the following code along with the code flow and the explanation for the the cases.i have called a function funcall() in the code. The alarm is being called for the first iteration but in the subsequent iterations the alarm is not being called. Why is it so? Does alarm(0) prevents any future alarm requests?

EDIT : Even after deleting the "print_T()" line in the signal handler the code doesnot seem to run.

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

#define LEN 50

jmp_buf po;

void print_T() {
    time_t rawtime;
    struct tm * timeinfo;

    time(&rawtime);
    timeinfo = localtime ( &rawtime );
    printf ( "Current local time and date: %s", asctime (timeinfo) );
}



static void ti() {
    print_T();
    longjmp(po,1);
}
int funcall(int reply) {


    static int p;
    p = 0;
    signal(SIGALRM, ti);
    int q = setjmp(po);
    if(q == 0)  
        printf("the value BEFORE setjmp %d for reply %d\n", p, reply);
    else 
        printf("the value AFTER setjmp %d for reply %d\n", p, reply);
    alarm(5);

    if(p > 0) {
        printf("INVOKING THE ALARM");
        alarm(0);
        return -1;
    }

    p++;    
    for(int i = 0; i < 100000; i++) 
        for(int j = 0; j < 100000; j++);
    return 0;

}

int main() {

    int a;
    int reply;
    time_t start, end;
    for(reply=0; ; reply++) {
        printf("~~~~~~~~~~~~~~~~~~~~~~~~~ITERATION NUMBER  %d\n", reply);

        time(&start);
        a = funcall(reply);
        time(&end);
        double tin = difftime(end, start);
        printf("*********************ITERATION END  and a returned is %d after %f\n", a, tin );
        double tidiff = difftime(end, start);
        if(a < 0)
            if(reply == 10) {
                break;
           }

    }

}

Upvotes: 2

Views: 2395

Answers (1)

yabhishek
yabhishek

Reputation: 419

Since I can't comment on any post other than mine as my reputations are less than 50, here is the output when your code is executed on mac os:

I don't see any problem with your code as alarm(5) is being called as many number of times as funcall() is called.

For each call to funcall(), first call to alarm(5) sets the SIGALRM signal to be delivered to the calling process (which is nothing but the function being executed/thread executing the function) after 5 seconds while the remaining part of the code executes.

Since in each call to funcall() static variable p is set to 0, if(p > 0){...} block will not be executed until p is greater than 0 which happens only if the next statement following the body of this block, p++ incrementing p and making it greater than zero, is executed.

Execution of the aforementioned if block and therefore call to alarm(0) depends on the time taken by the for loop following p++ to terminate. If execution of for loop finishes within 5 seconds, return 0 statement will return the control to the calling function. The return will cancel all the alarm requests and destroy the function call stack. So, in this case alarm(0) is not called.

Next, if execution of for loop takes > 5 seconds (ignoring all the scheduling delays that can happen and may result in unexpected behaviors at times), the pending alarm will be fired, resulting in invocation of signal handler ti(). When the signal handler ti() is invoked, the call to longjump() is made and execution starts again at the calling instruction of the setjump(). By the time control reaches at alarm(0)(assuming the for loop keeps executing for as long as preceding if block does not get executed for the second time), all the remaining alarm requests get cancelled by this call. So, alarm(0) cancels all the pending alarm requests after p>0 and for loop takes longer than 5 seconds.

Here is the execution recorded through asciinema https://asciinema.org/a/fyZX7CRoikq5kLJS2t0Og2rot

And here is a screen shot of the asciinema session after execution completes.

screen shot of output from asciinema session

Upvotes: 2

Related Questions