/*
 * Allocate 10 MB each second. Exit on notification.
 */

#include <sys/mman.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <poll.h>
#include <pthread.h>
#include <errno.h>

int count = 0;
int size = 10;

void *do_alloc() 
{
        for(;;) {
                int *buffer;
                buffer = mmap(NULL,  size*1024*1024,
                              PROT_READ | PROT_WRITE,
                              MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
                if (buffer == MAP_FAILED) {
                        perror("mmap");
                        exit(EXIT_FAILURE);
                }
                memset(buffer, 1 , size*1024*1024);

                printf("-");
                fflush(stdout);

                count++;
                sleep(1);
        }
}

int wait_for_notification(struct pollfd *pfd)
{
        int ret;
        read(pfd->fd, 0, 0);
        ret = poll(pfd, 1, -1);
        if (ret == -1 && errno != EINTR) {
                perror("poll");
                exit(EXIT_FAILURE);
        }
        return ret;
}

void do_free() 
{
        struct pollfd pfd;

        pfd.fd = open("/dev/mem_notify", O_RDONLY);
        if (pfd.fd == -1) {
                perror("open");
                exit(EXIT_FAILURE);
        }
        pfd.events = POLLIN;
        for(;;)
                if (wait_for_notification(&pfd) > 0) {
                        printf("\nGot notification, allocated %d MB\n",
                               size * count);
                        exit(EXIT_SUCCESS);
                }
}

int main(int argc, char *argv[])
{
        pthread_t allocator;

        pthread_create(&allocator, NULL, do_alloc, NULL);
        do_free();
}
