Groonga 3.0.9 Source Code Document
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
ngx_palloc.c
Go to the documentation of this file.
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);
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
46 {
47  ngx_pool_t *p, *n;
50 
51  for (c = pool->cleanup; c; c = c->next) {
52  if (c->handler) {
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) {
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
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 {
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);
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) {
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 
316 {
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
347 {
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
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) {
376  ngx_close_file_n " \"%s\" failed", c->name);
377  }
378 }
379 
380 
381 void
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) {
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