Annotation of embedaddon/nginx/src/core/ngx_palloc.c, revision 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>