Understanding struct itimerval field tv_usec - c

Hi I'm studying this code:
#include <signal.h>
#include <stdio.h>
#include <string.h>
#include <sys/time.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdbool.h>
volatile sig_atomic_t print_flag = true;
static int count = 0;
void timer_handler (int signum)
{
printf ("timer expired %d times\n", ++count);
if(count>20) {
print_flag = false;
}
}
int main ()
{
struct sigaction sa;
struct itimerval timer;
/* Install timer_handler as the signal handler for SIGVTALRM. */
memset (&sa, 0, sizeof (sa));
sa.sa_handler = &timer_handler;
sigaction (SIGALRM, &sa, NULL);
/* Configure the timer to expire after 250 msec... */
timer.it_value.tv_sec = 0;
timer.it_value.tv_usec = 250000;
/* ... and every 250 msec after that. */
timer.it_interval.tv_sec = 0;
timer.it_interval.tv_usec = 250000;
/* Start a virtual timer. It counts down whenever this process is
executing. */
setitimer (ITIMER_REAL, &timer, NULL);
/* Do busy work. */
while (print_flag) {
sleep(1);
}
printf("job done bye bye\n");
exit(0);
}
With this settings everything goes fine and i get this output
...
timer expired 17 times
timer expired 18 times
timer expired 19 times
timer expired 20 times
timer expired 21 times
job done bye bye
If i try to alter the code commenting timer.it_interval.tv_usec and timer.it_interval.tv_usecand setting both timer.it_value.tv_sec and timer.it_value.tv_sec equal to, for instance, 3 it doesn't do his job.
However if I maintain an explicit declaration of tv_usec like this it works:
timer.it_value.tv_sec = 3;
timer.it_value.tv_usec = 0;
timer.it_interval.tv_sec = 3;
timer.it_interval.tv_usec = 0;
Why I'm bonded on the explicit declaration of tv_usec for both fields?

As far as you don't initialize *.tv_usec fields, theirs values are undefined. If it'd contain a value greater that 999999 or less than 0, the setitimer () will just fail with EINVAL as described on the man page.
You ought to initialize all the data yourself. If you are willing to save a line of code, you may memset the timer struct to 0 the same way you have done it for sa.

Related

linux pthread running in a loop for specified time (avoiding signals)

hello what i want do is:
thread (pthread.h) need to execute code in a while loop for some period of time that will be defined at run time
after that the thread will finish correctly the last loop and continue for some other work.
right now I am using signals: This is the loop
setTimer(sec);
while(flag)
{
//do some work
}
// continue to run
and i use signal to call for function that will set flag to false:
void setTimer(int sec)
{
struct sigaction sa;
struct itimerval timer;
memset (&sa, 0, sizeof (sa));
sa.sa_handler = &alarm_end_of_loop; // this is the function to change flag to false
sigaction (SIGVTALRM, &sa, NULL);
timer.it_value.tv_sec = sec;
timer.it_value.tv_usec = 0;
timer.it_interval.tv_sec = 0;
timer.it_interval.tv_usec = 0;
setitimer (ITIMER_REAL, &timer, NULL);
}
void alarm_end_of_loop()
{
flag = 0; //flag is global but only one thread will access it
}
My question is there a way to avoid using signals?
Seems to be a timeout pattern.
double get_delta_time_to_now(const time_t timeout_time)
{
time_t now;
time(&now);
return difftime(now, timeout_time);
}
void do_it(int sec)
{
time_t timeout_time;
double diff;
time(&timeout_time);
timeout_time += sec; /* this is not necessarily correct */
diff = get_delta_time_to_now(timeout_time);
while (diff <= 0.0)
{
/* do your stuff */
diff = get_delta_time_to_now(timeout_time);
}
}

How to generate same signal (SIGALRM) again and again?

