There is one function called test(), I want to call this function in every 30 seconds, Please find my implemented code snippet.
void init_sigaction(void) {
struct sigaction act;
act.sa_handler = test; //test()
act.sa_flags = 0;
sigemptyset(&act.sa_mask);
sigaction(SIGPROF, &act, NULL);
}
void init_time(void) {
struct itimerval val;
val.it_value.tv_sec = 30; //Timer 30 Seconds
val.it_value.tv_usec = 0;
val.it_interval = val.it_value;
setitimer(ITIMER_PROF, &val, NULL);
}
int main()
{
/*Set the handler for the signal SIG to HANDLER */
signal(SIGINT, signal_handler);
init_sigaction();
init_time();
Some_other_function();
}
Now I am using some other function, and I want to pause sigaction timer until other function's execution. how can I implemented interrupt for pause?
Thanks,
From the manual page of setitimer:
A timer which is set to zero (it_value is zero or the timer expires and it_interval is zero) stops.
Call setitimer with zero times, and with a valid old_value argument to store the current values of the timer, so you can start it again later.
Edit:
How about something like this:
struct itimerval old_timer;
void pause_timer()
{
struct itimerval zero_timer = { 0 };
setitimer(ITIMER_PROF, &zero_time, &old_timer);
}
void resume_timer()
{
setitimer(ITIMER_PROF, &old_timer, NULL);
}
Note The code above is untested, and coded only by reading the manual page.
You could consider blocking some signals with e.g. the sigprocmask(2) system call.
However, I strongly recommend reading several times the signal(7) man page. Don't forget that a signal handler can happen any time (including at the worst possible time, e.g. during calls to fprintf or malloc...), so can only call directly or indirectly async-signal-safe functions; and a big lot of library functions are not in this small restricted set. A usual way is to set a volatile sig_atomic_t flag in the signal handler, and test for it outside.
Related
I have a requirement to set more than one interval-timers (alarms of same type : ITIMER_REAL) in the same process. so I used setitimer() system call to create 3 alarms with each timer having separate structures to hold time interval values. when any timer expires it will give a signal SIGALRM to the calling process, but i couldn't find which timer among three has given the signal and I don't even know whether all the timers are running or not. Is there any way to find which timer has given the signal...
Thank you.
#include <signal.h>
#include <stdio.h>
#include <string.h>
#include <sys/time.h>
void timer_handler (int signum)
{
static int count = 0;
printf ("timer1 expired %d times\n", ++count);
}
int main ()
{
int m = 0;
struct sigaction sa;
struct itimerval timer1, timer2, timer3;
memset (&sa, 0, sizeof (sa));
sa.sa_handler = &timer_handler;
sigaction (SIGALRM/*SIGVTALRM*/, &sa, NULL);
timer1.it_value.tv_sec = 1;
timer1.it_value.tv_usec = 0;
timer1.it_interval.tv_sec = 5;
timer1.it_interval.tv_usec = 0;
timer2.it_value.tv_sec = 2;
timer2.it_value.tv_usec = 0/* 900000*/;
timer2.it_interval.tv_sec = 5;
timer2.it_interval.tv_usec = 0/*900000*/;
timer3.it_value.tv_sec = 3;
timer3.it_value.tv_usec = 0/* 900000*/;
timer3.it_interval.tv_sec = 5;
timer3.it_interval.tv_usec = 0/*900000*/;
setitimer (ITIMER_REAL/*ITIMER_VIRTUAL*/, &timer1, NULL);
setitimer (ITIMER_REAL/*ITIMER_VIRTUAL*/, &timer2, NULL);
setitimer (ITIMER_REAL/*ITIMER_VIRTUAL*/, &timer3, NULL);
while (1)
{
//printf("\nin main %d",m++);
//sleep(1);
}
}
No, you only have one ITIMER_REAL timer per process. Using setitimer multiple times overwrites the previous value, see man setitimer
A process has only one of each of the three types of timers.
You can also see this, when you modify the intervals in your example code
timer1.it_interval.tv_sec = 1;
timer2.it_interval.tv_sec = 2;
and using nanosleep instead of sleep, because it might interfere with SIGALRM.
Now running the code, you will see only 5 second intervals.
You can also retrieve the previous set value by providing a second struct itimerval
struct itimerval old1, old2, old3;
setitimer(ITIMER_REAL, &timer1, &old1);
setitimer(ITIMER_REAL, &timer2, &old2);
setitimer(ITIMER_REAL, &timer3, &old3);
old1 will contain zero values, because it is the first time you use setitimer. old2 contains it_interval = 1 sec, and old3 contains it_interval = 2 sec. The it_values will be different, depending on how much time elapsed between the calls to setitimer.
So, if you need multiple timers, you need to do some bookkeeping. Each time a timer expires, you must calculate which timer is next and call setitimer accordingly.
As an alternative, you may look into POSIX timers. This allows to create multiple timers
A program may create multiple interval timers using timer_create().
and also pass some id to the handler via sigevent. Although the example at the end of the man page looks a bit more involved.
If I understand your question right you want to know the status of the different timers.
In the reference a getitimer function avalable:
The function getitimer() fills the structure pointed to by curr_value
with the current setting for the timer specified by which (one of
ITIMER_REAL, ITIMER_VIRTUAL, or ITIMER_PROF). The element it_value is
set to the amount of time remaining on the timer, or zero if the timer
is disabled. Similarly, it_interval is set to the reset value.
You can find the full reference here Link
Hope that helps
I am building a pre-emptive userspace thread scheduler which uses a timer to interrupt threads and switch between them according to priority. However, once a thread is interrupted, I cannot seem to let it finish; only start it again. Is what I am asking for even possible using swapcontext? The result of this code, which should allow itake5seconds() to complete, just loops the "Hello" message over and over.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>
#include <sys/time.h>
#include <ucontext.h>
static ucontext_t mainc, newthread;
void itake5seconds()
{
puts("Hello. I take 5 seconds to run.");
sleep(5);
puts("And I'm done! Wasn't that nice?");
}
void timer_handler(int signum)
{
puts("Doing some scheduler stuff.");
swapcontext(&mainc, &newthread);
}
int main(int argc, char* argv[])
{
struct sigaction sa;
memset(&sa, 0, sizeof(sa));
sa.sa_handler = &timer_handler;
sigaction(SIGALRM, &sa, NULL);
getcontext(&newthread);
newthread.uc_stack.ss_sp = malloc(5000);
newthread.uc_stack.ss_size = 5000;
newthread.uc_link = &mainc;
makecontext(&newthread, &itake5seconds, 0);
struct itimerval timer;
timer.it_value.tv_sec = 0;
timer.it_value.tv_usec = 500000;
timer.it_interval.tv_sec = 0;
timer.it_interval.tv_usec = 500000;
setitimer(ITIMER_REAL, &timer, NULL);
while(1);
return 0;
}
Your code is calling an "unsafe" function in the signal handler (swapcontext). Therefor, the behavior of your program is "undefined".
From man 7 signal:
A signal handler function must be very careful, since processing elsewhere may be interrupted at some arbitrary point in the execution of the program. POSIX has the concept of "safe function". If a signal interrupts the execution of an unsafe function, and handler calls an unsafe function, then the behavior of the program is undefined.
See the "Example for SVID Context Handling" section in Complete Context Control for an example of how you can work this with a signal handler. But basically you'd use a volatile int global variable to flag that your signal handler was called and instead do the swapcontext call from normal code (i.e. code that's not running from within the context of signal handling).
The problem was that I was not saving the current execution context that swapcontext() returns to its first parameter.
We are trying to switch between multiple functions in our C program after saving the state using setjmp and longjmp but for only one function we are able to save the context not for other two functions. What could be the possible solution to it. Please suggest if necessary changes are required in the code.
In the o/p the state of fun1() is saved successfully in env1 and we are able to resume it back, but in case of fun2() and fun3() the state is not saved in the env2, env3.
Sample o/p:
i=0,j=999
i=1,j=998
i=2,j=997
i=3,j=996
ch=a
ch=b
ch=c
ch=d
a=0
a=-1
a=-2
a=-3
i=4,j=995/*The previous value of i is preserved*/
i=5,j=996
i=6,j=994
i=7,j=993
ch=<garbagevalue> /*The previous value of ch is lost*/
ch=<garbagevalue>
ch=<garbagevalue>
ch=<garbagevalue>
a=<garbagevalue> /*The previous value of ch is lost*/
a=<garbagevalue>
a=<garbagevalue>
a=<garbagevalue>
i=8,j=992
and so on..
Code follows:
#include <signal.h>
#include <stdio.h>
#include <string.h>
#include <sys/time.h>
#include<setjmp.h>
#define INTERVAL 5000
void fun1();
void fun2();
void fun3();
void timer_handler(int );
struct itimerval it_val;
jmp_buf env1,env2,env3;
int count=0;
void timer_handler (int signum)
{
if(count==0){
count++;
fun1();
}
if(count==1){
count++;
fun2();
}
if(count==2){
count++;
fun3();
}
L1:
if(count==3){
count++;
siglongjmp(env1,7);
}
if(count==4){
count++;
siglongjmp(env2,7);
}
if(count==5){
count++;
siglongjmp(env3,7);
}
count=3;
goto L1;
}
void fun1()
{
struct sigaction sa;
int i=0,j=999;
/* Install timer_handler as the signal handler for SIGVTALRM. */
memset (&sa, 0, sizeof (sa));
sa.sa_flags=SA_NODEFER;
sa.sa_handler = &timer_handler;
/* Configure the timer to expire after 250 msec... */
it_val.it_value.tv_sec = INTERVAL/1000;
it_val.it_value.tv_usec = (INTERVAL*1000) % 1000000;
it_val.it_interval.tv_sec = INTERVAL/1000;;
it_val.it_interval.tv_usec=(INTERVAL*1000) % 1000000;
sigaction (SIGALRM, &sa, NULL);
setitimer (ITIMER_REAL, &it_val, NULL);
while (1) {
while(sigsetjmp(env1,3)==0){
sleep(1);
printf("i=%d,j=%d\n",i,j);
i++;
j--;
}
}
}
void fun2()
{
struct sigaction sa;
char ch='a';
/* Install timer_handler as the signal handler for SIGVTALRM. */
memset (&sa, 0, sizeof (sa));
sa.sa_handler = &timer_handler;
sa.sa_flags=SA_NODEFER;
sigaction (SIGALRM, &sa, NULL);
/* Configure the timer to expire after 250 msec... */
it_val.it_value.tv_sec = INTERVAL/1000;
it_val.it_value.tv_usec = (INTERVAL*1000) % 1000000;
/* ... and every 250 msec after that. */
it_val.it_interval.tv_sec = INTERVAL/1000;;
it_val.it_interval.tv_usec=(INTERVAL*1000) % 1000000;
/* Start a virtual timer. It counts down whenever this process is*/
setitimer (ITIMER_REAL, &it_val, NULL);
/* Do busy work. */
while (1) {
while(sigsetjmp(env2,2)==0) {
sleep(1);
printf("ch=%c\n",ch);
if(ch=='z')
ch='a';
ch++;
}
}
}
void fun3()
{
struct sigaction sa;
int a=0;
/* Install timer_handler as the signal handler for SIGVTALRM. */
memset (&sa, 0, sizeof (sa));
sa.sa_handler = &timer_handler;
sa.sa_flags=SA_NODEFER;
sigaction (SIGALRM, &sa, NULL);
/* Configure the timer to expire after 250 msec... */
it_val.it_value.tv_sec = INTERVAL/1000;
it_val.it_value.tv_usec = (INTERVAL*1000) % 1000000;
/* ... and every 250 msec after that. */
it_val.it_interval.tv_sec = INTERVAL/1000;;
it_val.it_interval.tv_usec=(INTERVAL*1000) % 1000000;
/* Start a virtual timer. It counts down whenever this process is*/
setitimer (ITIMER_REAL, &it_val, NULL);
/* Do busy work. */
while (1){
while(sigsetjmp(env3,1)==0){
sleep(1);
printf("a=%d\n",a);
a--;
}
}
}
int main ()
{
timer_handler(1);
return 0;
}
You seem to be trying to implement some kind of threading without managing your stacks. This will not work. Ignoring the fact that pretty much everything in your code is undefined behavior, let's see what's actually going on.
You first call timer_handler(). This calls fun1. This sets a real time timer that will call timer_handler(). Then fun1 calls setjmp and sleeps. At this point your stack looks something like this:
timer_handler, fun1 (env1 points here), sleep
Now you get a SIGALRM. You execute timer_handler, this time count is 1, so you call fun2. It does more or less the same thing as fun1 and your stack looks like this:
timer_handler, fun1 (&env1), sleep, timer_handler, fun2 (&env2), sleep
One more SIGALRM. Stack looks like this:
timer_handler, fun1(&env1), sleep, timer_handler, fun2 (&env2), sleep, timer_handler, fun3 (&env3), sleep
One more SIGALRM, this is where the fun happens. You siglongjmp to env1. At this point your stack looks like this:
timer_handler, fun1
That's it. There might be stuff on the stack for fun2 and fun3 that might even work when you siglongjmp to them, but those parts are completely invalid now that you've rewound the stack pointer back to fun1. The call to printf seals the deal. Even if there might have been surviving parts on the stack that you could longjmp to, printf will definitely overwrite those parts.
Please suggest if necessary changes are required in the code.
The necessary changes are to delete the code, forget that setjmp and longjmp exist and never speak of this again. You can't do this. I've seen successful implementations of poor mans threads using setjmp and longjmp, but they also set up special stacks for the threads with sigaltstack, had proper locking and critical sections implemented and restricted the allowed functions calls to a very limited set of functions. Using printf when running such code is as far as you can get from having defined behavior. And all the successful implementations of this were of the "Look at this, isn't it horrible?" kind, not something anyone would ever use in real code.
Good Grief !!
I see you added the SA_NODEFER following your earlier question on this piece of code.
Mr POSIX says:
The interaction between setitimer() and alarm() or sleep() is unspecified.
That may be enough to stop this from working... but, frankly, it is so absolutely frightful that it does not deserve to work.
To fix this you need to take all the logic out of the signal action function. Signals are very, very nasty "software interrupts" and need to be handled very carefully, preferably with gloves, eye protection and steady hands. Unless this is homework for setjmp etc., I would treat those as even more nasty, and avoid touching them at all at all.
I need to execute some code 1000 times per second.
I would like to do something like:
set up interval timer
while (1)
{
wait for timer
do something
}
My attempt looks like
// Create timer
timer_t timerid;
struct sigevent sev;
sev.sigev_notify = SIGEV_SIGNAL;
sev.sigev_signo = SIGUSR1;
if (timer_create(CLOCK_REALTIME, &sev, &timerid))
{
perror("timer_create");
exit(1);
}
// Every one mSec (10^6 nsec)
struct itimerspec its;
its.it_value.tv_sec = 0;
its.it_value.tv_nsec = 1000000;
its.it_interval.tv_sec = 0;
its.it_interval.tv_nsec = 1000000;
if (timer_settime(timerid, 0, &its, NULL))
{
perror("timer_settime");
exit(1);
}
// Create mask to wait for SIGUSR1
sigset_t set;
sigemptyset(&set);
sigaddset(&set, SIGUSR1);
while (1)
{
int sig;
// Wait for the timer: Do this loop once per millisecond
sigwait(&set, &sig);
(do something)
}
When I try this, I just get "User defined signal 1" at the console and my program exits. This is not surprising, as this is the default action for the signal. If I set the signal to SIG_IGN using sigaction(2), I never get to my (do something).
I presume I need to do something with sigaction(2), but I don't see an option for "deliver the signal". I don't want to ignore the signal, or do the default action, or call a function.
What's the best way to accomplish my goal?
Or I can just give up and put my (do something) in a function :-)
Edit: I implemented the timerfd idea, and it seems to be working. On to the next bug...
Since you have tagged your question with embedded-linux I assume that portability is not an issue. In that case you might want to have a look at timerfd. It will allow you to use select(2)/poll(2) to receive your timer events. It will also make it easier to combine the interval timer with other event sources such as file descriptors.
I think you should set a true signal handler as suggested by n.m. Look at man sigaction for your version of Linux. You can either call your do_something in signal handler (and wait for something else for program termination) or have a return only handler and keep you sigwait logic.
I am trying to create a handler for the exit signal in c and my operating system is ubuntu.
I am using sigaction method to register my custom handler method.
int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact);
Here's my code
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
void CustomHandler(int signo)
{
printf("Inside custom handler");
switch(signo)
{
case SIGFPE:
printf("ERROR: Illegal arithmatic operation.\n");
break;
}
exit(signo);
}
void newCustomHandler(int signo)
{
printf("Inside new custom handler");
switch(signo)
{
case SIGINT:
printf("ERROR: Illegal arithmatic operation.\n");
break;
}
exit(signo);
}
int main(void)
{
long value;
int i;
struct sigaction act = {CustomHandler};
struct sigaction newact = {newCustomHandler};
newact = act;
sigaction(SIGINT, &newact, NULL); //whats the difference between this
/*sigaction(SIGINT, &act, NULL); // and this?
sigaction(SIGINT, NULL, &newact);*/
for(i = 0; i < 5; i++)
{
printf("Value: ");
scanf("%ld", &value);
printf("Result = %ld\n", 2520 / value);
}
}
Now when I run the program and press Ctrl + c it displays Inside Inside custom handler.
I have read the documentation for sigaction and it says
If act is non-null, the new action for
signal signum is installed from act.
If oldact is non-null, the previous
action is saved in oldact.
why do I need to pass the second structure when I can directly assign the values like
newact = act
Thanks.
oldact is useful to reset the previous action handler:
sigaction(SIGINT, ©Interrupted, &previousHandler);
copy(something);
sigaction(SIGINT, &previousHandler, null);
This way, you can reset the previous signal handler even if you do not know what it was.
When you call sigaction, you replace the old handler with the new one; the oldact pointer is set to point to the handler information in effect before this replacement.
Perhaps, as is often the case, you want the new handlers to be in effect for only a limited region of the code: now that you know what the configuration was before you changed it, you can restore it by another call to sigaction, at the end of this region.
As Norman pointed out, you use oldact because
you want the new handlers to be in effect for only a limited region of the code
But I think one thing previous answers fail to explain very clearly (at least I think it's the only thing needs to be explained here) is oldact is what we read from sigaction.
As described in manual
If oldact is non-NULL, the previous action is saved
in oldact.
Alternatively, you can keep track of previous act, but if you think that's too much trouble, you can extract sigaction in this way.
One scenario one might find this useful, is when there is a default handler for one signal, and you want to use your customized handler for the first (or first few) time(s), and then the signal (if you receive it for many times), would be processed by the default handler, since it takes a lot of trouble to find or rebuild default handler you can put this at the buttom of your handler.
struct sigaction default_sa;
void your_handler(int signum) {
//code for your handler
//...
sigaction(signum,&default_sa,NULL);//use default handler
return ;
}
int main(){
//replace SIGNUM with real signal number
sigaction(SIGNUM,NULL,&default_sa);
struct sigaction sa;
sa.sa_handler = your_handler;
sigemptyset(&sa.sa_mask);
sa.sa_flags = SA_RESTART;
sigaction(SIGNUM, &sa, NULL);
//your rest of main function code
//...
}