I have the following code:
#include <stdio.h>
#include <sys/time.h>
#include <event.h>
void say_hello(int fd, short event, void *arg){
printf("Hello\n");
}
int main(int argc, const char* argv[])
{
struct event ev;
struct timeval tv;
tv.tv_sec = 3;
tv.tv_usec = 0;
event_init();
evtimer_set(&ev,say_hello,NULL);
evtimer_add(&ev, &tv);
event_dispatch();
return 0;
}
Problem is "hello" gets printed once and then the program exits...
I want it to output "hello" indefinitely.
How to do this? Many thanks in advance,
Just to clarify Basile's solution:
I was confused as well until I realized that "timer" in this context refers to a single shot timer. What we need is an interval timer; which requires the EV_PERSIST flag in libevent.
struct timeval time;
time.tv_sec = 1;
time.tv_usec = 0;
event_set(&my_event, 0, EV_PERSIST, my_function, NULL);
evtimer_add(&my_event, &time);
change the code in main to read
evtimer_set(&ev,say_hello,&ev);
and make your say_hello function
void say_hello(int fd, short event, void *arg){
struct event *ev = arg;
struct timeval tv;
printf("Hello\n");
tv.tv_sec = 3;
tv.tv_usec = 0;
evtimer_add(ev, &tv);
}
Here is the example for libevent2:
#include <event2/event.h>
static int n_calls = 0;
void cb_func(evutil_socket_t fd, short what, void *arg)
{
struct event *me = arg;
printf("cb_func called %d times so far.\n", ++n_calls);
if (n_calls > 100)
event_del(me);
}
void run(struct event_base *base)
{
struct timeval one_sec = { 1, 0 };
struct event *ev;
/* We're going to set up a repeating timer to get called called 100
times. */
ev = event_new(base, -1, EV_PERSIST, cb_func, event_self_cbarg());
event_add(ev, &one_sec);
event_base_dispatch(base);
}
Did you read evtimer_set(3) man page? Please read it again.
You probably want to use the flag EV_PERSIST or call evtimer_add from your say_hello callback.
#include <stdio.h>
#include "ev.h"
static void timer_cback_caller(EV_P_ ev_timer* w, int revents)
{
const int new_timeout_in_ms = 1200; // new delay between timer ticks
printf("timer tick\n");
w->repeat = new_timeout_in_ms / 1000.;
ev_timer_again(EV_A_ w);
}
int main()
{
struct ev_loop *loop = ev_default_loop(0);
ev_timer timer;
const int start_delay_in_ms = 1000; // delay before first timer tick
const int timeout_in_ms = 1500; // delay between every timer tick
ev_timer_init(&timer, timer_cback_caller, start_delay_in_ms/1000., timeout_in_ms/1000.);
ev_timer_start(loop, &timer);
ev_run(loop, 0); // will never return
return 0;
}
More examples in libev documentation
Related
I needed some timer for my program, and I decided to write it with pthreads.
My timer needed to update some info via update callback every update_interval ticks.
I've done it like this:
timer.h:
#include <pthread.h>
enum timer_messages
{
TIMER_START,
TIMER_STOP,
TIMER_PAUSE,
TIMER_EXIT
};
typedef void (*callback)(void *);
struct timer
{
pthread_t thread_id;
struct timeval *interval;
struct timeval *update_interval;
struct timeval *start;
int ls;
int wr;
int enabled;
int exit;
callback update;
callback on_time;
};
struct timer *my_timer_create();
void timer_destroy(struct timer *t);
void timer_set_update_interval(struct timer *t, int seconds, int microseconds);
void timer_set_interval(struct timer *t, int seconds, int microseconds);
void timer_set_update_func(struct timer *t, callback update);
void timer_set_ontime_func(struct timer *t, callback on_time);
void timer_stop(struct timer *t);
void timer_start(struct timer *t);
void timer_exit(struct timer *t);
void timer_pause(struct timer *t);
timer.c:
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/time.h>
#include <string.h>
#include "timer.h"
#define TIMEVAL_TO_MICROSECONDS(tv) ((long long)((tv).tv_sec * 1000000 + (tv).tv_usec))
#define GET_TIME_PASSED(start, now) ((TIMEVAL_TO_MICROSECONDS(now) - TIMEVAL_TO_MICROSECONDS(start)))
static int passed(struct timeval *start, struct timeval *interval);
static void fill_timeval(struct timeval *tv, int sec, int microsec);
static void timer_count(struct timer *t);
static void timer_message(struct timer *t);
static void *main_func(void *data);
static void timer_send_msg(struct timer *t, enum timer_messages message);
static struct timeval DEFAULT_TIMEOUT = { 0, 500000 };
static int passed(struct timeval *start, struct timeval *interval)
{
struct timeval cur, sub;
int check;
check = gettimeofday(&cur, NULL);
if(-1 == check)
{
perror("gettimeofday");
return 0;
}
if(GET_TIME_PASSED(*start, cur) < TIMEVAL_TO_MICROSECONDS(*interval))
return 0;
return 1;
}
static void fill_timeval(struct timeval *tv, int sec, int microsec)
{
tv->tv_sec = sec;
tv->tv_usec = microsec;
}
static void timer_count(struct timer *t)
{
int check;
fd_set readfds;
struct timeval timeout;
check = gettimeofday(t->start, NULL);
while(1)
{
if(!t->enabled)
return;
FD_ZERO(&readfds);
FD_SET(t->ls, &readfds);
if(t->update_interval)
memcpy(&timeout, t->update_interval, sizeof(*(t->update_interval)));
else
memcpy(&timeout, &DEFAULT_TIMEOUT, sizeof(DEFAULT_TIMEOUT));
check = select(t->ls + 1, &readfds, NULL, NULL, &timeout);
if(-1 == check)
{
perror("select");
return;
}
if(FD_ISSET(t->ls, &readfds))
timer_message(t);
else
if(t->update)
t->update(t);
if(passed(t->start, t->interval))
{
t->on_time(t);
break;
}
}
}
static void timer_message(struct timer *t)
{
int read_bytes;
char message;
read_bytes = read(t->ls, &message, sizeof(message));
if(-1 == read_bytes)
{
perror("timer_message read");
return;
}
switch(message)
{
case TIMER_START: t->enabled = 1; break;
case TIMER_STOP: t->enabled = 0; t->interval = NULL; t->start = NULL; break;
case TIMER_EXIT: t->enabled = 0; t->exit = 1; break;
case TIMER_PAUSE: break;
default: break;
}
}
static void *main_func(void *data)
{
struct timer *t = data;
fd_set readfds;
int check;
while(!t->exit)
{
if(t->enabled)
{
timer_count(t);
}
else
{
FD_ZERO(&readfds);
FD_SET(t->ls, &readfds);
check = select(t->ls + 1, &readfds, NULL, NULL, NULL);
if(-1 == check)
{
perror("select");
return NULL;
}
if(FD_ISSET(t->ls, &readfds))
timer_message(t);
}
}
return NULL;
}
static void timer_send_msg(struct timer *t, enum timer_messages message)
{
int check;
char msg;
msg = message;
check = write(t->wr, &msg, sizeof(msg));
if(-1 == check)
{
perror("timer_send_msg write");
}
}
struct timer *my_timer_create()
{
int check;
struct timer *t;
int fd[2];
t = malloc(sizeof(*t));
t->interval = malloc(sizeof(*(t->interval)));
t->update_interval = malloc(sizeof(*(t->update_interval)));
t->start = malloc(sizeof(*(t->start)));
check = pipe(fd);
if(-1 == check)
{
perror("pipe");
return NULL;
}
t->ls = fd[0];
t->wr = fd[1];
t->enabled = 0;
t->exit = 0;
t->update = NULL;
t->on_time = NULL;
check = pthread_create(&(t->thread_id), NULL, main_func, t);
if(-1 == check)
{
perror("pthread_create");
return NULL;
}
return t;
}
void timer_destroy(struct timer *t)
{
free(t->interval);
free(t->update_interval);
free(t->start);
close(t->ls);
close(t->wr);
free(t);
}
void timer_set_update_interval(struct timer *t, int seconds, int microseconds)
{
fill_timeval(t->update_interval, seconds, microseconds);
}
void timer_set_interval(struct timer *t, int seconds, int microseconds)
{
fill_timeval(t->interval, seconds, microseconds);
}
void timer_set_update_func(struct timer *t, callback update)
{
t->update = update;
}
void timer_set_ontime_func(struct timer *t, callback on_time)
{
t->on_time = on_time;
}
void timer_stop(struct timer *t)
{
timer_send_msg(t, TIMER_STOP);
}
void timer_start(struct timer *t)
{
timer_send_msg(t, TIMER_START);
}
void timer_exit(struct timer *t)
{
timer_send_msg(t, TIMER_EXIT);
}
void timer_pause(struct timer *t)
{
timer_send_msg(t, TIMER_PAUSE);
}
And then in main file invoked it like this:
#include <stdio.h>
#include <assert.h>
#include <string.h>
#include <sys/time.h>
#include "../timer.h"
#define BUF_SIZE 4096
#define TIMEVAL_TO_MICROSECONDS(tv) ((long long)((tv).tv_sec * 1000000 + (tv).tv_usec))
#define GET_TIME_PASSED(start, now) ((TIMEVAL_TO_MICROSECONDS(now) - TIMEVAL_TO_MICROSECONDS(start)))
void progress_bar(int percent, int bar_len)
{
char buf[BUF_SIZE];
int inside = bar_len - 2;
int filled = inside * percent / 100;
int not_filled = inside - filled;
assert(percent <= 100);
assert(bar_len < BUF_SIZE);
buf[0] = '[';
memset(buf + 1, '#', filled);
memset(buf + 1 + filled, '-', not_filled);
buf[bar_len - 1] = ']';
buf[bar_len] = 0;
printf("\r%s %d%%", buf, percent);
fflush(stdout);
}
void timer_ontime(void *data)
{
struct timer *t = data;
puts("");
puts("That's all folks!");
timer_exit(t);
}
void timer_update(void *data)
{
struct timer *t = data;
struct timeval now;
long long passed;
int percent;
gettimeofday(&now, NULL);
passed = GET_TIME_PASSED(*(t->start), now);
percent = passed * 100 / (t->interval->tv_sec * 1000000);
progress_bar(percent, 50);
}
int main(int argc, char **argv)
{
struct timer *t;
int seconds;
int check;
if(argc != 2)
{
fprintf(stderr, "Usage: %s <seconds>\n", argv[0]);
return 1;
}
check = sscanf(argv[1], "%d", &seconds);
if(check != 1)
{
fprintf(stderr, "Couldn't parse number of seconds\n");
return 1;
}
t = my_timer_create();
if(t == NULL)
{
fprintf(stderr, "Couldn't create timer\n");
return 1;
}
timer_set_interval(t, seconds, 0);
timer_set_ontime_func(t, timer_ontime);
timer_set_update_func(t, timer_update);
timer_start(t);
printf("Started timer(%d seconds)\n", seconds);
pthread_join(t->thread_id, NULL);
}
Then i run it with:
[udalny#bulba test]$ time ./timer_check 3
Started timer(3 seconds)
[###############################################-] 99%
That's all folks!
./timer_check 3 0.48s user 1.22s system 56% cpu 3.002 total
So as you can see it takes 56% CPU time. Why so much?
It updates only twice per second(DEFAULT_CALLBACK is 500000 microseconds). And all
other time it is sleeping.
How could I change it so it takes less?
Also I would appreciate any tips on the code.
Your program spends most of its time in timer_count, looping busily - if you add a simple printf before your select:
printf("?\n");
check = select(t->ls + 1, &readfds, NULL, NULL, &timeout);
and run ./timer_check 3 | wc -l you should get millions of lines - meaning the CPU hard-loops on this loop. This is because of the way you initialize your timeout:
if(t->update_interval)
memcpy(&timeout, t->update_interval, sizeof(*(t->update_interval)));
this actually sets your timeout to zero - because you never initialized your t->update_interval in main. This effectively turns your loop into a busy loop.
Add the following line to your main function to fix this:
timer_set_update_interval(t, seconds, 0);
after which you get your desired behavior:
Started timer(3 seconds)
[################################################] 100%
That's all folks!
0.00user 0.00system 0:03.00elapsed 0%CPU (0avgtext+0avgdata 1932maxresident)k
0inputs+0outputs (0major+77minor)pagefaults 0swaps
I have to do for University a project about UDP, where i have to guarantee reliable communication; for packets, i want use timer_gettime() and timer_Settime() functions, because i can queue signals and i can associate to them a timer; in particular, struct sigevent has a field which union sigval where i can pass value to handler when signal arrived; I would like to take advantage of this passing to handler number of packets for which timer expired; I have a problem, and I've done a simple program to verify this; when I start timer, i can disarm it setting it_value of struct sigevent to 0; but data doesn't change; if I send 100 signal, header receives only data of first signal. This is my code:
#include <signal.h>
#include <time.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <unistd.h>
int d;
void err_exit(char* str)
{
perror(str);
exit(EXIT_FAILURE);
}
void sighandler(int sig, siginfo_t *si, void *uc)
{
(void) sig;
(void) uc;
d = si->si_value.sival_int;
}
void handle_signal(struct sigaction* sa)
{
sa->sa_flags = SA_SIGINFO;
sa->sa_sigaction = sighandler;
sigemptyset(&sa->sa_mask);
if (sigaction(SIGRTMAX,sa,NULL) == -1)
err_exit("sigaction");
}
void create_timer(struct sigevent* sev,timer_t* timer_id,int i)
{
union sigval s;
s.sival_int = i;
printf("value: %d\n",i);
sev->sigev_notify = SIGEV_SIGNAL;
sev->sigev_signo = SIGRTMAX;
sev->sigev_value = s;
timer_create(CLOCK_REALTIME,sev,timer_id);
}
void set_timer(timer_t timer_id,struct itimerspec* ts)
{
if(ts == NULL)
printf("itimerspec null\n");
if (timer_settime(timer_id, 0, ts, NULL) == -1){
printf("errno code: %d\n",errno);
err_exit("timer_settime");
}
}
void initialize_timerspec(struct itimerspec* ts)
{
ts->it_value.tv_sec = 2;
ts->it_value.tv_nsec = 5;
ts->it_interval.tv_sec = 0;
ts->it_interval.tv_nsec = 0;
}
void reset_timer(timer_t timer_id, struct itimerspec* ts)
{
ts->it_value.tv_sec = 0;
ts->it_value.tv_nsec = 0;
ts->it_interval.tv_sec = 0;
ts->it_interval.tv_nsec = 0;
if (timer_settime(timer_id, 0, ts, NULL) == -1){
printf("errno code: %d\n",errno);
err_exit("timer_settime");
}
}
int main()
{
struct sigaction sa;
struct itimerspec ts[2];
struct sigevent sev[2];
timer_t timer_id[2];
handle_signal(&sa);
create_timer(sev,timer_id,0);
initialize_timerspec(ts);
set_timer(timer_id,ts);
reset_timer(timer_id,ts);
create_timer(sev + 1,timer_id + 1,1);
initialize_timerspec(ts + 1);
set_timer(timer_id,ts + 1);
printf("id1: %ju id2: %ju\n",timer_id[0],timer_id[1]);
sleep(10);
printf("d = %d\n",d);
exit(EXIT_SUCCESS);
}
I disarm first timer, and send another signal; but handler receives data associated to first signal, because it prints 0. Is there a way to send to overwrite data, sending to handler data of second signal(in this case 1)?
I m trying to set the flag variable on(working with raspbery pi. I need pin on) for 500 useconds(micro seconds) and flag off for 300 useconds continuously(infinitely until I stop it). I thought of implementing it using 2 timers.
Now In this program i have written for 5 seconds and 3 seconds.
#include <signal.h>
#include <stdio.h>
#include <string.h>
#include <sys/time.h>
#include <unistd.h>
struct sigaction sa;
struct itimerval timer1,timer2;
int count=1;
void timer_handler (int signum)
{
if(count++%2==1)
printf("High\n"); //flag=1
else
printf("Low\n"); //flag=0
}
int main ()
{
/* Install timer_handler as the signal handler for SIGVTALRM. */
memset (&sa, 0, sizeof (sa));
sa.sa_handler = &timer_handler;
sa.sa_flags = SA_RESTART;
sigaction (SIGALRM, &sa, NULL);
int i=0;
while(1){
scanf(" %d",&i);
if(i==1){ // I m starting 2 timers here
timer1.it_value.tv_sec = 0;
timer1.it_value.tv_usec = 1;
timer1.it_interval.tv_sec = 8; //5+3
timer1.it_interval.tv_usec = 0;
timer2.it_value.tv_sec = 5;
timer2.it_value.tv_usec = 0;
timer2.it_interval.tv_sec = 8;
timer2.it_interval.tv_usec = 0;
setitimer (ITIMER_REAL, &timer1, NULL);
setitimer (ITIMER_REAL, &timer2, NULL);
}
else if(i==2) // I m stopping here
{
timer1.it_value.tv_sec = 0;
timer1.it_value.tv_usec = 0;
timer1.it_interval.tv_sec = 0;
timer1.it_interval.tv_usec = 0;
timer2.it_value.tv_sec = 0;
timer2.it_value.tv_usec = 0;
timer2.it_interval.tv_sec = 0;
timer2.it_interval.tv_usec = 0;
setitimer (ITIMER_REAL, &timer1, NULL); // 1st timer on
setitimer (ITIMER_REAL, &timer2, NULL); //2nd timer on
}
}
}
This is code I have written.
what actually happening is the second timer is running and first timer is not running. I think its overwritten.
Ps. I dont want to use sleep function as it takes more time. I m using timers as the resolution is microsecond.
1.How do I do this using two timers?
2.Is there any better method to do this task?
There is only one ITIMER_REAL, so you must create virtual timers yourself. A simple and reliable possibility if you don't need microsecond precision, is to use a periodic timer with a small interval and implement your virtual timers on top of that (so every "tick" from your periodic timer will decrement your virtual timers).
Following an example how you could implement it:
vtimer.h
#ifndef VTIMER_H
#define VTIMER_H
typedef void (vtimer_timeout)(void *arg);
typedef struct vtimer
{
int msec;
int periodic;
int current;
vtimer_timeout *timeout;
} vtimer;
#define vtimer_init(m, p, cb) { \
.msec=(m), .periodic=(p), .current=0, .timeout=cb}
void vtimer_start(vtimer *self, void *timeoutArg);
void vtimer_stop(vtimer *self);
// call this periodically, e.g. after each interrupted library call:
void vtimer_dispatch();
#endif
vtimer.c
#define _POSIX_C_SOURCE 200101L
#include "vtimer.h"
#include <stddef.h>
#include <signal.h>
#include <sys/time.h>
#define NUM_TIMERS 8
static vtimer *timers[NUM_TIMERS] = {0};
static void *timoutArgs[NUM_TIMERS] = {0};
static size_t ntimers = 0;
static volatile sig_atomic_t ticks = 0;
static void tickhandler(int signum)
{
(void)signum;
++ticks;
}
static struct sigaction timerAction = {.sa_handler = tickhandler};
static struct sigaction defaultAction;
static struct itimerval tickTimerval = {{0, 1000}, {0, 1000}};
static struct itimerval disableTimerval = {{0,0},{0,0}};
void vtimer_start(vtimer *self, void *timeoutArg)
{
int found = 0;
for (size_t idx = 0; idx < NUM_TIMERS; ++idx)
{
if (timers[idx] == self)
{
found = 1;
break;
}
}
if (!found)
{
if (ntimers == NUM_TIMERS) return; // or maybe return error
if (!ntimers++)
{
// only start the "ticking" timer when necessary
sigaction(SIGALRM, &timerAction, &defaultAction);
setitimer(ITIMER_REAL, &tickTimerval, 0);
}
for (size_t idx = 0; idx < NUM_TIMERS; ++idx)
{
if (!timers[idx])
{
timers[idx] = self;
timoutArgs[idx] = timeoutArg;
break;
}
}
}
self->current = self->msec;
}
void vtimer_stop(vtimer *self)
{
int found = 0;
for (size_t idx = 0; idx < NUM_TIMERS; ++idx)
{
if (timers[idx] == self)
{
timers[idx] = 0;
found = 1;
break;
}
}
if (found && !--ntimers)
{
// no virtual timers running -> stop ticking timer
setitimer(ITIMER_REAL, &disableTimerval, 0);
sigaction(SIGALRM, &defaultAction, 0);
}
}
void vtimer_dispatch(void)
{
while (ticks)
{
--ticks;
for (size_t idx = 0; idx < NUM_TIMERS; ++idx)
{
if (timers[idx])
{
if (!--(timers[idx]->current))
{
timers[idx]->timeout(timoutArgs[idx]);
if (timers[idx]->periodic)
{
timers[idx]->current = timers[idx]->msec;
}
else vtimer_stop(timers[idx]);
}
}
}
}
}
Example program using this:
#include "vtimer.h"
#include <stdio.h>
#include <errno.h>
static void timer1_timeout(void *arg)
{
(void) arg;
puts("timer 1");
}
static void timer2_timeout(void *arg)
{
(void) arg;
puts("timer 2");
}
int main(void)
{
vtimer timer1 = vtimer_init(5000, 1, timer1_timeout);
vtimer timer2 = vtimer_init(8000, 1, timer2_timeout);
vtimer_start(&timer1, 0);
vtimer_start(&timer2, 0);
for (;;)
{
errno = 0;
int c = getchar();
if (c == EOF && errno != EINTR) break;
if (c == 'q') break;
vtimer_dispatch();
}
vtimer_stop(&timer2);
vtimer_stop(&timer1);
return 0;
}
There are a lot of design decisions on the way (e.g. how frequent your ticks should be (here 1ms), having a fixed number of virtual timers vs a dynamic one, using pointers as "timer handles" or maybe integers, and so on), so think about what you need and try to write your own.
I'm intending to use epoll to check out timerfd and fire some actions.
Code is blow:
#include <time.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/timerfd.h>
#include <stdint.h>
#include <unistd.h>
#include <sys/epoll.h>
int main(int argc, char const *argv[])
{
struct timespec now;
clock_gettime(CLOCK_MONOTONIC, &now);
int timerfd;
timerfd = timerfd_create(CLOCK_MONOTONIC, 0);
struct itimerspec new_value;
new_value.it_value.tv_sec = 1;
new_value.it_interval.tv_sec = 1;
timerfd_settime(timerfd, 0, &new_value, NULL);
// uint64_t buff;
// while(true) {
// read(timerfd, &buff, sizeof(uint64_t));
// printf("%s\n", "ding");
// }
// code above works fine.
struct epoll_event ev, events[10];
int epollfd;
epollfd = epoll_create1(0);
if (epollfd == -1) {
perror("epoll_create1");
exit(EXIT_FAILURE);
}
ev.events = EPOLLIN;
ev.data.fd = timerfd;
if (epoll_ctl(epollfd, EPOLL_CTL_ADD, timerfd, &ev) == -1) {
perror("epoll_ctl: timerfd");
exit(EXIT_FAILURE);
}
int num;
printf("start\n");
while(true) {
num = epoll_wait(epollfd, events, 10, -1);
printf("%d\n", num);
uint64_t buff;
read(timerfd, &buff, sizeof(uint64_t));
printf("%s\n", "ding");
}
return 0;
}
When using timerfd seperately, it works fine. Every second will print "ding". But when adding epoll to observe timerfd, progrom will block at epoll_wait for ever.
I'v tryed using EPOLLET, but noting changed. What's wrong with this code?
Your itimerspec is not properly initialized, so depending on what particular garbage values it contains, timerfd_settime() might fail. To detect that, do error checking:
if (timerfd_settime(timerfd, 0, &new_value, NULL) != 0) {
perror("settime");
exit(-1);
}
Another way to debug this is to run your program under the strace, program, and you will see which, if any, system calls that fails.
The relevant structs looks like this:
struct timespec {
time_t tv_sec;
long tv_nsec;
};
struct itimerspec {
struct timespec it_interval;
struct timespec it_value;
};
You have to initialize both these members completely, and your program will work reliably:
new_value.it_value.tv_sec = 1;
new_value.it_value.tv_nsec = 0;
new_value.it_interval.tv_sec = 1;
new_value.it_interval.tv_nsec = 0;
Actually I want to implement non-blocking timer, when the timer expires a handler will be called and will do something (for now it prints data). I google and realized that timer_create, timer_settimer are non-blocking timer. BUT still I've issue, I have to wait for my timer to expire (sleep(MAX) or while(1) {;}). But then if I'm calling my start_timer method with different "expiry" time, it should work accordingly, should not block other. e.g. here first time I'm calling timer, and expecting to call handler in 5 sec but before that 2nd call should print its data as, that interval I've given is 1sec only. And of course its not behaving same. Any idea?
#include <time.h>
#include <stdio.h>
#include <signal.h>
#include <pthread.h>
#include <unistd.h>
#include <errno.h>
typedef struct _data{
char *name;
}data;
void handler(union sigval val)
{
data *data_handler = val.sival_ptr;
printf("Handler entered with value :%s\n", data_handler->name);
}
void mod_timer(timer_t timerid, struct sigevent sig, struct itimerspec in, struct itimerspec out)
{
printf("mod_timer\n");
timer_settime(timerid, 0, &in, &out);
while(1)
sleep(1);
//delete the timer.
timer_delete(timerid);
}
void start_timer(void* val, int interval)
{
int Ret;
pthread_attr_t attr;
pthread_attr_init( &attr );
struct sched_param parm;
parm.sched_priority = 255;
pthread_attr_setschedparam(&attr, &parm);
struct sigevent sig;
sig.sigev_notify = SIGEV_THREAD;
sig.sigev_notify_function = handler;
// sig.sigev_value.sival_int = val;
sig.sigev_value.sival_ptr = val;
sig.sigev_notify_attributes = &attr;
//create a new timer.
timer_t timerid;
Ret = timer_create(CLOCK_REALTIME, &sig, &timerid);
if (Ret == 0)
{
struct itimerspec in, out;
in.it_value.tv_sec = 1;
in.it_value.tv_nsec = 0;
in.it_interval.tv_sec = interval;
in.it_interval.tv_nsec = 0;
mod_timer(timerid, sig, in, out);
}
}
void main()
{
// start_timer(1, 5);
// start_timer(2, 1);
data handler_data1 = {"Handler Data 1"};
data handler_data2 = {"Handler Data 2"};
void *data1 = &handler_data1;
void *data2 = &handler_data2;
start_timer(data1, 5);
start_timer(data2, 1);
}
You can use the alarm function to generate a signal, and the signal function to specify the handler to that signal.