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