/**
 * \file
 * \brief process that allocates some memory to test page faulting and page mapping
 */

/*
 * Copyright (c) 2016, ETH Zurich.
 * All rights reserved.
 *
 * This file is distributed under the terms in the attached LICENSE file.
 * If you do not find this file, copies can be found by writing to:
 * ETH Zurich D-INFK, Universitaetsstrasse 6, CH-8092 Zurich. Attn: Systems Group.
 */

#include <stdio.h>
#include <stdlib.h>

#include <aos/aos.h>
#include <aos/paging.h>
#include <aos/deferred.h>

#define NUM_SMALL_BUFFERS 128
// one thread is for the main and MAX_THREADS is 256
#define NUM_THREADS (256 - 1)

static struct thread* threads[NUM_THREADS];

__attribute__((__used__))
static int test_large_buffer(void * __args) {
    //allocate a 256 MiB buffer
    debug_printf("allocating 256MiB buffer\n");
    char * big_buf = malloc(1<<28);
    big_buf[0] = 'a';

    //only write to a small part of the large buffer
    for (int i = 0; i < (1 << 16); i += (1 << 12)) {
        barrelfish_usleep(rand() % 10 * 100000);
        big_buf[i] = 'b';
    }

    debug_printf("freeing 256MiB buffer\n");
    free(big_buf);
    debug_printf("thread done!\n");

    return 0;
}

__attribute__((__used__))
static void test_many_buffers(void) {

    char* buffers[NUM_SMALL_BUFFERS];

    for (int i = 0; i < NUM_SMALL_BUFFERS; ++i) {
        buffers[i] = malloc(4 * BASE_PAGE_SIZE);
    }

    //free the buffers in a different order
    for (int i = NUM_SMALL_BUFFERS - 1; i >= NUM_SMALL_BUFFERS / 2; --i) {
        free(buffers[i]);
    }
    for (int i = 0; i < NUM_SMALL_BUFFERS / 2; ++i) {
        free(buffers[i]);
    }
}


static void test_multi_thread(void) {
    for (int i = 0; i < NUM_THREADS; ++i) {
        threads[i] = thread_create(test_large_buffer, NULL);
    }

    //wait for the threads
    for (int i = 0; i < NUM_THREADS; ++i) {
        thread_join(threads[i], NULL);
    }
}

int main(int argc, char *argv[])
{
    // test_large_buffer();
    // test_many_buffers();
    test_multi_thread();

    debug_printf("i am done!\n");
}