Модуль 5. Лекция 18 - Школа системного моделирования
Author
Co-authors
#define _GNU_SOURCE
#include <stdio.h>
#include <stdint.h>
#include <stdbool.h>
#include <unistd.h>
#include <sys/timerfd.h>
#include <time.h>
#include <errno.h>
#include "piCtl.h"
static void do_step(void)
{
static bool OverrunFlag = false;
if (OverrunFlag) {
/* model step overrun – skip this tick */
return;
}
OverrunFlag = true;
piCtl_step();
OverrunFlag = false;
}
int main(void)
{
int tfd;
struct itimerspec ts;
uint64_t expirations;
FILE * fd;
piCtl_init();
fd = fopen("output.csv","wt");
/* Create timerfd (monotonic clock = no jumps on NTP) */
tfd = timerfd_create(CLOCK_MONOTONIC, 0);
if (tfd == -1) {
perror("timerfd_create");
return 1;
}
/* 1 ms period */
ts.it_interval.tv_sec = 0;
ts.it_interval.tv_nsec = 1 * 1000 * 1000; /* 1 ms */
/* start after 1 ms */
ts.it_value = ts.it_interval;
if (timerfd_settime(tfd, 0, &ts, NULL) == -1) {
perror("timerfd_settime");
return 1;
}
/* Main loop driven by timer */
while (1) {
ssize_t s = read(tfd, &expirations, sizeof(expirations));
if (s != sizeof(expirations)) {
perror("read(timerfd)");
break;
}
/*
* expirations > 1 means we missed ticks
* (model slower than real-time)
*/
while (expirations--) {
do_step();
}
}
piCtl_term();
close(tfd);
return 0;
}