/* Compile with: gcc -Wall -o getres -lrt getres.c */
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <time.h>
#include <sys/time.h>

#define USECREQ 250
#define LOOPS   1000

/* Signalhandler fuer den Timer */
void event_handler (int signum)
  {
  static unsigned long cnt = 0;
  static struct timeval tsFirst;
  struct timeval tsNow;
  struct timeval diff;
  unsigned long long udiff;
  double delta;
  unsigned int hz;

  if (cnt == 0)
    /* Anfangszeit */
    gettimeofday (&tsFirst, 0);
  cnt ++;
  if (cnt >= LOOPS)
    {
    /* Timer stoppen und Statistik ausgeben */
    setitimer (ITIMER_REAL, NULL, NULL);
    /* Endezeit */
    gettimeofday (&tsNow, 0);
    /* Zeitdifferenz und daraus Frequenz berechnen */
    timersub(&tsNow, &tsFirst, &diff);
    udiff = (diff.tv_sec * 1000000) + diff.tv_usec;
    delta = (double)(udiff/cnt)/1000000;
    hz = (unsigned)(1.0/delta);
    /* Ausgabe und Ende */
    printf("Kernel-Timer Interruptfrequenz ist ca. %d Hz", hz);
    if (hz >= (unsigned)(1.0/((double)(USECREQ)/1000000)))
      printf(" oder hoeher");
    printf("\n");
    exit(0);
    }
  }

int main(void)
  {
  struct timespec clock_resolution;
  struct sigaction sa;
  struct itimerval timer;

  /* Installiere timer_handler als Signal Handler fuer SIGVALRM. */
  memset(&sa, 0, sizeof (sa));
  sigemptyset(&sa.sa_mask);
  sa.sa_handler = &event_handler;
  sigaction(SIGALRM, &sa, NULL);

  /* Timer konfigurieren */
  timer.it_value.tv_sec = 0;
  timer.it_value.tv_usec = USECREQ;
  timer.it_interval.tv_sec = 0;
  timer.it_interval.tv_usec = USECREQ;

  /* Timer starten */
  setitimer (ITIMER_REAL, &timer, NULL);

  /* Mach irgendwas Wichtiges */
  while(1);

  return 0;
  }

