xref: /unit/src/nxt_buf_pool.c (revision 0:a63ceefd6ab0)
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
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
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
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
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         if (!bp->mmap) {
151             nxt_mem_free(bp->mem_pool, b->mem.start);
152         }
153 
154         nxt_buf_free(bp->mem_pool, b);
155 
156         return;
157     }
158 
159     if (bp->mmap) {
160         b->mem.pos = NULL;
161         b->mem.free = NULL;
162         nxt_buf_mem_set_size(&b->mem, size);
163 
164     } else {
165         b->mem.pos = b->mem.start;
166         b->mem.free = b->mem.start;
167     }
168 
169     if (b != bp->current) {
170         b->next = bp->free;
171         bp->free = b;
172     }
173 }
174 
175 
176 void
177 nxt_buf_pool_destroy(nxt_buf_pool_t *bp)
178 {
179     u_char     *p;
180     nxt_buf_t  *b;
181 
182     bp->destroy = 1;
183 
184     for (b = bp->free; b != NULL; b = b->next) {
185         p = b->mem.start;
186         nxt_buf_free(bp->mem_pool, b);
187         nxt_mem_free(bp->mem_pool, p);
188     }
189 
190     bp->free = b; /* NULL */
191 }
192