Lines Matching +full:index +full:- +full:power +full:- +full:of +full:- +full:two
1 /* SPDX-License-Identifier: MIT */
5 * Shared producer-consumer ring macros.
16 * - standard integers types (uint8_t, uint16_t, etc)
17 * They are provided by stdint.h of the standard headers.
21 * - size_t
22 * - memcpy
23 * - grant_ref_t
24 * These declarations are provided by string.h of the standard headers,
32 /* Round a 32-bit unsigned constant down to the nearest power of two. */
40 * Calculate size of a shared ring, given the total available space for the
41 * ring and indexes (_sz), and the name tag of the request/response structure.
43 * power of two (so we can mask with (size-1) to loop around).
46 (__RD32(((_sz) - offsetof(struct _s##_sring, ring)) / \
47 sizeof(((struct _s##_sring *)0)->ring[0])))
49 * The same for passing in an actual pointer instead of a name tag.
52 (__RD32(((_sz) - (long)(_s)->ring + (long)(_s)) / sizeof((_s)->ring[0])))
55 * Macros to make the correct C datatypes for a new kind of ring.
57 * To make a new ring datatype, you need to have two message structures,
64 * These expand out to give you a set of types, as you can see below.
65 * The most important of these are:
67 * mytag_sring_t - The shared ring.
68 * mytag_front_ring_t - The 'front' half of the ring.
69 * mytag_back_ring_t - The 'back' half of the ring.
72 * of the shared memory area (PAGE_SIZE, for instance). To initialise
120 * FRONT_RING_whatever works on the "front end" of a ring: here
123 * BACK_RING_whatever works on the "back end" of a ring: here
127 * This is OK in 1-for-1 request-response situations where the
128 * requestor (front end) never has more than RING_SIZE()-1
134 (_s)->req_prod = (_s)->rsp_prod = 0; \
135 (_s)->req_event = (_s)->rsp_event = 1; \
136 (void)memset((_s)->__pad, 0, sizeof((_s)->__pad)); \
140 (_r)->req_prod_pvt = (_i); \
141 (_r)->rsp_cons = (_i); \
142 (_r)->nr_ents = __RING_SIZE(_s, __size); \
143 (_r)->sring = (_s); \
154 (_r)->rsp_prod_pvt = (_i); \
155 (_r)->req_cons = (_i); \
156 (_r)->nr_ents = __RING_SIZE(_s, __size); \
157 (_r)->sring = (_s); \
164 ((_r)->nr_ents)
166 /* Number of free requests (for use on front side only). */
168 (RING_SIZE(_r) - ((_r)->req_prod_pvt - (_r)->rsp_cons))
178 ((_r)->sring->rsp_prod - (_r)->rsp_cons)
181 unsigned int req = (_r)->sring->req_prod - (_r)->req_cons; \
182 unsigned int rsp = RING_SIZE(_r) - \
183 ((_r)->req_cons - (_r)->rsp_prod_pvt); \
192 /* Direct access to individual ring elements, by index. */
194 (&((_r)->sring->ring[((_idx) & (RING_SIZE(_r) - 1))].req))
197 (&((_r)->sring->ring[((_idx) & (RING_SIZE(_r) - 1))].rsp))
200 * Get a local copy of a request/response.
206 * to be ineffective where dest is a struct which consists of only bitfields.
216 /* Loop termination condition: Would the specified index overflow the ring? */
218 (((_cons) - (_r)->rsp_prod_pvt) >= RING_SIZE(_r))
220 /* Ill-behaved frontend determination: Can there be this many requests? */
222 (((_prod) - (_r)->rsp_prod_pvt) > RING_SIZE(_r))
224 /* Ill-behaved backend determination: Can there be this many responses? */
226 (((_prod) - (_r)->rsp_cons) > RING_SIZE(_r))
229 virt_wmb(); /* back sees requests /before/ updated producer index */\
230 (_r)->sring->req_prod = (_r)->req_prod_pvt; \
234 virt_wmb(); /* front sees resps /before/ updated producer index */ \
235 (_r)->sring->rsp_prod = (_r)->rsp_prod_pvt; \
239 * Notification hold-off (req_event and rsp_event):
262 * create batches of work (i.e., only receive a notification after several
264 * version of the FINAL_CHECK macro in your own code, which sets the event
269 RING_IDX __old = (_r)->sring->req_prod; \
270 RING_IDX __new = (_r)->req_prod_pvt; \
271 virt_wmb(); /* back sees requests /before/ updated producer index */\
272 (_r)->sring->req_prod = __new; \
274 (_notify) = ((RING_IDX)(__new - (_r)->sring->req_event) < \
275 (RING_IDX)(__new - __old)); \
279 RING_IDX __old = (_r)->sring->rsp_prod; \
280 RING_IDX __new = (_r)->rsp_prod_pvt; \
281 virt_wmb(); /* front sees resps /before/ updated producer index */ \
282 (_r)->sring->rsp_prod = __new; \
284 (_notify) = ((RING_IDX)(__new - (_r)->sring->rsp_event) < \
285 (RING_IDX)(__new - __old)); \
291 (_r)->sring->req_event = (_r)->req_cons + 1; \
299 (_r)->sring->rsp_event = (_r)->rsp_cons + 1; \
306 * DEFINE_XEN_FLEX_RING_AND_INTF defines two monodirectional rings and
316 * Convenience macro to calculate the size of one of the two rings
320 * Function to apply the size mask to an index, to reduce the index
321 * within the range [0-size].
324 * Function to read data from the ring. The amount of data to read is
328 * Function to write data to the ring. The amount of data to write is
337 * contains the array of grant refs.
342 * space is currently on the ring (XEN_FLEX_RING_SIZE() -
348 * 4K, regardless of the architecture, and page granularity chosen by
354 (1UL << ((order) + XEN_PAGE_SHIFT - 1))
359 return idx & (ring_size - 1); \
377 size <= ring_size - *masked_cons) { \
380 memcpy(opaque, buf + *masked_cons, ring_size - *masked_cons); \
381 memcpy((unsigned char *)opaque + ring_size - *masked_cons, buf, \
382 size - (ring_size - *masked_cons)); \
395 size <= ring_size - *masked_prod) { \
398 memcpy(buf + *masked_prod, opaque, ring_size - *masked_prod); \
399 memcpy(buf, (unsigned char *)opaque + (ring_size - *masked_prod), \
400 size - (ring_size - *masked_prod)); \
421 size = prod - cons; \
423 size = ring_size - (cons - prod); \
428 unsigned char *in; /* half of the allocation */ \
429 unsigned char *out; /* half of the allocation */ \