Zurück zur SPiC Übersicht
stoppuhr.c
#include <assert.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <sys/time.h>
#include <unistd.h>
static volatile uint8_t sigint_event;
static volatile uint8_t sigalarm_event;
static volatile uint16_t milliseconds;
static void sigint_handler(int signum) {
sigint_event = 1;
}
static void sigalarm_handler(int signum) {
milliseconds++;
if (milliseconds == 1000) {
milliseconds = 0;
sigalarm_event = 1;
}
}
static void set_timer(uint32_t microseconds) {
struct itimerval tv = {
.it_interval = {
.tv_sec = 0,
.tv_usec = microseconds
},
.it_value = {
.tv_sec = 0,
.tv_usec = microseconds
}
};
setitimer(ITIMER_REAL, &tv, NULL);
}
int main(void) {
sigset_t sync;
sigemptyset(&sync);
sigaddset(&sync, SIGINT);
sigaddset(&sync, SIGALRM);
sigset_t oldmask;
struct sigaction sa = {
.sa_handler = &sigint_handler,
.sa_flags = SA_RESTART,
};
sigemptyset(&sa.sa_mask);
sigaction(SIGINT, &sa, NULL);
sa.sa_handler = &sigalarm_handler;
sigaction(SIGALRM, &sa, NULL);
sigprocmask(SIG_UNBLOCK, &sync, NULL);
printf("SIGINT (Ctrl+C) für Start/Stop\n");
uint8_t running = 0;
int seconds = 0;
while(1) {
sigprocmask(SIG_BLOCK, &sync, &oldmask);
while (!sigint_event && !sigalarm_event) {
sigsuspend(&oldmask);
}
sigprocmask(SIG_SETMASK, &oldmask, NULL);
if (sigint_event) {
sigint_event = 0;
if (running == 0) {
set_timer(1000); running = 1;
printf("Timer läuft!\n");
} else {
set_timer(0);
printf("Vergangene Zeit: %d sec, %d ms\n", seconds, milliseconds);
running = 0;
seconds = 0;
milliseconds = 0;
}
}
if (sigalarm_event) {
sigalarm_event = 0;
seconds++;
printf("%d sec\n", seconds);
}
}
return EXIT_SUCCESS;
}