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>