xref: /unit/src/nxt_buf_pool.c (revision 1349:d9bdbfc22a6e)
1 
2 /*
3  * Copyright (C) Igor Sysoev
4  * Copyright (C) NGINX, Inc.
5  */
6 
7 #include <nxt_main.h>
8 
9 
10 nxt_int_t
nxt_buf_pool_mem_alloc(nxt_buf_pool_t * bp,size_t size)11 nxt_buf_pool_mem_alloc(nxt_buf_pool_t *bp, size_t size)
12 {
13     nxt_buf_t  *b;
14 
15     b = bp->current;
16 
17     if (b != NULL && b->mem.free < b->mem.end) {
18         return NXT_OK;
19     }
20 
21     b = bp->free;
22 
23     if (b != NULL) {
24         bp->current = b;
25         bp->free = b->next;
26         b->next = NULL;
27         return NXT_OK;
28     }
29 
30     if (bp->num >= bp->max) {
31         return NXT_AGAIN;
32     }
33 
34     if (size == 0 || size >= bp->size + bp->size / 4) {
35         size = bp->size;
36     }
37 
38     b = nxt_buf_mem_alloc(bp->mem_pool, size, bp->flags);
39 
40     if (nxt_fast_path(b != NULL)) {
41         bp->current = b;
42         bp->num++;
43         return NXT_OK;
44     }
45 
46     return NXT_ERROR;
47 }
48 
49 
50 nxt_int_t
nxt_buf_pool_file_alloc(nxt_buf_pool_t * bp,size_t size)51 nxt_buf_pool_file_alloc(nxt_buf_pool_t *bp, size_t size)
52 {
53     nxt_buf_t  *b;
54 
55     b = bp->current;
56 
57     if (b != NULL && b->mem.free < b->mem.end) {
58         return NXT_OK;
59     }
60 
61     b = bp->free;
62 
63     if (b != NULL) {
64         bp->current = b;
65         bp->free = b->next;
66         b->next = NULL;
67         return NXT_OK;
68     }
69 
70     if (bp->num >= bp->max) {
71         return NXT_AGAIN;
72     }
73 
74     if (size == 0 || size >= bp->size + bp->size / 4) {
75         size = bp->size;
76     }
77 
78     b = nxt_buf_file_alloc(bp->mem_pool, size, bp->flags);
79 
80     if (nxt_fast_path(b != NULL)) {
81         bp->current = b;
82         bp->num++;
83         return NXT_OK;
84     }
85 
86     return NXT_ERROR;
87 }
88 
89 
90 nxt_int_t
nxt_buf_pool_mmap_alloc(nxt_buf_pool_t * bp,size_t size)91 nxt_buf_pool_mmap_alloc(nxt_buf_pool_t *bp, size_t size)
92 {
93     nxt_buf_t  *b;
94 
95     b = bp->current;
96 
97     if (b != NULL) {
98         return NXT_OK;
99     }
100 
101     b = bp->free;
102 
103     if (b != NULL) {
104         bp->current = b;
105         bp->free = b->next;
106         b->next = NULL;
107         return NXT_OK;
108     }
109 
110     if (bp->num >= bp->max) {
111         return NXT_AGAIN;
112     }
113 
114     if (size == 0 || size >= bp->size + bp->size / 4) {
115         size = bp->size;
116     }
117 
118     b = nxt_buf_mmap_alloc(bp->mem_pool, size);
119 
120     if (nxt_fast_path(b != NULL)) {
121         bp->mmap = 1;
122         bp->current = b;
123         bp->num++;
124         return NXT_OK;
125     }
126 
127     return NXT_ERROR;
128 }
129 
130 
131 void
nxt_buf_pool_free(nxt_buf_pool_t * bp,nxt_buf_t * b)132 nxt_buf_pool_free(nxt_buf_pool_t *bp, nxt_buf_t *b)
133 {
134     size_t  size;
135 
136     nxt_thread_log_debug("buf pool free: %p %p", b, b->mem.start);
137 
138     size = nxt_buf_mem_size(&b->mem);
139 
140     if (bp->mmap) {
141         nxt_mem_unmap(b->mem.start, &b->mmap, size);
142     }
143 
144     if (bp->destroy) {
145 
146         if (b == bp->current) {
147             bp->current = NULL;
148         }
149 
150         nxt_buf_free(bp->mem_pool, b);
151 
152         return;
153     }
154 
155     if (bp->mmap) {
156         b->mem.pos = NULL;
157         b->mem.free = NULL;
158         nxt_buf_mem_set_size(&b->mem, size);
159 
160     } else {
161         b->mem.pos = b->mem.start;
162         b->mem.free = b->mem.start;
163     }
164 
165     if (b != bp->current) {
166         b->next = bp->free;
167         bp->free = b;
168     }
169 }
170 
171 
172 void
nxt_buf_pool_destroy(nxt_buf_pool_t * bp)173 nxt_buf_pool_destroy(nxt_buf_pool_t *bp)
174 {
175     nxt_buf_t  *b, *n;
176 
177     bp->destroy = 1;
178 
179     for (b = bp->free; b != NULL; b = n) {
180         n = b->next;
181         nxt_buf_free(bp->mem_pool, b);
182     }
183 
184     bp->free = b; /* NULL */
185 }
186