We are trying to take control from while(1) loop in three of our functions using sigaction and setitimer and problem that we are facing right now is that only once SIGALRM is generated and for the next time it is not generating ie we are able to take control from while(1) of fun1() but not from while(1) of fun2().
Could you please suggest the ways to over come this problem.Please find the code below.
#define INTERVAL 500
void fun1();
void fun2();
void fun3();
void timer_handler(int );
struct itimerval it_val;
int count=0;
void timer_handler (int signum)
{
L1:
printf(“\nScheduler Called .. Calling Fun1″);
if(count==0){
count++;
fun1();
}
printf(“\nScheduler Called .. Calling Fun2″);
if(count==1){
count++;
fun2();
}
printf(“\nScheduler Called .. Calling Fun3″);
if(count==2){
count++;
fun3();
}
count=0;
goto L1;
}
void fun1()
{
struct sigaction sa;
/* Install timer_handler as the signal handler for SIGVTALRM. */
memset (&sa, 0, sizeof (sa));
sa.sa_handler = &timer_handler;
/* Configure the timer to expire */
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;
/* Start a timer. It counts down whenever this process is*/
sigaction (SIGALRM, &sa, NULL);
setitimer (ITIMER_REAL, &it_val, NULL);
while (1){
printf(“\nfun1″);
}
}
void fun2()
{
struct sigaction sa;
/* Install timer_handler as the signal handler for SIGVTALRM. */
memset (&sa, 0, sizeof (sa));
sa.sa_handler = &timer_handler;
/* Configure the timer to expire */
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;
/* Start a timer. It counts down whenever this process is*/
sigaction (SIGALRM, &sa, NULL);
setitimer (ITIMER_REAL, &it_val, NULL);
while (1){
printf(“\nfun2″);
}
}
void fun3()
{
struct sigaction sa;
/* Install timer_handler as the signal handler for SIGVTALRM. */
memset (&sa, 0, sizeof (sa));
sa.sa_handler = &timer_handler;
/* Configure the timer to expire */
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;
/* Start a timer. It counts down whenever this process is*/
sigaction (SIGALRM, &sa, NULL);
setitimer (ITIMER_REAL, &it_val, NULL);
while (1){
printf(“\nfun3″);
}
}
int main(){
timer_handler(1);
return 0;
}
When a signal is delivered it is automagically masked until the action function returns.
In general you want to your signal action function to do the absolute minimum. What you have written is effectively a recursive action function with most of your program inside it. Even if it did work you would be eating stack until there was none left !
Chapter and verse: from sigaction() for POSIX:
When a signal is caught by a signal-catching function installed by
sigaction(), a new signal mask is calculated and installed for the
duration of the signal-catching function (or until a call to either
sigprocmask() or sigsuspend() is made). This mask is formed by taking
the union of the current signal mask and the value of the sa_mask for
the signal being delivered, and unless SA_NODEFER or SA_RESETHAND is
set, then including the signal being delivered. If and when the user's
signal handler returns normally, the original signal mask is restored.
Read carefully time(7) and signal(7) and signal-safety(7)
A signal handler can do very few things (it should not call, even indirectly, printf or malloc ...) Many signal handlers simply set a volatile sigatomic_t integer variable, which is later tested in the code.
I would suggest having some event loop based upon some multiplexing syscall like poll(2). You could use existing event loop frameworks (like libev, libevent, glib, etc....) or make your own above poll. The Linux specific timerfd_create(2) & signalfd(2) could help a lot.

Weird behavior of gettimeofday

