
#include <ngx_config.h>

#include <ngx_errno.h>
#include <ngx_log.h>
#include <ngx_alloc.h>


void *ngx_alloc(size_t size, ngx_log_t *log)
{
    void *p;

    p = malloc(size);
    if (p == NULL)
        ngx_log_error(NGX_LOG_EMERG, log, ngx_errno,
                      "malloc() %d bytes failed", size);

    ngx_log_debug(log, "malloc: %x" _ p);

    return p;
}

void *ngx_calloc(size_t size, ngx_log_t *log)
{
    void *p;

    p = ngx_alloc(size, log);
    if (p)
        ngx_memzero(p, size);

    return p;
}

ngx_pool_t *ngx_create_pool(size_t size, ngx_log_t *log)
{
    ngx_pool_t *p;

    ngx_test_null(p, ngx_alloc(size, log), NULL);

    p->last = (char *) p + sizeof(ngx_pool_t);
    p->end = (char *) p + size;
    p->next = NULL;
    p->large = NULL;
    p->log = log;

    return p;
}

void ngx_destroy_pool(ngx_pool_t *pool)
{
    ngx_pool_t        *p, *n;
    ngx_pool_large_t  *l;

    for (l = pool->large; l; l = l->next)
        free(l->alloc);

    for (p = pool, n = pool->next; /* void */; p = n, n = n->next) {
        free(p);

        if (n == NULL)
            break;
    }
}

void *ngx_palloc(ngx_pool_t *pool, size_t size)
{
    void              *m;
    ngx_pool_t        *p, *n;
    ngx_pool_large_t  *large, *last;

    if (size <= NGX_MAX_ALLOC_FROM_POOL) {

        for (p = pool, n = pool->next; /* void */; p = n, n = n->next) {
            if ((size_t) (p->end - p->last) >= size) {
                m = p->last;
                p->last += size;

                return m;
            }

            if (n == NULL)
                break;
        }

        /* alloc new pool block */
        ngx_test_null(n, ngx_create_pool(p->end - (char *) p, p->log), NULL);
        p->next = n;
        m = n->last;
        n->last += size;
        return m;

    /* alloc large block */
    } else {
        large = NULL;
        last = NULL;

        if (pool->large) {
            for (last = pool->large; /* void */; last = last->next) {
                if (last->alloc == NULL) {
                    large = last;
                    last = NULL;
                    break;
                }

                if (last->next == NULL)
                    break;
            }
        }

        if (large == NULL) {
            ngx_test_null(large, ngx_palloc(pool, sizeof(ngx_pool_large_t)),
                          NULL);
        }

        ngx_test_null(p, ngx_alloc(size, pool->log), NULL);

        if (pool->large == NULL) {
            pool->large = large;

        } else if (last) {
            last->next = large;
        }

        large->alloc = p;

        return p;
    }
}

void *ngx_pcalloc(ngx_pool_t *pool, size_t size)
{
    void *p;

    p = ngx_palloc(pool, size);
    if (p)
        ngx_memzero(p, size);

    return p;
}
