LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (https://www.linuxquestions.org/questions/programming-9/)
-   -   ITIMER_REAL fires, but ITIMER_VIRTUAL does not fire (https://www.linuxquestions.org/questions/programming-9/itimer_real-fires-but-itimer_virtual-does-not-fire-618550/)

the_shani 02-04-2008 06:10 AM

ITIMER_REAL fires, but ITIMER_VIRTUAL does not fire
 
Hi All,

I am trying to implement a user level thread library using sigsetjmp and siglompjmp. Thread scheduling happens whenever a timer expires. I have written a sample program to test context switching when a timer expires. Below the code for the sample.

This is how the code is supposed to work:
The signal handler for SIGVTALRM, virtual timer (ITIMER_VIRTUAL) and stacks for the user level threads)(A and B) are setup. Then A starts executing. The virtual timer then goes off and B starts executing. At each timer interrupt execution switches between A and B.

The problem:
The sample works if I am using ITIMER_REAL, by works I mean the timer raises an interrupt periodically but when I am using ITIMER_VIRTUAL no interrupts are raised. Can anyone tell me why this is happening and how to fix it?

The below is working, but if I comment the 2 lines marked with "//$$$$$$" (to use SIGALRM and ITIMER_REAL) and uncomment the two lines marked with "//&&&&&&" (to use SIGVTALRM and ITIMER_VIRTUAL) the code stops working.

Thanks for your time and replies.

Note: The below code is for 32-bit machines, on 64-bit machines replace JB_SP with JB_RSP

##############start of code####################

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

int flag = 0;
sigjmp_buf buf[2];

char stack[2][2048];

void handleVtAlarm (int sigNo)
{
if(0 != sigsetjmp(buf[flag], 1))
{
return;
}
else
{
flag = (flag + 1) % 2;
siglongjmp(buf[flag], 1);
}

}

void A()
{
while(1)
{
puts("A");
sleep(1);
}
}

void B()
{
while(1)
{
puts("B");
sleep(1);
}
}

void createThreads()
{
sigsetjmp(buf[0], 1);
buf[0][0].__jmpbuf[JB_PC] = (unsigned long)A;
buf[0][0].__jmpbuf[JB_SP] = (unsigned long)(&stack[0][0] + 2048);

sigsetjmp(buf[1], 1);
buf[1][0].__jmpbuf[JB_PC] = (unsigned long)B;
buf[1][0].__jmpbuf[JB_SP] = (unsigned long)(&stack[1][0] + 2048);
}


int main()
{
struct itimerval sTimerVal;
struct sigaction sSigAction;

sSigAction.sa_handler = &handleVtAlarm;
sigemptyset(&sSigAction.sa_mask);

if (0 != sigaction(SIGALRM, &sSigAction, NULL)) //$$$$$$
//if (0 != sigaction(SIGVTALRM, &sSigAction, NULL)) //&&&&&&&
{
printf("failed to set signal handler\n");
}

createThreads();

sTimerVal.it_interval.tv_sec = 2;
sTimerVal.it_interval.tv_usec = 0;
sTimerVal.it_value.tv_sec = 2;
sTimerVal.it_value.tv_usec = 0;

if (0 != setitimer(ITIMER_REAL, &sTimerVal, NULL)) //$$$$$$
//if (0 != setitimer(ITIMER_VIRTUAL, &sTimerVal, NULL)) //&&&&&&
{
printf("failed...\n");
}
else
{
printf("alarm set\n");
}

siglongjmp(buf[0], 1);
}



###############end of code#####################

Matir 02-04-2008 07:33 AM

Perhaps you're just not letting it run long enough? Unless the process is ACTIVELY doing work, the virtual timer is not decrementing -- so if it's just idle waiting on the signal, you will NEVER get that signal.

nachiket 02-05-2008 01:57 AM

Hey ... I am also trying to do similar kind of thing and getting the same problem :(
I have tried using the least possible time value for the alarm to set, but still this is not working.


All times are GMT -5. The time now is 04:58 PM.