I would like to obtain the elapsed time between one thread enters to the Critical Zone and the other takes the permision to enter in the same Critical Zone on ARM CortexA8. For this I have been using the function gettimeofday() in C.
void *Thread1_Routine (); //Create the Semaphore
void *Thread2_Routine (); //Wait for Thread1_Routine's Semaphore
void configured_malloc_behavior();
void Calc_Dif_Time (struct timeval *time1,struct timeval *time2);
//Definition to represent the time
typedef struct te_tim96
{
int64_t sec;
int32_t usec;
}te_tim96;
//Variables to save the time
struct timeval t1,t2;
//Variable to control the order enter Critical zone
char lock=0;
int count=0;
//Variable to make the create the mutex
pthread_mutex_t mutex;
int main (void)
{
//Variables define threads
pthread_t threadadd1, threadadd2;
pthread_attr_t attr1, attr2;
struct sched_param p1, p2;
//Configured malloc behavior
configured_malloc_behavior();
//Init the Thread
pthread_mutex_init(&mutex, NULL);
//Define Threads
pthread_attr_init(&attr1);
pthread_attr_init(&attr2);
//Thread1
pthread_attr_setschedpolicy(&attr1, SCHED_FIFO);
p1.sched_priority= 98; //This is lower than Thread2
pthread_attr_setschedparam(&attr1, &p1);
//Thread2
pthread_attr_setschedpolicy(&attr2, SCHED_FIFO);
p2.sched_priority= 99;
pthread_attr_setschedparam(&attr2, &p2);
//End define Threads
//Init the gpio63 as Output
do Stuff()
//Create the threads
pthread_create(&threadadd1,&attr1,&Thread1_Routine, NULL);
pthread_create(&threadadd2,&attr2,&Thread2_Routine, NULL);
//Wait to end the Threads ()
pthread_join(threadadd1, NULL);
pthread_join(threadadd2, NULL);
return 0;
}
//Thread Producer
void *Thread1_Routine (void)
{
//Variable to write in gpio/value
char value=1;
while (count<MAXCOUNT)
{
sleep (3);
pthread_mutex_lock(&mutex);
lock=lock+1; //Increment variable lock to indicate that the Thread Producer was done.
gettimeofday(&t1, NULL);
pthread_mutex_unlock(&mutex);
}
pthread_exit(NULL);
}
//Thread Consumer
void *Thread2_Routine (void)
{
//Variable to write in gpio/value
char value=0;
while (count<MAXCOUNT)
{
//Wait for the semaphore is free!!!!!
while (lock=0);
pthread_mutex_lock(&mutex);
lock=lock-1; //Decrement variable lock to indicate that the Thread Producer was done.
gettimeofday(&t2, NULL);
Calc_Dif_Time(&t1, &t2); //Function to calculate the latency and plot it
pthread_mutex_unlock(&mutex);
count++; //To incremate the count of how many time goes the thread are made
}
pthread_exit(NULL);
}
void Calc_Dif_Time (struct timeval *time1,struct timeval *time2)
{
struct te_tim96 Tmeasure1, Tmeasure2;
double Elapsedtime;
//TmeasureY=tY
Tmeasure1.sec=(*time1).tv_sec;
Tmeasure1.usec=(*time1).tv_usec;
Tmeasure2.sec=(*time2).tv_sec;
Tmeasure2.usec=(*time2).tv_usec;
//Calculate
//Part in sec to miliseconds
Elapsedtime=(Tmeasure2.sec-Tmeasure1.sec)*1000;
//Part in usec to miliseconds
Elapsedtime+=(Tmeasure2.usec-Tmeasure1.usec)*0.001;
//Work with the rest of the division to convert usec to miliseconds
printf("Time to create the Semaphore[%lld.%6ld] Time to take the Semaphore[%lld.%6ld] Elapsed Time [%f ms]\n", Tmeasure1.sec, Tmeasure1.usec, Tmeasure2.sec, Tmeasure2.usec, Elapsedtime);
Elapsedtime=0; //Reset Elapsedtime to the next measure
}
The program is without error, but my problem, when I execute it, is that the console show the following result:
./R_T_Measure4
Time to create the Semaphore[0. 0] Time to take the Semaphore[4878.153276] Elapsed Time [4878153.276000 ms]
Time to create the Semaphore[0. 0] Time to take the Semaphore[4878.153886] Elapsed Time [4878153.886000 ms]
This result shows how I might that the t1 variable is not pointed well or it is restarted. But I don't know that I am overlooking in this case because t2 works well.
Any help will be grateful
-Regards
Your while loop isn't waiting for the lock to be free. When you do while (lock=0);, that will always return 0, and you will end your loop immediately, and it is also messing up your locking, because you are setting your lock variable. You should use while (lock == 0);
You always call Calc_Dif_Time from thread 2 so if Thread 2 gets the lock before thread 1 t1 will be uninitialised

Having trouble using sigaction with a timer signal

Hi everyone
i'm trying to use sigaction() however without success
this is my code:
int main()
{
struct sigaction act, oact;
act.sa_handler = (void *)g;
sigaction(SIGVTALRM,&act,&oact);
struct itimerval tv;
tv.it_value.tv_sec = 2; //time of first timer
tv.it_value.tv_usec = 0; //time of first timer
tv.it_interval.tv_sec = 2; //time of all timers but the first one
tv.it_interval.tv_usec = 0; //time of all timers but the first one
setitimer(ITIMER_VIRTUAL, &tv, NULL);
for (;;);
}
this is g():
void g( void ){
printf("I'M NOT IN G!!");
for (;;);
}
when i run the code i get stuck in the first for(;;) loop without ever getting to g().
why don't i get to g() if i defined it as the function that handles the signal?
thank you
First, you should ensure that the input struct sigaction structure is clean:
sigemptyset(&act.sa_mask);
act.sa_flags = 0;
act.sa_handler = g;
Then, you should suspend the process rather than use a for-loop "spin wait":
sigset_t mask;
sigprocmask(0, NULL, &mask);
sigdelset(&mask, SIGVTALRM);
sigsuspend(&mask);
Lastly, your signal-handler should be defined correctly and not use the printf() function, which is considered unsafe in the presence of signals and shouldn't be used in a signal-handler. Instead, it should set an atomic flag:
static volatile sig_atomic_t g_called;
void g(int sig) {
g_called = 1;
}
The fundamental problem is that you're using an uninitialized sigaction structure. Either initialize it with:
struct sigaction act = {0};
Or use memset to clear it before calling sigaction.

