#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>
#include <signal.h>
#include <ucontext.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
#define TM_ONESHOT 1
#define TM_INTERVAL 0
#define QUEMAX 256
timer_t timerid;
volatile static int head = 0,tail=0;
volatile static int event_queue[QUEMAX];
static int sigint_sigevent(int signum, siginfo_t *info, void *ctx){
int ret;
ret = 0;
if(signum>0){ // シグナルによる呼び出し
event_queue[tail++] = signum;
if(tail>=QUEMAX){
tail = 0;
}
if(head==tail){
head++;
if(head>=QUEMAX){
head = 0;
}
}
}else{
if(head!=tail){
ret = event_queue[head++];
if(head>=QUEMAX){
head = 0;
}
}
}
return ret;
}
int set_signal_handler(void){
struct sigaction sa;
memset(&sa, 0, sizeof(sa));
sa.sa_flags = SA_SIGINFO|SA_RESTART;
sigemptyset(&sa.sa_mask);
sigaddset(&sa.sa_mask,SIGINT);
sigaddset(&sa.sa_mask,SIGRTMIN+1);
sa.sa_sigaction = (void *)sigint_sigevent;
if(sigaction(SIGINT,&sa,(struct sigaction *)NULL)) {
perror("sigaction error");
exit(1);
}
sa.sa_sigaction = (void *)sigint_sigevent;
if(sigaction(SIGRTMIN+1,&sa,(struct sigaction *)NULL)) {
perror("sigaction error");
exit(1);
}
return 0;
}
int set_timer_count(int oneshot,int sec,int nsec){
struct itimerspec ispec;
if(oneshot!=TM_INTERVAL){
ispec.it_interval.tv_sec = 0;
ispec.it_interval.tv_nsec = 0;
}else{
ispec.it_interval.tv_sec = sec;
ispec.it_interval.tv_nsec = nsec;
}
ispec.it_value.tv_sec = sec;
ispec.it_value.tv_nsec = nsec;
if(timer_settime(timerid, 0, &ispec, NULL) < 0){
perror("timer_settime error");
exit(1);
}
return 0;
}
int init_timer(void){
struct sigevent se;
memset(&se, 0, sizeof(se));
se.sigev_notify = SIGEV_SIGNAL;
se.sigev_signo = SIGRTMIN+1;
if(timer_create(CLOCK_REALTIME, &se, &timerid) < 0){
perror("timer_create error");
exit(1);
}
return 0;
}
int main(int argc, char** argv)
{
init_timer();
set_timer_count(TM_INTERVAL,0,500000000);
set_signal_handler();
while(1){
printf("%d:%d sigevent:%d\n",head,tail,sigint_sigevent(0,NULL,NULL));
while(usleep(50000)!=0);
}
return 0;
}