#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <errno.h>

#include <signal.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <time.h>
#include <stdint.h>

#define UNIX_PATH_MAX 108
#define NSAMPLES 11

#define MAX_SEND_SIZE 4096
unsigned int send_size = 64;

typedef uint64_t u64;

int spos = 0;
u64 samples[NSAMPLES];

u64 xresults[100];
u64 yresults[100];
int rpos = 0;

u64 sent;


void stats(void *sigdata)
{
     static u64 last = 0;
     static int counter = 0;
     u64 cur = sent;
     u64 val = cur - last;

     (void)sigdata;

     printf("Sending %12llu B/sec = %6d kB/sec, send size = %d\n",
	    val, val >> 10, send_size);

     last = cur;

     samples[spos++] = val;

     counter = ++ counter % NSAMPLES;
     if (!counter) {
	  u64 sum = 0;
	  int i, j;

	  /* Assume that 2 first and last entry can contain junk data */
	  for (j = 0, i = 2; i < NSAMPLES - 1; i++, j++)
	       sum += samples[i];

	  xresults[rpos] = send_size;
	  yresults[rpos] = sum/j;

	  ++ rpos;
	  spos = 0;
	  sent = 0;
	  last = 0;
	  send_size *= 2;
     }
}


int main(int argc, char *argv[])
{
     int fd;
     int r;
     int sz;
     char buf[4096] = { 1, 2, 3, 4 };
     struct sigevent sev;
     struct itimerspec its;
     timer_t tid;
     int i;

     setvbuf(stdout, NULL, _IOLBF, 0);

     fd = open("/dev/log_main", O_WRONLY);
     assert(fd >= 0);

     signal(SIGUSR1, stats);

     memset(&sev, 0, sizeof(sev));
     sev.sigev_notify = SIGEV_SIGNAL;
     sev.sigev_signo = SIGUSR1;
     r = timer_create(CLOCK_MONOTONIC, &sev, &tid);
     assert(!r);

     memset(&its, 0, sizeof(its));
     its.it_interval.tv_sec = 1;
     its.it_value.tv_sec = 1;

     r = timer_settime(tid, 0, &its, NULL);
     assert(!r);

     for (; send_size <= MAX_SEND_SIZE; ) {
	  int sz = send_size;

	  while (sz > 0) {
	       r = write(fd, &buf, sz);
	       if (r < 0) {
		    if (errno == -EAGAIN)
			 continue;

		    perror("write");
		    goto out;
	       }
	       sz -= r;
	       sent += r;
	  }
     }

out:

     printf("===\nAverage stats:\npacket size\t\t = Bytes/s\n");
     for (i = 0; i < rpos; i++)
	  printf("%4d = %16llu Bytes/s = %6d kB/s\n", xresults[i],
		 yresults[i], yresults[i]/1024);

     return 0;
}
