
#include <ngx_config.h>
#include <ngx_core.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);
    }

#if (NGX_DEBUG_ALLOC)
    ngx_log_debug(log, "malloc: %08x:%d" _ p _ size);
#endif

    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) {
#if (NGX_DEBUG_ALLOC)
        ngx_log_debug(pool->log, "free: %08x" _ l->alloc);
#endif
        free(l->alloc);
    }

    /*
     * we could allocate pool->log from this pool
     * so we can not use this log while free()ing the pool
     */

#if (NGX_DEBUG_ALLOC)
    for (p = pool, n = pool->next; /* void */; p = n, n = n->next) {
        ngx_log_debug(pool->log, "free: %08x" _ p);
    }
#endif

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

        if (n == NULL) {
            break;
        }
    }

    pool = NULL;
}

void *ngx_palloc(ngx_pool_t *pool, size_t size)
{
    char              *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) {
            m = ngx_align(p->last);

            if ((size_t) (p->end - m) >= size) {
                p->last = m + 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);
            large->next = 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;
}
