/*
 * Copyright (c) 2009, 2010 Wayne Meissner
 * Copyright (c) 2008-2013, Ruby FFI project contributors
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above copyright
 *       notice, this list of conditions and the following disclaimer in the
 *       documentation and/or other materials provided with the distribution.
 *     * Neither the name of the Ruby FFI project nor the
 *       names of its contributors may be used to endorse or promote products
 *       derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#ifndef _MSC_VER
#include <sys/param.h>
#endif
#include <sys/types.h>
#if defined(__CYGWIN__) || !defined(_WIN32)
#  include <sys/mman.h>
#endif
#include <stdio.h>
#ifndef _MSC_VER
# include <stdint.h>
# include <stdbool.h>
#else
# include "win32/stdbool.h"
# include "win32/stdint.h"
#endif
#if defined(__CYGWIN__) || !defined(_WIN32)
#  include <unistd.h>
#else
#  include <winsock2.h>
#  define _WINSOCKAPI_
#  include <windows.h>
#endif
#include <errno.h>
#include <ruby.h>

#if defined(_MSC_VER) && !defined(INT8_MIN)
#  include "win32/stdint.h"
#endif
#include <ffi.h>
#include "rbffi.h"
#include "compat.h"

#include "Function.h"
#include "Types.h"
#include "Type.h"
#include "LastError.h"
#include "Call.h"

#include "ClosurePool.h"


#ifndef roundup
#  define roundup(x, y)   ((((x)+((y)-1))/(y))*(y))
#endif
#ifdef _WIN32
  typedef char* caddr_t;
#endif

typedef struct Memory {
    void* code;
    void* data;
    struct Memory* next;
} Memory;

struct ClosurePool_ {
    void* ctx;
    int closureSize;
    bool (*prep)(void* ctx, void *code, Closure* closure, char* errbuf, size_t errbufsize);
    struct Memory* blocks; /* Keeps track of all the allocated memory for this pool */
    Closure* list;
    long refcnt;
};

static long pageSize;

static void* allocatePage(void);
static bool freePage(void *);
static bool protectPage(void *);

ClosurePool*
rbffi_ClosurePool_New(int closureSize, 
        bool (*prep)(void* ctx, void *code, Closure* closure, char* errbuf, size_t errbufsize),
        void* ctx)
{
    ClosurePool* pool;

    pool = xcalloc(1, sizeof(*pool));
    pool->closureSize = closureSize;
    pool->ctx = ctx;
    pool->prep = prep;
    pool->refcnt = 1;
    
    return pool;
}

void
cleanup_closure_pool(ClosurePool* pool)
{
    Memory* memory;
    
    for (memory = pool->blocks; memory != NULL; ) {
        Memory* next = memory->next;
        freePage(memory->code);
        free(memory->data);
        free(memory);
        memory = next;
    }
    xfree(pool);
}

void
rbffi_ClosurePool_Free(ClosurePool* pool)
{
    if (pool != NULL) {
        long refcnt = --(pool->refcnt);
        if (refcnt == 0) {
            cleanup_closure_pool(pool);
        }
    }
}

Closure*
rbffi_Closure_Alloc(ClosurePool* pool)
{
    Closure *list = NULL;
    Memory* block = NULL;
    caddr_t code = NULL;
    char errmsg[256];
    int nclosures;
    long trampolineSize;
    int i;

    if (pool->list != NULL) {
        Closure* closure = pool->list;
        pool->list = pool->list->next;
        pool->refcnt++;
    
        return closure;
    }

    trampolineSize = roundup(pool->closureSize, 8);
    nclosures = (int) (pageSize / trampolineSize);
    block = calloc(1, sizeof(*block));
    list = calloc(nclosures, sizeof(*list));
    code = allocatePage();
    
    if (block == NULL || list == NULL || code == NULL) {
        snprintf(errmsg, sizeof(errmsg), "failed to allocate a page. errno=%d (%s)", errno, strerror(errno));
        goto error;
    }
    
    for (i = 0; i < nclosures; ++i) {
        Closure* closure = &list[i];
        closure->next = &list[i + 1];
        closure->pool = pool;
        closure->code = (code + (i * trampolineSize));

        if (!(*pool->prep)(pool->ctx, closure->code, closure, errmsg, sizeof(errmsg))) {
            goto error;
        }
    }

    if (!protectPage(code)) {
        goto error;
    }

    /* Track the allocated page + Closure memory area */
    block->data = list;
    block->code = code;
    block->next = pool->blocks;
    pool->blocks = block;

    /* Thread the new block onto the free list, apart from the first one. */
    list[nclosures - 1].next = pool->list;
    pool->list = list->next;
    pool->refcnt++;

    /* Use the first one as the new handle */
    return list;

error:
    free(block);
    free(list);
    if (code != NULL) {
        freePage(code);
    }
    

    rb_raise(rb_eRuntimeError, "%s", errmsg);
    return NULL;
}

void
rbffi_Closure_Free(Closure* closure)
{
    if (closure != NULL) {
        ClosurePool* pool = closure->pool;
        long refcnt;
        /* Just push it on the front of the free list */
        closure->next = pool->list;
        pool->list = closure;
        refcnt = --(pool->refcnt);
        if (refcnt == 0) {
            cleanup_closure_pool(pool);
        }
    }
}

void*
rbffi_Closure_CodeAddress(Closure* handle)
{
    return handle->code;
}


static long
getPageSize()
{
#if !defined(__CYGWIN__) && (defined(_WIN32) || defined(__WIN32__))
    SYSTEM_INFO si;
    GetSystemInfo(&si);
    return si.dwPageSize;
#else
    return sysconf(_SC_PAGESIZE);
#endif
}

static void*
allocatePage(void)
{
#if !defined(__CYGWIN__) && (defined(_WIN32) || defined(__WIN32__))
    return VirtualAlloc(NULL, pageSize, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
#else
    caddr_t page = mmap(NULL, pageSize, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE, -1, 0);
    return (page != (caddr_t) -1) ? page : NULL;
#endif
}

static bool
freePage(void *addr)
{
#if !defined(__CYGWIN__) && (defined(_WIN32) || defined(__WIN32__))
    return VirtualFree(addr, 0, MEM_RELEASE);
#else
    return munmap(addr, pageSize) == 0;
#endif
}

static bool
protectPage(void* page)
{
#if !defined(__CYGWIN__) && (defined(_WIN32) || defined(__WIN32__))
    DWORD oldProtect;
    return VirtualProtect(page, pageSize, PAGE_EXECUTE_READ, &oldProtect);
#else
    return mprotect(page, pageSize, PROT_READ | PROT_EXEC) == 0;
#endif
}

void
rbffi_ClosurePool_Init(VALUE module)
{
    pageSize = getPageSize();
}

