
#include <ngx_config.h>
#include <ngx_core.h>
#include <ngx_process.h>
#include <ngx_log.h>
#include <ngx_alloc.h>


extern int   __isthreaded;


typedef int  ngx_tid_t;


static inline int ngx_gettid();


static char        *usrstack;
static int          red_zone = 4096;

static size_t       stack_size;
static size_t       usable_stack_size;
static char        *last_stack;

static int          threads;
static int          nthreads;
static ngx_tid_t   *tids;

/* the thread-safe errno */

static int   errno0;   /* the main thread's errno */
static int  *errnos;

int *__error()
{
    int  tid;

    tid = ngx_gettid();

    return tid ? &errnos[tid - 1] : &errno0;
}


int ngx_create_thread(ngx_tid_t *tid, int (*func)(void *arg), void *arg,
                      ngx_log_t *log)
{
    int         id, err;
    char       *stack, *stack_top;

    if (threads >= nthreads) {
        ngx_log_error(NGX_LOG_CRIT, log, 0,
                      "no more than %d threads can be created", nthreads);
        return NGX_ERROR;
    }

    last_stack -= stack_size;
    stack = mmap(last_stack, usable_stack_size, PROT_READ|PROT_WRITE,
                 MAP_STACK, -1, 0);
    if (stack == MAP_FAILED) {
        ngx_log_error(NGX_LOG_ALERT, log, errno,
                      "mmap(%08X:%d, MAP_STACK) thread stack failed",
                      last_stack, usable_stack_size);
        return NGX_ERROR;
    }

    if (stack != last_stack) {
        ngx_log_error(NGX_LOG_ALERT, log, 0, "stack address was changed");
    }

    stack_top = stack + usable_stack_size;

printf("stack: %08X-%08X\n", stack, stack_top);

#if 1
    id = rfork_thread(RFPROC|RFTHREAD|RFMEM, stack_top, func, arg);
#elif 1
    id = rfork_thread(RFPROC|RFMEM, stack_top, func, arg);
#elif 1
    id = rfork_thread(RFFDG|RFCFDG, stack_top, func, arg);
#else
    id = rfork(RFFDG|RFCFDG);
#endif

    err = errno;

    if (id == -1) {
        ngx_log_error(NGX_LOG_ALERT, log, err, "rfork() failed");

    } else {
        *tid = id;
        threads = (usrstack - stack_top) / stack_size;
        tids[threads] = id;

        /* allow the spinlock in libc malloc() */
        __isthreaded = 1;
    }

    return err;
}


int ngx_init_thread_env(int n, size_t size, ngx_log_t *log)
{
    int    len;
    char  *rz, *zone;

    nthreads = n;

    len = 4;
    if (sysctlbyname("kern.usrstack", &usrstack, &len, NULL, 0) == -1) {
        ngx_log_error(NGX_LOG_ALERT, log, errno,
                      "sysctlbyname(kern.usrstack) failed");
        return NGX_ERROR;
    }

printf("usrstack: %08X\n", usrstack);

    /* red zone */
    rz = usrstack - (size + red_zone);

printf("red zone: %08X\n", rz);

    zone = mmap(rz, red_zone, PROT_NONE, MAP_ANON, -1, 0);
    if (zone == MAP_FAILED) {
        ngx_log_error(NGX_LOG_ALERT, log, errno,
                      "mmap(%08X:%d, PROT_NONE, MAP_ANON) red zone failed",
                      rz, red_zone);
        return NGX_ERROR;
    }

    if (zone != rz) {
        ngx_log_error(NGX_LOG_ALERT, log, 0, "red zone address was changed");
    }

    /* create the thread errno array */
    ngx_test_null(errnos, ngx_calloc(n * sizeof(int), log), NGX_ERROR);

    /* create the thread tid array */
    ngx_test_null(tids, ngx_calloc((n + 1) * sizeof(ngx_tid_t), log),
                  NGX_ERROR);

    tids[0] = ngx_getpid();
    threads = 1;

    last_stack = zone + red_zone;
    usable_stack_size = size;
    stack_size = size + red_zone;

    return NGX_OK;
}


ngx_tid_t ngx_thread_self()
{
    int        tid;
    ngx_tid_t  pid;

    tid = ngx_gettid();

    if (tids[tid] == 0) {
        pid = ngx_getpid();
        tids[tid] = pid;
        return pid;
    }

    return tids[tid];
}


static inline int ngx_gettid()
{
    char  *sp;

    if (stack_size == 0) {
        return 0;
    }

    __asm__ ("mov %%esp, %0" : "=q" (sp));

    return (usrstack - sp) / stack_size;
}
