3 * Copyright (C) Igor Sysoev
4 * Copyright (C) Nginx, Inc.
8 #include <ngx_config.h>
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
);
17 ngx_create_pool(size_t size
, ngx_log_t
*log
)
21 p
= ngx_memalign(NGX_POOL_ALIGNMENT
, size
, log
);
26 p
->d
.last
= (u_char
*) p
+ sizeof(ngx_pool_t
);
27 p
->d
.end
= (u_char
*) p
+ size
;
31 size
= size
- sizeof(ngx_pool_t
);
32 p
->max
= (size
< NGX_MAX_ALLOC_FROM_POOL
) ? size
: NGX_MAX_ALLOC_FROM_POOL
;
45 ngx_destroy_pool(ngx_pool_t
*pool
)
49 ngx_pool_cleanup_t
*c
;
51 for (c
= pool
->cleanup
; c
; c
= c
->next
) {
53 ngx_log_debug1(NGX_LOG_DEBUG_ALLOC
, pool
->log
, 0,
54 "run cleanup: %p", c
);
59 for (l
= pool
->large
; l
; l
= l
->next
) {
61 ngx_log_debug1(NGX_LOG_DEBUG_ALLOC
, pool
->log
, 0, "free: %p", l
->alloc
);
71 * we could allocate the pool->log from this pool
72 * so we cannot use this log while free()ing the pool
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
);
86 for (p
= pool
, n
= pool
->d
.next
; /* void */; p
= n
, n
= n
->d
.next
) {
97 ngx_reset_pool(ngx_pool_t
*pool
)
102 for (l
= pool
->large
; l
; l
= l
->next
) {
110 for (p
= pool
; p
; p
= p
->d
.next
) {
111 p
->d
.last
= (u_char
*) p
+ sizeof(ngx_pool_t
);
117 ngx_palloc(ngx_pool_t
*pool
, size_t size
)
122 if (size
<= pool
->max
) {
127 m
= ngx_align_ptr(p
->d
.last
, NGX_ALIGNMENT
);
129 if ((size_t) (p
->d
.end
- m
) >= size
) {
130 p
->d
.last
= m
+ size
;
139 return ngx_palloc_block(pool
, size
);
142 return ngx_palloc_large(pool
, size
);
147 ngx_pnalloc(ngx_pool_t
*pool
, size_t size
)
152 if (size
<= pool
->max
) {
159 if ((size_t) (p
->d
.end
- m
) >= size
) {
160 p
->d
.last
= m
+ size
;
169 return ngx_palloc_block(pool
, size
);
172 return ngx_palloc_large(pool
, size
);
177 ngx_palloc_block(ngx_pool_t
*pool
, size_t size
)
181 ngx_pool_t
*p
, *new, *current
;
183 psize
= (size_t) (pool
->d
.end
- (u_char
*) pool
);
185 m
= ngx_memalign(NGX_POOL_ALIGNMENT
, psize
, pool
->log
);
190 new = (ngx_pool_t
*) m
;
192 new->d
.end
= m
+ psize
;
196 m
+= sizeof(ngx_pool_data_t
);
197 m
= ngx_align_ptr(m
, NGX_ALIGNMENT
);
198 new->d
.last
= m
+ size
;
200 current
= pool
->current
;
202 for (p
= current
; p
->d
.next
; p
= p
->d
.next
) {
203 if (p
->d
.failed
++ > 4) {
210 pool
->current
= current
? current
: new;
217 ngx_palloc_large(ngx_pool_t
*pool
, size_t size
)
221 ngx_pool_large_t
*large
;
223 p
= ngx_alloc(size
, pool
->log
);
230 for (large
= pool
->large
; large
; large
= large
->next
) {
231 if (large
->alloc
== NULL
) {
241 large
= ngx_palloc(pool
, sizeof(ngx_pool_large_t
));
248 large
->next
= pool
->large
;
256 ngx_pmemalign(ngx_pool_t
*pool
, size_t size
, size_t alignment
)
259 ngx_pool_large_t
*large
;
261 p
= ngx_memalign(alignment
, size
, pool
->log
);
266 large
= ngx_palloc(pool
, sizeof(ngx_pool_large_t
));
273 large
->next
= pool
->large
;
281 ngx_pfree(ngx_pool_t
*pool
, void *p
)
285 for (l
= pool
->large
; l
; l
= l
->next
) {
287 ngx_log_debug1(NGX_LOG_DEBUG_ALLOC
, pool
->log
, 0,
288 "free: %p", l
->alloc
);
301 ngx_pcalloc(ngx_pool_t
*pool
, size_t size
)
305 p
= ngx_palloc(pool
, size
);
307 ngx_memzero(p
, size
);
315 ngx_pool_cleanup_add(ngx_pool_t
*p
, size_t size
)
317 ngx_pool_cleanup_t
*c
;
319 c
= ngx_palloc(p
, sizeof(ngx_pool_cleanup_t
));
325 c
->data
= ngx_palloc(p
, size
);
326 if (c
->data
== NULL
) {
335 c
->next
= p
->cleanup
;
339 ngx_log_debug1(NGX_LOG_DEBUG_ALLOC
, p
->log
, 0, "add cleanup: %p", c
);
346 ngx_pool_run_cleanup_file(ngx_pool_t
*p
, ngx_fd_t fd
)
348 ngx_pool_cleanup_t
*c
;
349 ngx_pool_cleanup_file_t
*cf
;
351 for (c
= p
->cleanup
; c
; c
= c
->next
) {
352 if (c
->handler
== ngx_pool_cleanup_file
) {
367 ngx_pool_cleanup_file(void *data
)
369 ngx_pool_cleanup_file_t
*c
= data
;
371 ngx_log_debug1(NGX_LOG_DEBUG_ALLOC
, c
->log
, 0, "file cleanup: fd:%d",
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
);
382 ngx_pool_delete_file(void *data
)
384 ngx_pool_cleanup_file_t
*c
= data
;
388 ngx_log_debug2(NGX_LOG_DEBUG_ALLOC
, c
->log
, 0, "file cleanup: fd:%d %s",
391 if (ngx_delete_file(c
->name
) == NGX_FILE_ERROR
) {
394 if (err
!= NGX_ENOENT
) {
395 ngx_log_error(NGX_LOG_CRIT
, c
->log
, err
,
396 ngx_delete_file_n
" \"%s\" failed", c
->name
);
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
);
410 ngx_get_cached_block(size_t size
)
413 ngx_cached_block_slot_t
*slot
;
415 if (ngx_cycle
->cache
== NULL
) {
419 slot
= &ngx_cycle
->cache
[(size
+ ngx_pagesize
- 1) / ngx_pagesize
];
425 slot
->block
= slot
->block
->next
;