~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Linux Cross Reference
Nginx/core/ngx_palloc.c

Version: ~ [ nginx-0.8.20 ] ~ [ nginx-0.7.62 ] ~ [ nginx-0.6.39 ] ~

  1 
  2 /*
  3  * Copyright (C) Igor Sysoev
  4  */
  5 
  6 
  7 #include <ngx_config.h>
  8 #include <ngx_core.h>
  9 
 10 
 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);
 13 
 14 
 15 ngx_pool_t *
 16 ngx_create_pool(size_t size, ngx_log_t *log)
 17 {
 18     ngx_pool_t  *p;
 19 
 20     p = ngx_memalign(ngx_pagesize, size, log);
 21     if (p == NULL) {
 22         return NULL;
 23     }
 24 
 25     p->d.last = (u_char *) p + sizeof(ngx_pool_t);
 26     p->d.end = (u_char *) p + size;
 27     p->d.next = NULL;
 28     p->d.failed = 0;
 29 
 30     size = size - sizeof(ngx_pool_t);
 31     p->max = (size < NGX_MAX_ALLOC_FROM_POOL) ? size : NGX_MAX_ALLOC_FROM_POOL;
 32 
 33     p->current = p;
 34     p->chain = NULL;
 35     p->large = NULL;
 36     p->cleanup = NULL;
 37     p->log = log;
 38 
 39     return p;
 40 }
 41 
 42 
 43 void
 44 ngx_destroy_pool(ngx_pool_t *pool)
 45 {
 46     ngx_pool_t          *p, *n;
 47     ngx_pool_large_t    *l;
 48     ngx_pool_cleanup_t  *c;
 49 
 50     for (c = pool->cleanup; c; c = c->next) {
 51         if (c->handler) {
 52             ngx_log_debug1(NGX_LOG_DEBUG_ALLOC, pool->log, 0,
 53                            "run cleanup: %p", c);
 54             c->handler(c->data);
 55         }
 56     }
 57 
 58     for (l = pool->large; l; l = l->next) {
 59 
 60         ngx_log_debug1(NGX_LOG_DEBUG_ALLOC, pool->log, 0, "free: %p", l->alloc);
 61 
 62         if (l->alloc) {
 63             ngx_free(l->alloc);
 64         }
 65     }
 66 
 67 #if (NGX_DEBUG)
 68 
 69     /*
 70      * we could allocate the pool->log from this pool
 71      * so we can not use this log while the free()ing the pool
 72      */
 73 
 74     for (p = pool, n = pool->d.next; /* void */; p = n, n = n->d.next) {
 75         ngx_log_debug2(NGX_LOG_DEBUG_ALLOC, pool->log, 0,
 76                        "free: %p, unused: %uz", p, p->d.end - p->d.last);
 77 
 78         if (n == NULL) {
 79             break;
 80         }
 81     }
 82 
 83 #endif
 84 
 85     for (p = pool, n = pool->d.next; /* void */; p = n, n = n->d.next) {
 86         ngx_free(p);
 87 
 88         if (n == NULL) {
 89             break;
 90         }
 91     }
 92 }
 93 
 94 
 95 void
 96 ngx_reset_pool(ngx_pool_t *pool)
 97 {
 98     ngx_pool_t        *p;
 99     ngx_pool_large_t  *l;
100 
101     for (l = pool->large; l; l = l->next) {
102         if (l->alloc) {
103             ngx_free(l->alloc);
104         }
105     }
106 
107     pool->large = NULL;
108 
109     for (p = pool; p; p = p->d.next) {
110         p->d.last = (u_char *) p + sizeof(ngx_pool_t);
111     }
112 }
113 
114 
115 void *
116 ngx_palloc(ngx_pool_t *pool, size_t size)
117 {
118     u_char      *m;
119     ngx_pool_t  *p;
120 
121     if (size <= pool->max) {
122 
123         p = pool->current;
124 
125         do {
126             m = ngx_align_ptr(p->d.last, NGX_ALIGNMENT);
127 
128             if ((size_t) (p->d.end - m) >= size) {
129                 p->d.last = m + size;
130 
131                 return m;
132             }
133 
134             p = p->d.next;
135 
136         } while (p);
137 
138         return ngx_palloc_block(pool, size);
139     }
140 
141     return ngx_palloc_large(pool, size);
142 }
143 
144 
145 void *
146 ngx_pnalloc(ngx_pool_t *pool, size_t size)
147 {
148     u_char      *m;
149     ngx_pool_t  *p;
150 
151     if (size <= pool->max) {
152 
153         p = pool->current;
154 
155         do {
156             m = p->d.last;
157 
158             if ((size_t) (p->d.end - m) >= size) {
159                 p->d.last = m + size;
160 
161                 return m;
162             }
163 
164             p = p->d.next;
165 
166         } while (p);
167 
168         return ngx_palloc_block(pool, size);
169     }
170 
171     return ngx_palloc_large(pool, size);
172 }
173 
174 
175 static void *
176 ngx_palloc_block(ngx_pool_t *pool, size_t size)
177 {
178     u_char      *m;
179     size_t       psize;
180     ngx_pool_t  *p, *new, *current;
181 
182     psize = (size_t) (pool->d.end - (u_char *) pool);
183 
184     m = ngx_memalign(ngx_pagesize, psize, pool->log);
185     if (m == NULL) {
186         return NULL;
187     }
188 
189     new = (ngx_pool_t *) m;
190 
191     new->d.end = m + psize;
192     new->d.next = NULL;
193     new->d.failed = 0;
194 
195     m += sizeof(ngx_pool_data_t);
196     m = ngx_align_ptr(m, NGX_ALIGNMENT);
197     new->d.last = m + size;
198 
199     current = pool->current;
200 
201     for (p = current; p->d.next; p = p->d.next) {
202         if (p->d.failed++ > 4) {
203             current = p->d.next;
204         }
205     }
206 
207     p->d.next = new;
208 
209     pool->current = current ? current : new;
210 
211     return m;
212 }
213 
214 
215 static void *
216 ngx_palloc_large(ngx_pool_t *pool, size_t size)
217 {
218     void              *p;
219     ngx_uint_t         n;
220     ngx_pool_large_t  *large;
221 
222     p = ngx_memalign(ngx_pagesize, size, pool->log);
223     if (p == NULL) {
224         return NULL;
225     }
226 
227     n = 0;
228 
229     for (large = pool->large; large; large = large->next) {
230         if (large->alloc == NULL) {
231             large->alloc = p;
232             return p;
233         }
234 
235         if (n++ > 3) {
236             break;
237         }
238     }
239 
240     large = ngx_palloc(pool, sizeof(ngx_pool_large_t));
241     if (large == NULL) {
242         ngx_free(p);
243         return NULL;
244     }
245 
246     large->alloc = p;
247     large->next = pool->large;
248     pool->large = large;
249 
250     return p;
251 }
252 
253 
254 void *
255 ngx_pmemalign(ngx_pool_t *pool, size_t size, size_t alignment)
256 {
257     void              *p;
258     ngx_pool_large_t  *large;
259 
260     p = ngx_memalign(alignment, size, pool->log);
261     if (p == NULL) {
262         return NULL;
263     }
264 
265     large = ngx_palloc(pool, sizeof(ngx_pool_large_t));
266     if (large == NULL) {
267         ngx_free(p);
268         return NULL;
269     }
270 
271     large->alloc = p;
272     large->next = pool->large;
273     pool->large = large;
274 
275     return p;
276 }
277 
278 
279 ngx_int_t
280 ngx_pfree(ngx_pool_t *pool, void *p)
281 {
282     ngx_pool_large_t  *l;
283 
284     for (l = pool->large; l; l = l->next) {
285         if (p == l->alloc) {
286             ngx_log_debug1(NGX_LOG_DEBUG_ALLOC, pool->log, 0,
287                            "free: %p", l->alloc);
288             ngx_free(l->alloc);
289             l->alloc = NULL;
290 
291             return NGX_OK;
292         }
293     }
294 
295     return NGX_DECLINED;
296 }
297 
298 
299 void *
300 ngx_pcalloc(ngx_pool_t *pool, size_t size)
301 {
302     void *p;
303 
304     p = ngx_palloc(pool, size);
305     if (p) {
306         ngx_memzero(p, size);
307     }
308 
309     return p;
310 }
311 
312 
313 ngx_pool_cleanup_t *
314 ngx_pool_cleanup_add(ngx_pool_t *p, size_t size)
315 {
316     ngx_pool_cleanup_t  *c;
317 
318     c = ngx_palloc(p, sizeof(ngx_pool_cleanup_t));
319     if (c == NULL) {
320         return NULL;
321     }
322 
323     if (size) {
324         c->data = ngx_palloc(p, size);
325         if (c->data == NULL) {
326             return NULL;
327         }
328 
329     } else {
330         c->data = NULL;
331     }
332 
333     c->handler = NULL;
334     c->next = p->cleanup;
335 
336     p->cleanup = c;
337 
338     ngx_log_debug1(NGX_LOG_DEBUG_ALLOC, p->log, 0, "add cleanup: %p", c);
339 
340     return c;
341 }
342 
343 
344 void
345 ngx_pool_run_cleanup_file(ngx_pool_t *p, ngx_fd_t fd)
346 {
347     ngx_pool_cleanup_t       *c;
348     ngx_pool_cleanup_file_t  *cf;
349 
350     for (c = p->cleanup; c; c = c->next) {
351         if (c->handler == ngx_pool_cleanup_file) {
352 
353             cf = c->data;
354 
355             if (cf->fd == fd) {
356                 c->handler(cf);
357                 c->handler = NULL;
358                 return;
359             }
360         }
361     }
362 }
363 
364 
365 void
366 ngx_pool_cleanup_file(void *data)
367 {
368     ngx_pool_cleanup_file_t  *c = data;
369 
370     ngx_log_debug1(NGX_LOG_DEBUG_ALLOC, c->log, 0, "file cleanup: fd:%d",
371                    c->fd);
372 
373     if (ngx_close_file(c->fd) == NGX_FILE_ERROR) {
374         ngx_log_error(NGX_LOG_ALERT, c->log, ngx_errno,
375                       ngx_close_file_n " \"%s\" failed", c->name);
376     }
377 }
378 
379 
380 void
381 ngx_pool_delete_file(void *data)
382 {
383     ngx_pool_cleanup_file_t  *c = data;
384 
385     ngx_err_t  err;
386 
387     ngx_log_debug2(NGX_LOG_DEBUG_ALLOC, c->log, 0, "file cleanup: fd:%d %s",
388                    c->fd, c->name);
389 
390     if (ngx_delete_file(c->name) == NGX_FILE_ERROR) {
391         err = ngx_errno;
392 
393         if (err != NGX_ENOENT) {
394             ngx_log_error(NGX_LOG_CRIT, c->log, err,
395                           ngx_delete_file_n " \"%s\" failed", c->name);
396         }
397     }
398 
399     if (ngx_close_file(c->fd) == NGX_FILE_ERROR) {
400         ngx_log_error(NGX_LOG_ALERT, c->log, ngx_errno,
401                       ngx_close_file_n " \"%s\" failed", c->name);
402     }
403 }
404 
405 
406 #if 0
407 
408 static void *
409 ngx_get_cached_block(size_t size)
410 {
411     void                     *p;
412     ngx_cached_block_slot_t  *slot;
413 
414     if (ngx_cycle->cache == NULL) {
415         return NULL;
416     }
417 
418     slot = &ngx_cycle->cache[(size + ngx_pagesize - 1) / ngx_pagesize];
419 
420     slot->tries++;
421 
422     if (slot->number) {
423         p = slot->block;
424         slot->block = slot->block->next;
425         slot->number--;
426         return p;
427     }
428 
429     return NULL;
430 }
431 
432 #endif
433 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.