Lines Matching +full:4 +full:- +full:ring
2 * ring.h
4 * Shared producer-consumer ring macros.
33 * - standard integers types (uint8_t, uint16_t, etc)
38 * - size_t
39 * - memcpy
40 * - grant_ref_t
45 #include "../xen-compat.h"
55 /* Round a 32-bit unsigned constant down to the nearest power of two. */
58 #define __RD8(_x) (((_x) & 0x000000f0) ? __RD4((_x)>>4)<<4 : __RD4(_x))
63 * Calculate size of a shared ring, given the total available space for the
64 * ring and indexes (_sz), and the name tag of the request/response structure.
65 * A ring contains as many entries as will fit, rounded down to the nearest
66 * power of two (so we can mask with (size-1) to loop around).
69 (__RD32(((_sz) - offsetof(struct _s##_sring, ring)) / \
70 sizeof(((struct _s##_sring *)0)->ring[0])))
75 (__RD32(((_sz) - (long)(_s)->ring + (long)(_s)) / sizeof((_s)->ring[0])))
78 * Macros to make the correct C datatypes for a new kind of ring.
80 * To make a new ring datatype, you need to have two message structures,
83 * In a header where you want the ring datatype declared, you then do:
90 * mytag_sring_t - The shared ring.
91 * mytag_front_ring_t - The 'front' half of the ring.
92 * mytag_back_ring_t - The 'back' half of the ring.
94 * To initialize a ring in your code you need to know the location and size
103 * initializes the shared ring):
111 /* Shared ring entry */ \
117 /* Shared ring page */ \
128 uint8_t pvt_pad[4]; \
131 union __name##_sring_entry ring[1]; /* variable-length */ \
158 * FRONT_RING_whatever works on the "front end" of a ring: here
159 * requests are pushed on to the ring and responses taken off it.
161 * BACK_RING_whatever works on the "back end" of a ring: here
162 * requests are taken off the ring and responses put on.
165 * This is OK in 1-for-1 request-response situations where the
166 * requestor (front end) never has more than RING_SIZE()-1
172 (_s)->req_prod = (_s)->rsp_prod = 0; \
173 (_s)->req_event = (_s)->rsp_event = 1; \
174 (void)memset((_s)->pvt.pvt_pad, 0, sizeof((_s)->pvt.pvt_pad)); \
175 (void)memset((_s)->__pad, 0, sizeof((_s)->__pad)); \
179 (_r)->req_prod_pvt = (_i); \
180 (_r)->rsp_cons = (_i); \
181 (_r)->nr_ents = __RING_SIZE(_s, __size); \
182 (_r)->sring = (_s); \
188 (_r)->rsp_prod_pvt = (_i); \
189 (_r)->req_cons = (_i); \
190 (_r)->nr_ents = __RING_SIZE(_s, __size); \
191 (_r)->sring = (_s); \
196 /* How big is this ring? */
198 ((_r)->nr_ents)
202 (RING_SIZE(_r) - ((_r)->req_prod_pvt - (_r)->rsp_cons))
204 /* Test if there is an empty slot available on the front ring.
210 /* Test if there are outstanding messages to be processed on a ring. */
212 ((_r)->sring->rsp_prod - (_r)->rsp_cons)
216 unsigned int req = (_r)->sring->req_prod - (_r)->req_cons; \
217 unsigned int rsp = RING_SIZE(_r) - \
218 ((_r)->req_cons - (_r)->rsp_prod_pvt); \
224 ((((_r)->sring->req_prod - (_r)->req_cons) < \
225 (RING_SIZE(_r) - ((_r)->req_cons - (_r)->rsp_prod_pvt))) ? \
226 ((_r)->sring->req_prod - (_r)->req_cons) : \
227 (RING_SIZE(_r) - ((_r)->req_cons - (_r)->rsp_prod_pvt)))
230 /* Direct access to individual ring elements, by index. */
232 (&((_r)->sring->ring[((_idx) & (RING_SIZE(_r) - 1))].req))
235 (&((_r)->sring->ring[((_idx) & (RING_SIZE(_r) - 1))].rsp))
254 /* Loop termination condition: Would the specified index overflow the ring? */
256 (((_cons) - (_r)->rsp_prod_pvt) >= RING_SIZE(_r))
258 /* Ill-behaved frontend determination: Can there be this many requests? */
260 (((_prod) - (_r)->rsp_prod_pvt) > RING_SIZE(_r))
262 /* Ill-behaved backend determination: Can there be this many responses? */
264 (((_prod) - (_r)->rsp_cons) > RING_SIZE(_r))
268 (_r)->sring->req_prod = (_r)->req_prod_pvt; \
273 (_r)->sring->rsp_prod = (_r)->rsp_prod_pvt; \
277 * Notification hold-off (req_event and rsp_event):
279 * When queueing requests or responses on a shared ring, it may not always be
295 * are pending messages on the ring (i.e., the connection should not be put
307 RING_IDX __old = (_r)->sring->req_prod; \
308 RING_IDX __new = (_r)->req_prod_pvt; \
310 (_r)->sring->req_prod = __new; \
312 (_notify) = ((RING_IDX)(__new - (_r)->sring->req_event) < \
313 (RING_IDX)(__new - __old)); \
317 RING_IDX __old = (_r)->sring->rsp_prod; \
318 RING_IDX __new = (_r)->rsp_prod_pvt; \
320 (_r)->sring->rsp_prod = __new; \
322 (_notify) = ((RING_IDX)(__new - (_r)->sring->rsp_event) < \
323 (RING_IDX)(__new - __old)); \
329 (_r)->sring->req_event = (_r)->req_cons + 1; \
337 (_r)->sring->rsp_event = (_r)->rsp_cons + 1; \
345 * functions to check if there is data on the ring, and to read and
359 * within the range [0-size].
362 * Function to read data from the ring. The amount of data to read is
366 * Function to write data to the ring. The amount of data to write is
371 * ring at the right location.
378 * Function to calculate how many bytes are currently on the ring,
380 * space is currently on the ring (XEN_FLEX_RING_SIZE() -
385 /* The PAGE_SIZE for ring protocols and hypercall interfaces is always
386 * 4K, regardless of the architecture, and page granularity chosen by
392 (1UL << ((order) + XEN_PAGE_SHIFT - 1))
397 return idx & (ring_size - 1); \
415 size <= ring_size - *masked_cons) { \
418 memcpy(opaque, buf + *masked_cons, ring_size - *masked_cons); \
419 memcpy((unsigned char *)opaque + ring_size - *masked_cons, buf, \
420 size - (ring_size - *masked_cons)); \
433 size <= ring_size - *masked_prod) { \
436 memcpy(buf + *masked_prod, opaque, ring_size - *masked_prod); \
437 memcpy(buf, (unsigned char *)opaque + (ring_size - *masked_prod), \
438 size - (ring_size - *masked_prod)); \
459 size = prod - cons; \
461 size = ring_size - (cons - prod); \
490 * c-file-style: "BSD"
491 * c-basic-offset: 4
492 * tab-width: 4
493 * indent-tabs-mode: nil