xref: /unit/src/nxt_buf.h (revision 122:d18727e877c6)
1 
2 /*
3  * Copyright (C) Igor Sysoev
4  * Copyright (C) NGINX, Inc.
5  */
6 
7 #ifndef _NXT_BUF_H_INCLUDED_
8 #define _NXT_BUF_H_INCLUDED_
9 
10 
11 /*
12  * There are four types of buffers.  They are different sizes, so they
13  * should be allocated by appropriate nxt_buf_XXX_alloc() function.
14  *
15  * 1) Memory-only buffers, their size is less than nxt_buf_t size, it
16  *    is equal to offsetof(nxt_buf_t, file_pos), that is it is nxt_buf_t
17  *    without file and mmap part.  The buffers are frequently used, so
18  *    the reduction allows to save 20-32 bytes depending on platform.
19  *
20  * 2) Memory/file buffers, on Unix their size is exactly nxt_buf_t size,
21  *    since nxt_mem_map_file_ctx_t() is empty macro.  On Windows the size
22  *    equals offsetof(nxt_buf_t, mmap), that is it is nxt_buf_t without
23  *    memory map context part.  The buffers can contain both memory and
24  *    file pointers at once, or only memory or file pointers.
25  *
26  * 3) Memory mapped buffers are similar to the memory/file buffers.  Their
27  *    size is exactly nxt_buf_t size.  The buffers can contain both memory
28  *    and file pointers at once, or only memory or file pointers.  If a
29  *    buffer is not currently mapped in memory, its mapping size is stored
30  *    in the mem.end field and available via nxt_buf_mem_size() macro.
31  *
32  * 4) Sync buffers, their size is the same size as memory-only buffers
33  *    size.  A sync buffer can be smaller but for memory pool cache
34  *    purpose it is better to allocate it as frequently used memory-only
35  *    buffer.  The buffers are used to synchronize pipeline processing
36  *    completion, because data buffers in the pipeline can be completed
37  *    and freed before their final output will even be passed to a peer.
38  *    For this purpose a sync buffer is allocated with the stop flag which
39  *    stops buffer chain completion processing on the sync buffer in
40  *    nxt_sendbuf_update() and nxt_sendbuf_completion().
41  *    Clearing the stop flag allows to continue completion processing.
42  *
43  *    The last flag means the end of the output and must be set only
44  *    in a sync buffer.  The last flag is not permitted in memory and
45  *    file buffers since it requires special handling while conversion
46  *    one buffer to another.
47  *
48  *    The nxt_buf_used_size() macro treats a sync buffer as a memory-only
49  *    buffer which has NULL pointers, thus the buffer content size is zero.
50  *    If allocated size of sync buffer would be lesser than memory-only
51  *    buffer, then the special memory flag would be required because
52  *    currently presence of memory part is indicated by non-NULL pointer
53  *    to a content in memory.
54  *
55  *    All types of buffers can have the flush flag that means the buffer
56  *    should be sent as much as possible.
57  */
58 
59 typedef struct {
60     u_char                  *pos;
61     u_char                  *free;
62     u_char                  *start;
63     u_char                  *end;
64 } nxt_buf_mem_t;
65 
66 
67 struct nxt_buf_s {
68     void                    *data;
69     nxt_work_handler_t      completion_handler;
70     void                    *parent;
71 
72     /*
73      * The next link, flags, and nxt_buf_mem_t should
74      * reside together to improve cache locality.
75      */
76     nxt_buf_t               *next;
77 
78     uint32_t                retain;
79 
80     uint8_t                 is_file;     /* 1 bit */
81 
82     uint16_t                is_mmap:1;
83     uint16_t                is_port_mmap:1;
84 
85     uint16_t                is_sync:1;
86     uint16_t                is_nobuf:1;
87     uint16_t                is_flush:1;
88     uint16_t                is_last:1;
89     uint16_t                is_port_mmap_sent:1;
90     uint16_t                is_ts:1;
91 
92     nxt_buf_mem_t           mem;
93 
94     /* The file and mmap parts are not allocated by nxt_buf_mem_alloc(). */
95     nxt_file_t              *file;
96     nxt_off_t               file_pos;
97     nxt_off_t               file_end;
98 
99     /* The mmap part is not allocated by nxt_buf_file_alloc(). */
100     nxt_mem_map_file_ctx_t  (mmap)
101 };
102 
103 
104 #define NXT_BUF_MEM_SIZE        offsetof(nxt_buf_t, file)
105 #define NXT_BUF_SYNC_SIZE       NXT_BUF_MEM_SIZE
106 #define NXT_BUF_FILE_SIZE       sizeof(nxt_buf_t)
107 #define NXT_BUF_MMAP_SIZE       NXT_BUF_FILE_SIZE
108 #define NXT_BUF_PORT_MMAP_SIZE  NXT_BUF_MEM_SIZE
109 
110 
111 #define NXT_BUF_SYNC_NOBUF  1
112 #define NXT_BUF_SYNC_FLUSH  2
113 #define NXT_BUF_SYNC_LAST   4
114 
115 
116 #define                                                                       \
117 nxt_buf_is_mem(b)                                                             \
118     ((b)->mem.pos != NULL)
119 
120 
121 #define                                                                       \
122 nxt_buf_is_file(b)                                                            \
123     ((b)->is_file)
124 
125 #define                                                                       \
126 nxt_buf_set_file(b)                                                           \
127     (b)->is_file = 1
128 
129 #define                                                                       \
130 nxt_buf_clear_file(b)                                                         \
131     (b)->is_file = 0
132 
133 
134 #define                                                                       \
135 nxt_buf_is_mmap(b)                                                            \
136     ((b)->is_mmap)
137 
138 #define                                                                       \
139 nxt_buf_set_mmap(b)                                                           \
140     (b)->is_mmap = 1
141 
142 #define                                                                       \
143 nxt_buf_clear_mmap(b)                                                         \
144     (b)->is_mmap = 0
145 
146 
147 #define                                                                       \
148 nxt_buf_is_port_mmap(b)                                                       \
149     ((b)->is_port_mmap)
150 
151 #define                                                                       \
152 nxt_buf_set_port_mmap(b)                                                      \
153     (b)->is_port_mmap = 1
154 
155 #define                                                                       \
156 nxt_buf_clear_port_mmap(b)                                                    \
157     (b)->is_port_mmap = 0
158 
159 
160 #define                                                                       \
161 nxt_buf_is_sync(b)                                                            \
162     ((b)->is_sync)
163 
164 #define                                                                       \
165 nxt_buf_set_sync(b)                                                           \
166     (b)->is_sync = 1
167 
168 #define                                                                       \
169 nxt_buf_clear_sync(b)                                                         \
170     (b)->is_sync = 0
171 
172 
173 #define                                                                       \
174 nxt_buf_is_nobuf(b)                                                           \
175     ((b)->is_nobuf)
176 
177 #define                                                                       \
178 nxt_buf_set_nobuf(b)                                                          \
179     (b)->is_nobuf = 1
180 
181 #define                                                                       \
182 nxt_buf_clear_nobuf(b)                                                        \
183     (b)->is_nobuf = 0
184 
185 
186 #define                                                                       \
187 nxt_buf_is_flush(b)                                                           \
188     ((b)->is_flush)
189 
190 #define                                                                       \
191 nxt_buf_set_flush(b)                                                          \
192     (b)->is_flush = 1
193 
194 #define                                                                       \
195 nxt_buf_clear_flush(b)                                                        \
196     (b)->is_flush = 0
197 
198 
199 #define                                                                       \
200 nxt_buf_is_last(b)                                                            \
201     ((b)->is_last)
202 
203 #define                                                                       \
204 nxt_buf_set_last(b)                                                           \
205     (b)->is_last = 1
206 
207 #define                                                                       \
208 nxt_buf_clear_last(b)                                                         \
209    (b)->is_last = 0
210 
211 
212 #define                                                                       \
213 nxt_buf_mem_set_size(bm, size)                                                \
214     do {                                                                      \
215         (bm)->start = 0;                                                      \
216         (bm)->end = (void *) size;                                            \
217     } while (0)
218 
219 
220 #define                                                                       \
221 nxt_buf_mem_size(bm)                                                          \
222     ((bm)->end - (bm)->start)
223 
224 
225 #define                                                                       \
226 nxt_buf_mem_used_size(bm)                                                     \
227     ((bm)->free - (bm)->pos)
228 
229 
230 #define                                                                       \
231 nxt_buf_mem_free_size(bm)                                                     \
232     ((bm)->end - (bm)->free)
233 
234 
235 #define                                                                       \
236 nxt_buf_used_size(b)                                                          \
237     (nxt_buf_is_file(b) ? (b)->file_end - (b)->file_pos:                      \
238                           nxt_buf_mem_used_size(&(b)->mem))
239 
240 
241 NXT_EXPORT void nxt_buf_mem_init(nxt_buf_t *b, void *start, size_t size);
242 NXT_EXPORT nxt_buf_t *nxt_buf_mem_alloc(nxt_mp_t *mp, size_t size,
243     nxt_uint_t flags);
244 NXT_EXPORT nxt_buf_t *nxt_buf_mem_ts_alloc(nxt_task_t *task, nxt_mp_t *mp,
245     size_t size);
246 NXT_EXPORT nxt_buf_t *nxt_buf_file_alloc(nxt_mp_t *mp, size_t size,
247     nxt_uint_t flags);
248 NXT_EXPORT nxt_buf_t *nxt_buf_mmap_alloc(nxt_mp_t *mp, size_t size);
249 NXT_EXPORT nxt_buf_t *nxt_buf_sync_alloc(nxt_mp_t *mp, nxt_uint_t flags);
250 
251 NXT_EXPORT nxt_int_t nxt_buf_ts_handle(nxt_task_t *task, void *obj, void *data);
252 
253 #define                                                                       \
254 nxt_buf_free(mp, b)                                                           \
255     nxt_mp_free((mp), (b))
256 
257 
258 NXT_EXPORT void nxt_buf_chain_add(nxt_buf_t **head, nxt_buf_t *in);
259 NXT_EXPORT size_t nxt_buf_chain_length(nxt_buf_t *b);
260 
261 
262 #endif /* _NXT_BUF_H_INCLIDED_ */
263