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##################### |
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.
|
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. |