#include <sys/types.h>
#include <sys/wait.h>
#include <time.h>
#include <signal.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <assert.h>
#include <errno.h>
static timer_t timer_server_id;
static pid_t timer_server_pid;
static int timer_server_initialize(void)
{
struct sigevent ev;
int r;
memset(&ev, 0, sizeof(&ev));
ev.sigev_notify = SIGEV_THREAD_ID;
ev.sigev_signo = SIGUSR1;
ev._sigev_un._tid = timer_server_pid; /* see gcc -E */
r = timer_create(CLOCK_MONOTONIC, &ev, &timer_server_id);
assert(r == 0);
return 0;
}
static void usr_handler(int signo)
{
int ov;
ov = timer_getoverrun(timer_server_id);
printf("%s pid: %d, sig: %d, overrun: %d\n", __func__, getpid(), signo, ov);
}
static void sig_init(void)
{
struct sigaction act;
sigset_t set, oldset;
memset(&act, 0, sizeof(act));
act.sa_handler = usr_handler;
act.sa_flags = SA_RESTART;
sigfillset(&set);
sigprocmask(SIG_BLOCK, &set, &oldset);
sigemptyset(&set);
sigaddset(&set, SIGUSR1);
sigprocmask(SIG_UNBLOCK, &set, &oldset);
act.sa_mask = set;
sigaction(SIGUSR1, &act, NULL);
}
int main(int argc, char* argv[])
{
struct itimerspec it;
struct timespec now;
int r;
pid_t pid;
pid = fork();
if ( pid < 0) {
fprintf(stderr, "fork: %s\n", strerror(errno));
exit(1);
}
if (pid > 0) { /* parent */
int status;
printf("parent pid: %d\n", getpid());
waitpid(pid, &status, 0);
if (WIFEXITED(status)) {
printf("child exited.\n");
}
} else { /* child */
timer_server_pid = getpid();
sig_init();
timer_server_initialize();
printf("child pid: %d\n", timer_server_pid);
printf("timer initialized.\n");
clock_gettime(CLOCK_MONOTONIC, &now);
it.it_value.tv_sec = now.tv_sec + 1;
it.it_value.tv_nsec = now.tv_nsec;
it.it_interval.tv_sec = 0;
it.it_interval.tv_nsec = 500000000;
r = timer_settime(timer_server_id, TIMER_ABSTIME, &it, NULL);
assert(r == 0);
printf("timer created.\n");
{
struct timespec ts;
int i;
ts.tv_sec = 1;
ts.tv_nsec = 0;
for (i = 0; i < 10; i++) {
nanosleep(&ts, NULL);
}
}
}
return 0;
}
|