#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include <sys/lockstat.h>

int fd = -1;
lsctl_t lsctl;

void init_ls() {
    if (fd > 0)
	close(fd);

    fd = open("/dev/lockstat", O_RDWR);
    if (fd < 0) {
	perror("opening /dev/lockstat");
	exit(1);
    }

    if (write(fd, &lsctl, sizeof(lsctl)) != sizeof(lsctl)) {
	perror("writing lockstat control");
	exit(1);
    }
}

void handle_data(char *buf, int rec_len, int rec_cnt) {
    lsrec_t *l;
    int i;

    for (i=0; i<rec_cnt; i++) {
	l = buf + rec_len*i;
	/* Handle (lsrec_t *)l and note read locks without an appropriate
	 * release..
	 */
    }
}

int main() {
    int rlen;
    int nlocks;

    char *buf;
    int buf_len;

    memset(&lsctl, 0, sizeof(lsctl));
    lsctl.lc_recsize = LS_STACK(5);
    lsctl.lc_nlocks = 10000;
    lsctl.lc_event[LS_RW_WRITER_HOLD] = LSE_ENTER | LSE_EXIT | LSE_RECORD;
    lsctl.lc_event[LS_RW_READER_HOLD] = LSE_ENTER | LSE_EXIT | LSE_RECORD;

    buf_len = lsctl.lc_recsize * (lsctl.lc_nlocks + 1);
    buf = malloc(buf_len);
    init_ls();

    while(1) {
	/* Wait.. */
	sleep(1);

	lseek(fd, 0, SEEK_SET);
	rlen = read(fd, buf, buf_len);
	init_ls();
	if (rlen < 0) {
	    perror("reading lockstat data");
	    exit(1);
	}
	nlocks = rlen / lsctl.lc_recsize;

	if (nlocks >= lsctl.lc_nlocks)
	    printf("Warning: lockstat module ran out of lock records.\n");

	handle_data(buf, nlocks, lsctl.lc_recsize);
    }
}