need programs that illustrate use of settimer and alarm functions in GNU C

Can anyone illustrate the use of settimer or alarm function in gnu C , with some program examples ,please ?
I have a program that continuously processes some data , and i need to set a timer / alarm that goes off every t seconds , in response to which , i need to store the processed data into a file. This file writing has to be asynchronous < i.e. the data processing and file writing must not wait for each other > . I went through the GNU C Library pages , but i couldn't understand much..
[EDIT]
I got this program :
#include <stdio.h>
#include <signal.h>
#include <sys/time.h>
#define INTERVAL 1
int howmany = 0;
void alarm_wakeup (int i)
{
struct itimerval tout_val;
signal(SIGALRM,alarm_wakeup);
howmany += INTERVAL;
printf("\n%d sec up partner, Wakeup!!!\n",howmany);
tout_val.it_interval.tv_sec = 0;
tout_val.it_interval.tv_usec = 0;
tout_val.it_value.tv_sec = INTERVAL; /* 10 seconds timer */
tout_val.it_value.tv_usec = 0;
setitimer(ITIMER_REAL, &tout_val,0);
}
void exit_func (int i)
{
signal(SIGINT,exit_func);
printf("\nBye Bye!!!\n");
exit(0);
}
int main ()
{
struct itimerval tout_val;
tout_val.it_interval.tv_sec = 0;
tout_val.it_interval.tv_usec = 0;
tout_val.it_value.tv_sec = INTERVAL; /* 10 seconds timer */
tout_val.it_value.tv_usec = 0;
setitimer(ITIMER_REAL, &tout_val,0);
signal(SIGALRM,alarm_wakeup); /* set the Alarm signal capture */
signal(SIGINT,exit_func);
while (1)
{
//printf("!");
}
return 0;
}
But seems like i cannot do anything while the timer is on..
What should i modify to suit my needs ? Pl suggest..
[/EDIT]
Here's an example from here which uses setitimer() to periodically call DoStuff().
The key here is that calling setitimer() results in the OS scheduling a SIGALRM to be sent to your process after the specified time has elapsed, and it is up to your program to handle that signal when it comes. You handle the signal by registering a signal handler function for the signal type (DoStufF() in this case) after which the OS will know to call that function when the timer expires.
You can read the setitimer() man page to figure out what the arguments are and how to cancel a timer.
Note: if you want the timer to trigger only once, you will have to call alarm() or ualarm() instead of setitimer().
/*
* setitimer.c - simple use of the interval timer
*/
#include <sys/time.h> /* for setitimer */
#include <unistd.h> /* for pause */
#include <signal.h> /* for signal */
#define INTERVAL 500 /* number of milliseconds to go off */
/* function prototype */
void DoStuff(void);
int main(int argc, char *argv[]) {
struct itimerval it_val; /* for setting itimer */
/* Upon SIGALRM, call DoStuff().
* Set interval timer. We want frequency in ms,
* but the setitimer call needs seconds and useconds. */
if (signal(SIGALRM, (void (*)(int)) DoStuff) == SIG_ERR) {
perror("Unable to catch SIGALRM");
exit(1);
}
it_val.it_value.tv_sec = INTERVAL/1000;
it_val.it_value.tv_usec = (INTERVAL*1000) % 1000000;
it_val.it_interval = it_val.it_value;
if (setitimer(ITIMER_REAL, &it_val, NULL) == -1) {
perror("error calling setitimer()");
exit(1);
}
while (1)
pause();
}
/*
* DoStuff
*/
void DoStuff(void) {
printf("Timer went off.\n");
}

Resources