3 * Copyright (C) Igor Sysoev
7 #include <ngx_config.h>
11 static void *ngx_palloc_block(ngx_pool_t *pool, size_t size);
12 static void *ngx_palloc_large(ngx_pool_t *pool, size_t size);
16 ngx_create_pool(size_t size, ngx_log_t *log)
20 p = ngx_alloc(size, log);
25 p->d.last = (u_char *) p + sizeof(ngx_pool_t);
26 p->d.end = (u_char *) p + size;
29 size = size - sizeof(ngx_pool_t);
30 p->max = (size < NGX_MAX_ALLOC_FROM_POOL) ? size : NGX_MAX_ALLOC_FROM_POOL;
43 ngx_destroy_pool(ngx_pool_t *pool)
47 ngx_pool_cleanup_t *c;
49 for (c = pool->cleanup; c; c = c->next) {
51 ngx_log_debug1(NGX_LOG_DEBUG_ALLOC, pool->log, 0,
52 "run cleanup: %p", c);
57 for (l = pool->large; l; l = l->next) {
59 ngx_log_debug1(NGX_LOG_DEBUG_ALLOC, pool->log, 0, "free: %p", l->alloc);
69 * we could allocate the pool->log from this pool
70 * so we can not use this log while the free()ing the pool
73 for (p = pool, n = pool->d.next; /* void */; p = n, n = n->d.next) {
74 ngx_log_debug2(NGX_LOG_DEBUG_ALLOC, pool->log, 0,
75 "free: %p, unused: %uz", p, p->d.end - p->d.last);
84 for (p = pool, n = pool->d.next; /* void */; p = n, n = n->d.next) {
95 ngx_reset_pool(ngx_pool_t *pool)
100 for (l = pool->large; l; l = l->next) {
108 for (p = pool; p; p = p->d.next) {
109 p->d.last = (u_char *) p + sizeof(ngx_pool_t);
115 ngx_palloc(ngx_pool_t *pool, size_t size)
120 if (size <= pool->max) {
125 m = ngx_align_ptr(p->d.last, NGX_ALIGNMENT);
127 if ((size_t) (p->d.end - m) >= size) {
128 p->d.last = m + size;
137 return ngx_palloc_block(pool, size);
140 return ngx_palloc_large(pool, size);
145 ngx_pnalloc(ngx_pool_t *pool, size_t size)
150 if (size <= pool->max) {
157 if ((size_t) (p->d.end - m) >= size) {
158 p->d.last = m + size;
167 return ngx_palloc_block(pool, size);
170 return ngx_palloc_large(pool, size);
175 ngx_palloc_block(ngx_pool_t *pool, size_t size)
179 ngx_pool_t *p, *new, *current;
181 psize = (size_t) (pool->d.end - (u_char *) pool);
183 m = ngx_alloc(psize, pool->log);
188 new = (ngx_pool_t *) m;
190 new->d.end = m + psize;
193 m += sizeof(ngx_pool_data_t);
194 m = ngx_align_ptr(m, NGX_ALIGNMENT);
195 new->d.last = m + size;
197 current = pool->current;
199 for (p = current; p->d.next; p = p->d.next) {
200 if ((size_t) (p->d.end - p->d.last) < NGX_ALIGNMENT) {
207 pool->current = current ? current : new;
214 ngx_palloc_large(ngx_pool_t *pool, size_t size)
217 ngx_pool_large_t *large;
219 p = ngx_alloc(size, pool->log);
224 large = ngx_palloc(pool, sizeof(ngx_pool_large_t));
231 large->next = pool->large;
239 ngx_pmemalign(ngx_pool_t *pool, size_t size, size_t alignment)
242 ngx_pool_large_t *large;
244 p = ngx_memalign(alignment, size, pool->log);
249 large = ngx_palloc(pool, sizeof(ngx_pool_large_t));
256 large->next = pool->large;
264 ngx_pfree(ngx_pool_t *pool, void *p)
268 for (l = pool->large; l; l = l->next) {
270 ngx_log_debug1(NGX_LOG_DEBUG_ALLOC, pool->log, 0,
271 "free: %p", l->alloc);
284 ngx_pcalloc(ngx_pool_t *pool, size_t size)
288 p = ngx_palloc(pool, size);
290 ngx_memzero(p, size);
298 ngx_pool_cleanup_add(ngx_pool_t *p, size_t size)
300 ngx_pool_cleanup_t *c;
302 c = ngx_palloc(p, sizeof(ngx_pool_cleanup_t));
308 c->data = ngx_palloc(p, size);
309 if (c->data == NULL) {
318 c->next = p->cleanup;
322 ngx_log_debug1(NGX_LOG_DEBUG_ALLOC, p->log, 0, "add cleanup: %p", c);
329 ngx_pool_cleanup_file(void *data)
331 ngx_pool_cleanup_file_t *c = data;
333 ngx_log_debug1(NGX_LOG_DEBUG_ALLOC, c->log, 0, "file cleanup: fd:%d",
336 if (ngx_close_file(c->fd) == NGX_FILE_ERROR) {
337 ngx_log_error(NGX_LOG_ALERT, c->log, ngx_errno,
338 ngx_close_file_n " \"%s\" failed", c->name);
344 ngx_pool_delete_file(void *data)
346 ngx_pool_cleanup_file_t *c = data;
350 ngx_log_debug2(NGX_LOG_DEBUG_ALLOC, c->log, 0, "file cleanup: fd:%d %s",
353 if (ngx_delete_file(c->name) == NGX_FILE_ERROR) {
356 if (err != NGX_ENOENT) {
357 ngx_log_error(NGX_LOG_CRIT, c->log, err,
358 ngx_delete_file_n " \"%s\" failed", c->name);
362 if (ngx_close_file(c->fd) == NGX_FILE_ERROR) {
363 ngx_log_error(NGX_LOG_ALERT, c->log, ngx_errno,
364 ngx_close_file_n " \"%s\" failed", c->name);
372 ngx_get_cached_block(size_t size)
375 ngx_cached_block_slot_t *slot;
377 if (ngx_cycle->cache == NULL) {
381 slot = &ngx_cycle->cache[(size + ngx_pagesize - 1) / ngx_pagesize];
387 slot->block = slot->block->next;