3 * Copyright (C) Igor Sysoev
4 * Copyright (C) Nginx, Inc.
8 #include <ngx_config.h>
12 static ngx_inline void *ngx_palloc_small(ngx_pool_t *pool, size_t size,
14 static void *ngx_palloc_block(ngx_pool_t *pool, size_t size);
15 static void *ngx_palloc_large(ngx_pool_t *pool, size_t size);
19 ngx_create_pool(size_t size, ngx_log_t *log)
23 p = ngx_memalign(NGX_POOL_ALIGNMENT, size, log);
28 p->d.last = (u_char *) p + sizeof(ngx_pool_t);
29 p->d.end = (u_char *) p + size;
33 size = size - sizeof(ngx_pool_t);
34 p->max = (size < NGX_MAX_ALLOC_FROM_POOL) ? size : NGX_MAX_ALLOC_FROM_POOL;
47 ngx_destroy_pool(ngx_pool_t *pool)
51 ngx_pool_cleanup_t *c;
53 for (c = pool->cleanup; c; c = c->next) {
55 ngx_log_debug1(NGX_LOG_DEBUG_ALLOC, pool->log, 0,
56 "run cleanup: %p", c);
64 * we could allocate the pool->log from this pool
65 * so we cannot use this log while free()ing the pool
68 for (l = pool->large; l; l = l->next) {
69 ngx_log_debug1(NGX_LOG_DEBUG_ALLOC, pool->log, 0, "free: %p", l->alloc);
72 for (p = pool, n = pool->d.next; /* void */; p = n, n = n->d.next) {
73 ngx_log_debug2(NGX_LOG_DEBUG_ALLOC, pool->log, 0,
74 "free: %p, unused: %uz", p, p->d.end - p->d.last);
83 for (l = pool->large; l; l = l->next) {
89 for (p = pool, n = pool->d.next; /* void */; p = n, n = n->d.next) {
100 ngx_reset_pool(ngx_pool_t *pool)
105 for (l = pool->large; l; l = l->next) {
111 for (p = pool; p; p = p->d.next) {
112 p->d.last = (u_char *) p + sizeof(ngx_pool_t);
116 pool->current = pool;
123 ngx_palloc(ngx_pool_t *pool, size_t size)
125 #if !(NGX_DEBUG_PALLOC)
126 if (size <= pool->max) {
127 return ngx_palloc_small(pool, size, 1);
131 return ngx_palloc_large(pool, size);
136 ngx_pnalloc(ngx_pool_t *pool, size_t size)
138 #if !(NGX_DEBUG_PALLOC)
139 if (size <= pool->max) {
140 return ngx_palloc_small(pool, size, 0);
144 return ngx_palloc_large(pool, size);
148 static ngx_inline void *
149 ngx_palloc_small(ngx_pool_t *pool, size_t size, ngx_uint_t align)
160 m = ngx_align_ptr(m, NGX_ALIGNMENT);
163 if ((size_t) (p->d.end - m) >= size) {
164 p->d.last = m + size;
173 return ngx_palloc_block(pool, size);
178 ngx_palloc_block(ngx_pool_t *pool, size_t size)
184 psize = (size_t) (pool->d.end - (u_char *) pool);
186 m = ngx_memalign(NGX_POOL_ALIGNMENT, psize, pool->log);
191 new = (ngx_pool_t *) m;
193 new->d.end = m + psize;
197 m += sizeof(ngx_pool_data_t);
198 m = ngx_align_ptr(m, NGX_ALIGNMENT);
199 new->d.last = m + size;
201 for (p = pool->current; p->d.next; p = p->d.next) {
202 if (p->d.failed++ > 4) {
203 pool->current = p->d.next;
214 ngx_palloc_large(ngx_pool_t *pool, size_t size)
218 ngx_pool_large_t *large;
220 p = ngx_alloc(size, pool->log);
227 for (large = pool->large; large; large = large->next) {
228 if (large->alloc == NULL) {
238 large = ngx_palloc_small(pool, sizeof(ngx_pool_large_t), 1);
245 large->next = pool->large;
253 ngx_pmemalign(ngx_pool_t *pool, size_t size, size_t alignment)
256 ngx_pool_large_t *large;
258 p = ngx_memalign(alignment, size, pool->log);
263 large = ngx_palloc_small(pool, sizeof(ngx_pool_large_t), 1);
270 large->next = pool->large;
278 ngx_pfree(ngx_pool_t *pool, void *p)
282 for (l = pool->large; l; l = l->next) {
284 ngx_log_debug1(NGX_LOG_DEBUG_ALLOC, pool->log, 0,
285 "free: %p", l->alloc);
298 ngx_pcalloc(ngx_pool_t *pool, size_t size)
302 p = ngx_palloc(pool, size);
304 ngx_memzero(p, size);
312 ngx_pool_cleanup_add(ngx_pool_t *p, size_t size)
314 ngx_pool_cleanup_t *c;
316 c = ngx_palloc(p, sizeof(ngx_pool_cleanup_t));
322 c->data = ngx_palloc(p, size);
323 if (c->data == NULL) {
332 c->next = p->cleanup;
336 ngx_log_debug1(NGX_LOG_DEBUG_ALLOC, p->log, 0, "add cleanup: %p", c);
343 ngx_pool_run_cleanup_file(ngx_pool_t *p, ngx_fd_t fd)
345 ngx_pool_cleanup_t *c;
346 ngx_pool_cleanup_file_t *cf;
348 for (c = p->cleanup; c; c = c->next) {
349 if (c->handler == ngx_pool_cleanup_file) {
364 ngx_pool_cleanup_file(void *data)
366 ngx_pool_cleanup_file_t *c = data;
368 ngx_log_debug1(NGX_LOG_DEBUG_ALLOC, c->log, 0, "file cleanup: fd:%d",
371 if (ngx_close_file(c->fd) == NGX_FILE_ERROR) {
372 ngx_log_error(NGX_LOG_ALERT, c->log, ngx_errno,
373 ngx_close_file_n " \"%s\" failed", c->name);
379 ngx_pool_delete_file(void *data)
381 ngx_pool_cleanup_file_t *c = data;
385 ngx_log_debug2(NGX_LOG_DEBUG_ALLOC, c->log, 0, "file cleanup: fd:%d %s",
388 if (ngx_delete_file(c->name) == NGX_FILE_ERROR) {
391 if (err != NGX_ENOENT) {
392 ngx_log_error(NGX_LOG_CRIT, c->log, err,
393 ngx_delete_file_n " \"%s\" failed", c->name);
397 if (ngx_close_file(c->fd) == NGX_FILE_ERROR) {
398 ngx_log_error(NGX_LOG_ALERT, c->log, ngx_errno,
399 ngx_close_file_n " \"%s\" failed", c->name);
407 ngx_get_cached_block(size_t size)
410 ngx_cached_block_slot_t *slot;
412 if (ngx_cycle->cache == NULL) {
416 slot = &ngx_cycle->cache[(size + ngx_pagesize - 1) / ngx_pagesize];
422 slot->block = slot->block->next;