Lines Matching full:ring
2 * bcm_ring.h : Ring context abstraction
3 * The ring context tracks the WRITE and READ indices where elements may be
4 * produced and consumed respectively. All elements in the ring need to be
7 * NOTE: A ring of size N, may only hold N-1 elements.
33 * Ring manipulation API allows for:
36 * a ring. Approaches such as, #1) reserve resources one by one and return them
44 * - Pending production: Fetch the next index where a ring element may be
46 * - Pending consumption: Fetch the next index where a ring element may be
50 * - bcm_ring_is_full : Test whether ring is full
57 * - bcm_ring_is_empty : Test whether ring is empty
63 * - bcm_ring_sync_read: Sync read offset in peer ring, from local ring
64 * - bcm_ring_sync_write: Sync write offset in peer ring, from local ring
69 * Following items are not tracked in a ring context (design decision)
70 * - width of a ring element.
71 * - depth of the ring.
73 * - count of number of free slots in the ring
82 * An application may incarnate a ring of some fixed sized elements, by defining
83 * - a ring data buffer to store the ring elements.
84 * - depth of the ring (max number of elements managed by ring context).
86 * - width of a ring element: to be used in pointer arithmetic with the ring's
87 * data buffer base and an index to fetch the ring element.
119 #define BCM_RING_IS_VALID(ring) (((ring) != BCM_RING_NULL) && \ argument
120 ((ring)->self == (ring)))
123 #define BCM_RING_IS_VALID(ring) ((ring) != BCM_RING_NULL) argument
130 * Ring Context
133 typedef struct bcm_ring { /* Ring context */
137 int write __ring_aligned; /* WRITE index in a circular ring */
138 int read __ring_aligned; /* READ index in a circular ring */
141 static INLINE void bcm_ring_init(bcm_ring_t *ring);
143 static INLINE bool bcm_ring_is_empty(const bcm_ring_t *ring);
145 static INLINE int __bcm_ring_next_write(const bcm_ring_t *ring, const int ring_size);
147 static INLINE bool __bcm_ring_full(const bcm_ring_t *ring, int next_write);
148 static INLINE bool bcm_ring_is_full(bcm_ring_t *ring, const int ring_size);
150 static INLINE void bcm_ring_prod_done(bcm_ring_t *ring, int write);
151 static INLINE int bcm_ring_prod_pend(const bcm_ring_t *ring, int *pend_write,
153 static INLINE int bcm_ring_prod(bcm_ring_t *ring, const int ring_size);
155 static INLINE void bcm_ring_cons_done(bcm_ring_t *ring, int read);
156 static INLINE int bcm_ring_cons_pend(const bcm_ring_t *ring, int *pend_read,
158 static INLINE int bcm_ring_cons(bcm_ring_t *ring, const int ring_size);
163 static INLINE int bcm_ring_prod_avail(const bcm_ring_t *ring,
165 static INLINE int bcm_ring_cons_avail(const bcm_ring_t *ring,
167 static INLINE void bcm_ring_cons_all(bcm_ring_t *ring);
170 * bcm_ring_init - initialize a ring context.
171 * @ring: pointer to a ring context
174 bcm_ring_init(bcm_ring_t *ring) in bcm_ring_init() argument
176 ASSERT(ring != (bcm_ring_t *)NULL); in bcm_ring_init()
178 ring->self = ring; in bcm_ring_init()
180 ring->write = 0; in bcm_ring_init()
181 ring->read = 0; in bcm_ring_init()
185 * bcm_ring_copy - copy construct a ring
186 * @to: pointer to the new ring context
187 * @from: pointer to orig ring context
199 * bcm_ring_is_empty - "Boolean" test whether ring is empty.
200 * @ring: pointer to a ring context
205 bcm_ring_is_empty(const bcm_ring_t *ring) in bcm_ring_is_empty() argument
207 RING_ASSERT(BCM_RING_IS_VALID(ring)); in bcm_ring_is_empty()
208 return (ring->read == ring->write); in bcm_ring_is_empty()
214 * @ring: pointer to a ring context
215 * @ring_size: size of the ring
220 __bcm_ring_next_write(const bcm_ring_t *ring, const int ring_size) in __bcm_ring_next_write() argument
222 RING_ASSERT(BCM_RING_IS_VALID(ring) && BCM_RING_SIZE_IS_VALID(ring_size)); in __bcm_ring_next_write()
223 return ((ring->write + 1) % ring_size); in __bcm_ring_next_write()
227 * __bcm_ring_full - support function for ring full test.
228 * @ring: pointer to a ring context
229 * @next_write: next location in ring where an element is to be produced
234 __bcm_ring_full(const bcm_ring_t *ring, int next_write) in __bcm_ring_full() argument
236 return (next_write == ring->read); in __bcm_ring_full()
240 * bcm_ring_is_full - "Boolean" test whether a ring is full.
241 * @ring: pointer to a ring context
242 * @ring_size: size of the ring
247 bcm_ring_is_full(bcm_ring_t *ring, const int ring_size) in bcm_ring_is_full() argument
250 RING_ASSERT(BCM_RING_IS_VALID(ring) && BCM_RING_SIZE_IS_VALID(ring_size)); in bcm_ring_is_full()
251 next_write = __bcm_ring_next_write(ring, ring_size); in bcm_ring_is_full()
252 return __bcm_ring_full(ring, next_write); in bcm_ring_is_full()
258 * @ring: pointer to a ring context
259 * @write: index into ring upto where production was done.
263 bcm_ring_prod_done(bcm_ring_t *ring, int write) in bcm_ring_prod_done() argument
265 RING_ASSERT(BCM_RING_IS_VALID(ring)); in bcm_ring_prod_done()
266 ring->write = write; in bcm_ring_prod_done()
272 * @ring: pointer to a ring context
274 * @ring_size: size of the ring
277 bcm_ring_prod_pend(const bcm_ring_t *ring, int *pend_write, const int ring_size) in bcm_ring_prod_pend() argument
280 RING_ASSERT(BCM_RING_IS_VALID(ring) && BCM_RING_SIZE_IS_VALID(ring_size)); in bcm_ring_prod_pend()
281 *pend_write = __bcm_ring_next_write(ring, ring_size); in bcm_ring_prod_pend()
282 if (__bcm_ring_full(ring, *pend_write)) { in bcm_ring_prod_pend()
287 rtn = ring->write; in bcm_ring_prod_pend()
293 * bcm_ring_prod - Fetch and "commit" the next index where a ring element may
295 * @ring: pointer to a ring context
296 * @ring_size: size of the ring
299 bcm_ring_prod(bcm_ring_t *ring, const int ring_size) in bcm_ring_prod() argument
302 RING_ASSERT(BCM_RING_IS_VALID(ring) && BCM_RING_SIZE_IS_VALID(ring_size)); in bcm_ring_prod()
304 next_write = __bcm_ring_next_write(ring, ring_size); in bcm_ring_prod()
305 if (__bcm_ring_full(ring, next_write)) { in bcm_ring_prod()
308 prod_write = ring->write; in bcm_ring_prod()
309 bcm_ring_prod_done(ring, next_write); /* "commit" production */ in bcm_ring_prod()
316 * @ring: pointer to a ring context
320 bcm_ring_cons_done(bcm_ring_t *ring, int read) in bcm_ring_cons_done() argument
322 RING_ASSERT(BCM_RING_IS_VALID(ring)); in bcm_ring_cons_done()
323 ring->read = read; in bcm_ring_cons_done()
327 * bcm_ring_cons_pend - fetch in "pend" mode, the next index where a ring
329 * @ring: pointer to a ring context
330 * @pend_read: index into ring upto which elements may be consumed.
331 * @ring_size: size of the ring
334 bcm_ring_cons_pend(const bcm_ring_t *ring, int *pend_read, const int ring_size) in bcm_ring_cons_pend() argument
337 RING_ASSERT(BCM_RING_IS_VALID(ring) && BCM_RING_SIZE_IS_VALID(ring_size)); in bcm_ring_cons_pend()
338 if (bcm_ring_is_empty(ring)) { in bcm_ring_cons_pend()
342 *pend_read = (ring->read + 1) % ring_size; in bcm_ring_cons_pend()
344 rtn = ring->read; in bcm_ring_cons_pend()
350 * bcm_ring_cons - fetch and "commit" the next index where a ring element may
352 * @ring: pointer to a ring context
353 * @ring_size: size of the ring
356 bcm_ring_cons(bcm_ring_t *ring, const int ring_size) in bcm_ring_cons() argument
359 RING_ASSERT(BCM_RING_IS_VALID(ring) && BCM_RING_SIZE_IS_VALID(ring_size)); in bcm_ring_cons()
360 if (bcm_ring_is_empty(ring)) { in bcm_ring_cons()
363 cons_read = ring->read; in bcm_ring_cons()
364 ring->read = (ring->read + 1) % ring_size; /* read is committed */ in bcm_ring_cons()
371 * @peer: pointer to peer's producer ring context
372 * @self: pointer to consumer's ring context
384 * @peer: pointer to peer's consumer ring context
385 * @self: pointer to producer's ring context
397 * ring for production.
398 * @ring: pointer to a ring context
399 * @ring_size: size of the ring
402 bcm_ring_prod_avail(const bcm_ring_t *ring, const int ring_size) in bcm_ring_prod_avail() argument
405 RING_ASSERT(BCM_RING_IS_VALID(ring) && BCM_RING_SIZE_IS_VALID(ring_size)); in bcm_ring_prod_avail()
406 if (ring->write >= ring->read) { in bcm_ring_prod_avail()
407 prod_avail = (ring_size - (ring->write - ring->read) - 1); in bcm_ring_prod_avail()
409 prod_avail = (ring->read - (ring->write + 1)); in bcm_ring_prod_avail()
417 * @ring: pointer to a ring context
418 * @ring_size: size of the ring
421 bcm_ring_cons_avail(const bcm_ring_t *ring, const int ring_size) in bcm_ring_cons_avail() argument
424 RING_ASSERT(BCM_RING_IS_VALID(ring) && BCM_RING_SIZE_IS_VALID(ring_size)); in bcm_ring_cons_avail()
425 if (ring->read == ring->write) { in bcm_ring_cons_avail()
427 } else if (ring->read > ring->write) { in bcm_ring_cons_avail()
428 cons_avail = ((ring_size - ring->read) + ring->write); in bcm_ring_cons_avail()
430 cons_avail = ring->write - ring->read; in bcm_ring_cons_avail()
437 * bcm_ring_cons_all - set ring in state where all elements are consumed.
438 * @ring: pointer to a ring context
441 bcm_ring_cons_all(bcm_ring_t *ring) in bcm_ring_cons_all() argument
443 ring->read = ring->write; in bcm_ring_cons_all()
448 * A work Queue is composed of a ring of work items, of a specified depth.
450 * producer/consumer circular ring.
454 bcm_ring_t ring; /* Ring context abstraction */ member
478 #define WORKQ_RING(workq) (&((workq)->ring))
479 #define WORKQ_PEER_RING(workq) (&((workq)->peer->ring))
501 * @buffer: pointer to a pre-allocated circular buffer to serve as a ring
502 * @ring_size: size of the ring in terms of max number of elements.
534 * bcm_workq_prod_sync - Commit the producer write index to peer workq's ring
547 * bcm_workq_cons_sync - Commit the consumer read index to the peer workq's ring