#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>
#include <time.h>
#include <unistd.h>
#include <fcntl.h>
#include <signal.h>

#define FILENAME "/tmp/seqfile"

static int get_sequence_number(char *filename)
{
	char buf[16] = { '\0', };
	int fd, n;
	struct flock fl = { 0, };

	fd = open(filename, O_RDWR | O_CREAT, 0666);
	if (fd < 0)
		return -1;
	fl.l_type = F_WRLCK;
	fl.l_whence = SEEK_SET;
	fl.l_start = fl.l_len = 0;
	if (fcntl(fd, F_SETLKW, &fl) < 0) {
	out:
		close(fd);
		return -1;
	}
	n = read(fd, buf, sizeof buf - 1);
	if (n < 0)
		goto out;
	else if (n > 0) {
		n = atoi(buf);
		if (!n)
			goto out;
	}
	lseek(fd, 0, SEEK_SET);
	write(fd, buf, snprintf(buf, sizeof buf, "%d\n", n + 1));
	close(fd);
	return n;
}

static volatile int done;
static void alrmcatcher(int unused)
{
	done = 1;
}
int main (void)
{
	struct timeval tv, tv0;
	int seq, n = 0;
	double t;

	gettimeofday(&tv0, NULL);
	signal(SIGALRM, alrmcatcher);
	alarm(10);
	while (!done) {
		seq = get_sequence_number(FILENAME);
		n++;
		if (!(seq & 0x7fff))
			fprintf(stderr, "%d...\r", seq);
	}
	gettimeofday(&tv, NULL);
	t = tv.tv_sec - tv0.tv_sec + (tv.tv_usec - tv0.tv_usec) / 1000000.0;
	printf("%d sequence values in %.2f seconds (%.1f per second)\n",
	       n, t, n/t);
	return 0;
}

