Annotation of embedaddon/nginx/src/core/ngx_palloc.c, revision 1.1.1.1

1.1       misho       1: 
                      2: /*
                      3:  * Copyright (C) Igor Sysoev
                      4:  * Copyright (C) Nginx, Inc.
                      5:  */
                      6: 
                      7: 
                      8: #include <ngx_config.h>
                      9: #include <ngx_core.h>
                     10: 
                     11: 
                     12: static void *ngx_palloc_block(ngx_pool_t *pool, size_t size);
                     13: static void *ngx_palloc_large(ngx_pool_t *pool, size_t size);
                     14: 
                     15: 
                     16: ngx_pool_t *
                     17: ngx_create_pool(size_t size, ngx_log_t *log)
                     18: {
                     19:     ngx_pool_t  *p;
                     20: 
                     21:     p = ngx_memalign(NGX_POOL_ALIGNMENT, size, log);
                     22:     if (p == NULL) {
                     23:         return NULL;
                     24:     }
                     25: 
                     26:     p->d.last = (u_char *) p + sizeof(ngx_pool_t);
                     27:     p->d.end = (u_char *) p + size;
                     28:     p->d.next = NULL;
                     29:     p->d.failed = 0;
                     30: 
                     31:     size = size - sizeof(ngx_pool_t);
                     32:     p->max = (size < NGX_MAX_ALLOC_FROM_POOL) ? size : NGX_MAX_ALLOC_FROM_POOL;
                     33: 
                     34:     p->current = p;
                     35:     p->chain = NULL;
                     36:     p->large = NULL;
                     37:     p->cleanup = NULL;
                     38:     p->log = log;
                     39: 
                     40:     return p;
                     41: }
                     42: 
                     43: 
                     44: void
                     45: ngx_destroy_pool(ngx_pool_t *pool)
                     46: {
                     47:     ngx_pool_t          *p, *n;
                     48:     ngx_pool_large_t    *l;
                     49:     ngx_pool_cleanup_t  *c;
                     50: 
                     51:     for (c = pool->cleanup; c; c = c->next) {
                     52:         if (c->handler) {
                     53:             ngx_log_debug1(NGX_LOG_DEBUG_ALLOC, pool->log, 0,
                     54:                            "run cleanup: %p", c);
                     55:             c->handler(c->data);
                     56:         }
                     57:     }
                     58: 
                     59:     for (l = pool->large; l; l = l->next) {
                     60: 
                     61:         ngx_log_debug1(NGX_LOG_DEBUG_ALLOC, pool->log, 0, "free: %p", l->alloc);
                     62: 
                     63:         if (l->alloc) {
                     64:             ngx_free(l->alloc);
                     65:         }
                     66:     }
                     67: 
                     68: #if (NGX_DEBUG)
                     69: 
                     70:     /*
                     71:      * we could allocate the pool->log from this pool
                     72:      * so we cannot use this log while free()ing the pool
                     73:      */
                     74: 
                     75:     for (p = pool, n = pool->d.next; /* void */; p = n, n = n->d.next) {
                     76:         ngx_log_debug2(NGX_LOG_DEBUG_ALLOC, pool->log, 0,
                     77:                        "free: %p, unused: %uz", p, p->d.end - p->d.last);
                     78: 
                     79:         if (n == NULL) {
                     80:             break;
                     81:         }
                     82:     }
                     83: 
                     84: #endif
                     85: 
                     86:     for (p = pool, n = pool->d.next; /* void */; p = n, n = n->d.next) {
                     87:         ngx_free(p);
                     88: 
                     89:         if (n == NULL) {
                     90:             break;
                     91:         }
                     92:     }
                     93: }
                     94: 
                     95: 
                     96: void
                     97: ngx_reset_pool(ngx_pool_t *pool)
                     98: {
                     99:     ngx_pool_t        *p;
                    100:     ngx_pool_large_t  *l;
                    101: 
                    102:     for (l = pool->large; l; l = l->next) {
                    103:         if (l->alloc) {
                    104:             ngx_free(l->alloc);
                    105:         }
                    106:     }
                    107: 
                    108:     pool->large = NULL;
                    109: 
                    110:     for (p = pool; p; p = p->d.next) {
                    111:         p->d.last = (u_char *) p + sizeof(ngx_pool_t);
                    112:     }
                    113: }
                    114: 
                    115: 
                    116: void *
                    117: ngx_palloc(ngx_pool_t *pool, size_t size)
                    118: {
                    119:     u_char      *m;
                    120:     ngx_pool_t  *p;
                    121: 
                    122:     if (size <= pool->max) {
                    123: 
                    124:         p = pool->current;
                    125: 
                    126:         do {
                    127:             m = ngx_align_ptr(p->d.last, NGX_ALIGNMENT);
                    128: 
                    129:             if ((size_t) (p->d.end - m) >= size) {
                    130:                 p->d.last = m + size;
                    131: 
                    132:                 return m;
                    133:             }
                    134: 
                    135:             p = p->d.next;
                    136: 
                    137:         } while (p);
                    138: 
                    139:         return ngx_palloc_block(pool, size);
                    140:     }
                    141: 
                    142:     return ngx_palloc_large(pool, size);
                    143: }
                    144: 
                    145: 
                    146: void *
                    147: ngx_pnalloc(ngx_pool_t *pool, size_t size)
                    148: {
                    149:     u_char      *m;
                    150:     ngx_pool_t  *p;
                    151: 
                    152:     if (size <= pool->max) {
                    153: 
                    154:         p = pool->current;
                    155: 
                    156:         do {
                    157:             m = p->d.last;
                    158: 
                    159:             if ((size_t) (p->d.end - m) >= size) {
                    160:                 p->d.last = m + size;
                    161: 
                    162:                 return m;
                    163:             }
                    164: 
                    165:             p = p->d.next;
                    166: 
                    167:         } while (p);
                    168: 
                    169:         return ngx_palloc_block(pool, size);
                    170:     }
                    171: 
                    172:     return ngx_palloc_large(pool, size);
                    173: }
                    174: 
                    175: 
                    176: static void *
                    177: ngx_palloc_block(ngx_pool_t *pool, size_t size)
                    178: {
                    179:     u_char      *m;
                    180:     size_t       psize;
                    181:     ngx_pool_t  *p, *new, *current;
                    182: 
                    183:     psize = (size_t) (pool->d.end - (u_char *) pool);
                    184: 
                    185:     m = ngx_memalign(NGX_POOL_ALIGNMENT, psize, pool->log);
                    186:     if (m == NULL) {
                    187:         return NULL;
                    188:     }
                    189: 
                    190:     new = (ngx_pool_t *) m;
                    191: 
                    192:     new->d.end = m + psize;
                    193:     new->d.next = NULL;
                    194:     new->d.failed = 0;
                    195: 
                    196:     m += sizeof(ngx_pool_data_t);
                    197:     m = ngx_align_ptr(m, NGX_ALIGNMENT);
                    198:     new->d.last = m + size;
                    199: 
                    200:     current = pool->current;
                    201: 
                    202:     for (p = current; p->d.next; p = p->d.next) {
                    203:         if (p->d.failed++ > 4) {
                    204:             current = p->d.next;
                    205:         }
                    206:     }
                    207: 
                    208:     p->d.next = new;
                    209: 
                    210:     pool->current = current ? current : new;
                    211: 
                    212:     return m;
                    213: }
                    214: 
                    215: 
                    216: static void *
                    217: ngx_palloc_large(ngx_pool_t *pool, size_t size)
                    218: {
                    219:     void              *p;
                    220:     ngx_uint_t         n;
                    221:     ngx_pool_large_t  *large;
                    222: 
                    223:     p = ngx_alloc(size, pool->log);
                    224:     if (p == NULL) {
                    225:         return NULL;
                    226:     }
                    227: 
                    228:     n = 0;
                    229: 
                    230:     for (large = pool->large; large; large = large->next) {
                    231:         if (large->alloc == NULL) {
                    232:             large->alloc = p;
                    233:             return p;
                    234:         }
                    235: 
                    236:         if (n++ > 3) {
                    237:             break;
                    238:         }
                    239:     }
                    240: 
                    241:     large = ngx_palloc(pool, sizeof(ngx_pool_large_t));
                    242:     if (large == NULL) {
                    243:         ngx_free(p);
                    244:         return NULL;
                    245:     }
                    246: 
                    247:     large->alloc = p;
                    248:     large->next = pool->large;
                    249:     pool->large = large;
                    250: 
                    251:     return p;
                    252: }
                    253: 
                    254: 
                    255: void *
                    256: ngx_pmemalign(ngx_pool_t *pool, size_t size, size_t alignment)
                    257: {
                    258:     void              *p;
                    259:     ngx_pool_large_t  *large;
                    260: 
                    261:     p = ngx_memalign(alignment, size, pool->log);
                    262:     if (p == NULL) {
                    263:         return NULL;
                    264:     }
                    265: 
                    266:     large = ngx_palloc(pool, sizeof(ngx_pool_large_t));
                    267:     if (large == NULL) {
                    268:         ngx_free(p);
                    269:         return NULL;
                    270:     }
                    271: 
                    272:     large->alloc = p;
                    273:     large->next = pool->large;
                    274:     pool->large = large;
                    275: 
                    276:     return p;
                    277: }
                    278: 
                    279: 
                    280: ngx_int_t
                    281: ngx_pfree(ngx_pool_t *pool, void *p)
                    282: {
                    283:     ngx_pool_large_t  *l;
                    284: 
                    285:     for (l = pool->large; l; l = l->next) {
                    286:         if (p == l->alloc) {
                    287:             ngx_log_debug1(NGX_LOG_DEBUG_ALLOC, pool->log, 0,
                    288:                            "free: %p", l->alloc);
                    289:             ngx_free(l->alloc);
                    290:             l->alloc = NULL;
                    291: 
                    292:             return NGX_OK;
                    293:         }
                    294:     }
                    295: 
                    296:     return NGX_DECLINED;
                    297: }
                    298: 
                    299: 
                    300: void *
                    301: ngx_pcalloc(ngx_pool_t *pool, size_t size)
                    302: {
                    303:     void *p;
                    304: 
                    305:     p = ngx_palloc(pool, size);
                    306:     if (p) {
                    307:         ngx_memzero(p, size);
                    308:     }
                    309: 
                    310:     return p;
                    311: }
                    312: 
                    313: 
                    314: ngx_pool_cleanup_t *
                    315: ngx_pool_cleanup_add(ngx_pool_t *p, size_t size)
                    316: {
                    317:     ngx_pool_cleanup_t  *c;
                    318: 
                    319:     c = ngx_palloc(p, sizeof(ngx_pool_cleanup_t));
                    320:     if (c == NULL) {
                    321:         return NULL;
                    322:     }
                    323: 
                    324:     if (size) {
                    325:         c->data = ngx_palloc(p, size);
                    326:         if (c->data == NULL) {
                    327:             return NULL;
                    328:         }
                    329: 
                    330:     } else {
                    331:         c->data = NULL;
                    332:     }
                    333: 
                    334:     c->handler = NULL;
                    335:     c->next = p->cleanup;
                    336: 
                    337:     p->cleanup = c;
                    338: 
                    339:     ngx_log_debug1(NGX_LOG_DEBUG_ALLOC, p->log, 0, "add cleanup: %p", c);
                    340: 
                    341:     return c;
                    342: }
                    343: 
                    344: 
                    345: void
                    346: ngx_pool_run_cleanup_file(ngx_pool_t *p, ngx_fd_t fd)
                    347: {
                    348:     ngx_pool_cleanup_t       *c;
                    349:     ngx_pool_cleanup_file_t  *cf;
                    350: 
                    351:     for (c = p->cleanup; c; c = c->next) {
                    352:         if (c->handler == ngx_pool_cleanup_file) {
                    353: 
                    354:             cf = c->data;
                    355: 
                    356:             if (cf->fd == fd) {
                    357:                 c->handler(cf);
                    358:                 c->handler = NULL;
                    359:                 return;
                    360:             }
                    361:         }
                    362:     }
                    363: }
                    364: 
                    365: 
                    366: void
                    367: ngx_pool_cleanup_file(void *data)
                    368: {
                    369:     ngx_pool_cleanup_file_t  *c = data;
                    370: 
                    371:     ngx_log_debug1(NGX_LOG_DEBUG_ALLOC, c->log, 0, "file cleanup: fd:%d",
                    372:                    c->fd);
                    373: 
                    374:     if (ngx_close_file(c->fd) == NGX_FILE_ERROR) {
                    375:         ngx_log_error(NGX_LOG_ALERT, c->log, ngx_errno,
                    376:                       ngx_close_file_n " \"%s\" failed", c->name);
                    377:     }
                    378: }
                    379: 
                    380: 
                    381: void
                    382: ngx_pool_delete_file(void *data)
                    383: {
                    384:     ngx_pool_cleanup_file_t  *c = data;
                    385: 
                    386:     ngx_err_t  err;
                    387: 
                    388:     ngx_log_debug2(NGX_LOG_DEBUG_ALLOC, c->log, 0, "file cleanup: fd:%d %s",
                    389:                    c->fd, c->name);
                    390: 
                    391:     if (ngx_delete_file(c->name) == NGX_FILE_ERROR) {
                    392:         err = ngx_errno;
                    393: 
                    394:         if (err != NGX_ENOENT) {
                    395:             ngx_log_error(NGX_LOG_CRIT, c->log, err,
                    396:                           ngx_delete_file_n " \"%s\" failed", c->name);
                    397:         }
                    398:     }
                    399: 
                    400:     if (ngx_close_file(c->fd) == NGX_FILE_ERROR) {
                    401:         ngx_log_error(NGX_LOG_ALERT, c->log, ngx_errno,
                    402:                       ngx_close_file_n " \"%s\" failed", c->name);
                    403:     }
                    404: }
                    405: 
                    406: 
                    407: #if 0
                    408: 
                    409: static void *
                    410: ngx_get_cached_block(size_t size)
                    411: {
                    412:     void                     *p;
                    413:     ngx_cached_block_slot_t  *slot;
                    414: 
                    415:     if (ngx_cycle->cache == NULL) {
                    416:         return NULL;
                    417:     }
                    418: 
                    419:     slot = &ngx_cycle->cache[(size + ngx_pagesize - 1) / ngx_pagesize];
                    420: 
                    421:     slot->tries++;
                    422: 
                    423:     if (slot->number) {
                    424:         p = slot->block;
                    425:         slot->block = slot->block->next;
                    426:         slot->number--;
                    427:         return p;
                    428:     }
                    429: 
                    430:     return NULL;
                    431: }
                    432: 
                    433: #endif

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>