Ngnix 源码学习----内存池的申请

来源:互联网 发布:json格式数据 编辑:程序博客网 时间:2024/06/05 08:30

这篇文章,主要是对代码的注释。就是对内存池的销毁,以及如何使用内存池的内存。如果 对内存的结构已经很了解,那么,对以下代码就很好理解了

////销毁内存池 基本都是链表的基本操作。voidngx_destroy_pool(ngx_pool_t *pool){    ngx_pool_t          *p, *n;    ngx_pool_large_t    *l;    ngx_pool_cleanup_t  *c;///根据注册的ngx_pool_cleanup_s 来逐个销毁内存    for (c = pool->cleanup; c; c = c->next) {        if (c->handler) {            ngx_log_debug1(NGX_LOG_DEBUG_ALLOC, pool->log, 0,                           "run cleanup: %p", c);            c->handler(c->data);        }    }    ///销毁大大内存块    for (l = pool->large; l; l = l->next) {        ngx_log_debug1(NGX_LOG_DEBUG_ALLOC, pool->log, 0, "free: %p", l->alloc);        if (l->alloc) {            ngx_free(l->alloc);        }    }#if (NGX_DEBUG)    /*     * we could allocate the pool->log from this pool     * so we cannot use this log while free()ing the pool     */    for (p = pool, n = pool->d.next; /* void */; p = n, n = n->d.next) {        ngx_log_debug2(NGX_LOG_DEBUG_ALLOC, pool->log, 0,                       "free: %p, unused: %uz", p, p->d.end - p->d.last);        if (n == NULL) {            break;        }    }#endif    ///普通销毁,    for (p = pool, n = pool->d.next; /* void */; p = n, n = n->d.next) {        ngx_free(p);        if (n == NULL) {            break;        }    }}////充值内存池,先销毁,再重新分配内存voidngx_reset_pool(ngx_pool_t *pool){    ngx_pool_t        *p;    ngx_pool_large_t  *l;    for (l = pool->large; l; l = l->next) {        if (l->alloc) {            ngx_free(l->alloc);        }    }    pool->large = NULL;    for (p = pool; p; p = p->d.next) {        p->d.last = (u_char *) p + sizeof(ngx_pool_t);    }}/////这个方法就是 申请了内存后,///对内存的使用了。void *ngx_palloc(ngx_pool_t *pool, size_t size){    u_char      *m;    ngx_pool_t  *p;    if (size <= pool->max) {        p = pool->current;        do {            m = ngx_align_ptr(p->d.last, NGX_ALIGNMENT);            if ((size_t) (p->d.end - m) >= size) {                p->d.last = m + size;                return m;            }            p = p->d.next;        } while (p);        return ngx_palloc_block(pool, size);///内存不够了,申请下一块内存池链表结构    }    return ngx_palloc_large(pool, size);/////申请大内存池块。}///同上。void *ngx_pnalloc(ngx_pool_t *pool, size_t size){    u_char      *m;    ngx_pool_t  *p;    if (size <= pool->max) {        p = pool->current;        do {            m = p->d.last;            if ((size_t) (p->d.end - m) >= size) {                p->d.last = m + size;                return m;            }            p = p->d.next;        } while (p);        return ngx_palloc_block(pool, size);    }    return ngx_palloc_large(pool, size);}////申请下一个内存块。static void *ngx_palloc_block(ngx_pool_t *pool, size_t size){    u_char      *m;    size_t       psize;    ngx_pool_t  *p, *new, *current;    psize = (size_t) (pool->d.end - (u_char *) pool); //计算pool大小    m = ngx_memalign(NGX_POOL_ALIGNMENT, psize, pool->log);////申请psize大小的内存    if (m == NULL) {        return NULL;    }    new = (ngx_pool_t *) m; //给new。    new->d.end = m + psize;//在额外申一个等大小的内存 ,设置end 值    new->d.next = NULL;    new->d.failed = 0;    m += sizeof(ngx_pool_data_t);    m = ngx_align_ptr(m, NGX_ALIGNMENT);    new->d.last = m + size;    current = pool->current;    for (p = current; p->d.next; p = p->d.next) {        if (p->d.failed++ > 4) {            current = p->d.next;        }    }    p->d.next = new;    pool->current = current ? current : new;    return m;}////申请大内存块。static void *ngx_palloc_large(ngx_pool_t *pool, size_t size){    void              *p;    ngx_uint_t         n;    ngx_pool_large_t  *large;    p = ngx_alloc(size, pool->log);    if (p == NULL) {        return NULL;    }    n = 0;    for (large = pool->large; large; large = large->next) {        if (large->alloc == NULL) {            large->alloc = p;            return p;        }        if (n++ > 3) {            break;        }    }    large = ngx_palloc(pool, sizeof(ngx_pool_large_t));    if (large == NULL) {        ngx_free(p);        return NULL;    }    large->alloc = p;    large->next = pool->large;    pool->large = large;    return p;}void *ngx_pmemalign(ngx_pool_t *pool, size_t size, size_t alignment){    void              *p;    ngx_pool_large_t  *large;    p = ngx_memalign(alignment, size, pool->log);    if (p == NULL) {        return NULL;    }    large = ngx_palloc(pool, sizeof(ngx_pool_large_t));    if (large == NULL) {        ngx_free(p);        return NULL;    }    large->alloc = p;    large->next = pool->large;    pool->large = large;    return p;}////释放内存内存。基本的链表操作ngx_int_tngx_pfree(ngx_pool_t *pool, void *p){    ngx_pool_large_t  *l;    for (l = pool->large; l; l = l->next) {        if (p == l->alloc) {            ngx_log_debug1(NGX_LOG_DEBUG_ALLOC, pool->log, 0,                           "free: %p", l->alloc);            ngx_free(l->alloc);            l->alloc = NULL;            return NGX_OK;        }    }    return NGX_DECLINED;}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;}/////注册cleanup的一个内存池分配ngx_pool_cleanup_t *ngx_pool_cleanup_add(ngx_pool_t *p, size_t size){    ngx_pool_cleanup_t  *c;    c = ngx_palloc(p, sizeof(ngx_pool_cleanup_t));    if (c == NULL) {        return NULL;    }    if (size) {        c->data = ngx_palloc(p, size);        if (c->data == NULL) {            return NULL;        }    } else {        c->data = NULL;    }    c->handler = NULL;    c->next = p->cleanup;    p->cleanup = c;    ngx_log_debug1(NGX_LOG_DEBUG_ALLOC, p->log, 0, "add cleanup: %p", c);    return c;}voidngx_pool_run_cleanup_file(ngx_pool_t *p, ngx_fd_t fd){    ngx_pool_cleanup_t       *c;    ngx_pool_cleanup_file_t  *cf;    for (c = p->cleanup; c; c = c->next) {        if (c->handler == ngx_pool_cleanup_file) {            cf = c->data;            if (cf->fd == fd) {                c->handler(cf);                c->handler = NULL;                return;            }        }    }}voidngx_pool_cleanup_file(void *data){    ngx_pool_cleanup_file_t  *c = data;    ngx_log_debug1(NGX_LOG_DEBUG_ALLOC, c->log, 0, "file cleanup: fd:%d",                   c->fd);    if (ngx_close_file(c->fd) == NGX_FILE_ERROR) {        ngx_log_error(NGX_LOG_ALERT, c->log, ngx_errno,                      ngx_close_file_n " \"%s\" failed", c->name);    }}voidngx_pool_delete_file(void *data){    ngx_pool_cleanup_file_t  *c = data;    ngx_err_t  err;    ngx_log_debug2(NGX_LOG_DEBUG_ALLOC, c->log, 0, "file cleanup: fd:%d %s",                   c->fd, c->name);    if (ngx_delete_file(c->name) == NGX_FILE_ERROR) {        err = ngx_errno;        if (err != NGX_ENOENT) {            ngx_log_error(NGX_LOG_CRIT, c->log, err,                          ngx_delete_file_n " \"%s\" failed", c->name);        }    }    if (ngx_close_file(c->fd) == NGX_FILE_ERROR) {        ngx_log_error(NGX_LOG_ALERT, c->log, ngx_errno,                      ngx_close_file_n " \"%s\" failed", c->name);    }}#if 0static void *ngx_get_cached_block(size_t size){    void                     *p;    ngx_cached_block_slot_t  *slot;    if (ngx_cycle->cache == NULL) {        return NULL;    }    slot = &ngx_cycle->cache[(size + ngx_pagesize - 1) / ngx_pagesize];    slot->tries++;    if (slot->number) {        p = slot->block;        slot->block = slot->block->next;        slot->number--;        return p;    }    return NULL;}#endif


 

下面给几个图片以帮助大家理解。不是我画的

 

基本的内存数据结构

 

 

内存配图,很清晰了,都是链表的操作


 

看完之后,已经对ngnix的内存池的分配有很清晰的认识了,以后写个内存可以借鉴他的。哈哈,

 

 

更多文章欢迎访问:http://blog.csdn.net/wallwind

原创粉丝点击