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.
41 * Ring manipulation API allows for:
44 * a ring. Approaches such as, #1) reserve resources one by one and return them
52 * - Pending production: Fetch the next index where a ring element may be
54 * - Pending consumption: Fetch the next index where a ring element may be
58 * - bcm_ring_is_full : Test whether ring is full
65 * - bcm_ring_is_empty : Test whether ring is empty
71 * - bcm_ring_sync_read: Sync read offset in peer ring, from local ring
72 * - bcm_ring_sync_write: Sync write offset in peer ring, from local ring
77 * Following items are not tracked in a ring context (design decision)
78 * - width of a ring element.
79 * - depth of the ring.
81 * - count of number of free slots in the ring
90 * An application may incarnate a ring of some fixed sized elements, by defining
91 * - a ring data buffer to store the ring elements.
92 * - depth of the ring (max number of elements managed by ring context).
94 * - width of a ring element: to be used in pointer arithmetic with the ring's
95 * data buffer base and an index to fetch the ring element.
151 #define BCM_RING_IS_VALID(ring) (((ring) != BCM_RING_NULL) && \ argument
152 ((ring)->self == (ring)))
155 #define BCM_RING_IS_VALID(ring) ((ring) != BCM_RING_NULL) argument
162 * Ring Context
165 typedef struct bcm_ring { /* Ring context */
169 int write __ring_aligned; /* WRITE index in a circular ring */
170 int read __ring_aligned; /* READ index in a circular ring */
173 static INLINE void bcm_ring_init(bcm_ring_t *ring);
175 static INLINE bool bcm_ring_is_empty(bcm_ring_t *ring);
177 static INLINE int __bcm_ring_next_write(bcm_ring_t *ring, const int ring_size);
179 static INLINE bool __bcm_ring_full(bcm_ring_t *ring, int next_write);
180 static INLINE bool bcm_ring_is_full(bcm_ring_t *ring, const int ring_size);
182 static INLINE void bcm_ring_prod_done(bcm_ring_t *ring, int write);
183 static INLINE int bcm_ring_prod_pend(bcm_ring_t *ring, int *pend_write,
185 static INLINE int bcm_ring_prod(bcm_ring_t *ring, const int ring_size);
187 static INLINE void bcm_ring_cons_done(bcm_ring_t *ring, int read);
188 static INLINE int bcm_ring_cons_pend(bcm_ring_t *ring, int *pend_read,
190 static INLINE int bcm_ring_cons(bcm_ring_t *ring, const int ring_size);
195 static INLINE int bcm_ring_prod_avail(const bcm_ring_t *ring,
197 static INLINE int bcm_ring_cons_avail(const bcm_ring_t *ring,
199 static INLINE void bcm_ring_cons_all(bcm_ring_t *ring);
202 * bcm_ring_init - initialize a ring context.
203 * @ring: pointer to a ring context
206 bcm_ring_init(bcm_ring_t *ring) in bcm_ring_init() argument
208 ASSERT(ring != (bcm_ring_t *)NULL); in bcm_ring_init()
210 ring->self = ring; in bcm_ring_init()
212 ring->write = 0; in bcm_ring_init()
213 ring->read = 0; in bcm_ring_init()
217 * bcm_ring_copy - copy construct a ring
218 * @to: pointer to the new ring context
219 * @from: pointer to orig ring context
231 * bcm_ring_is_empty - "Boolean" test whether ring is empty.
232 * @ring: pointer to a ring context
237 bcm_ring_is_empty(bcm_ring_t *ring) in bcm_ring_is_empty() argument
239 RING_ASSERT(BCM_RING_IS_VALID(ring)); in bcm_ring_is_empty()
240 return (ring->read == ring->write); in bcm_ring_is_empty()
246 * @ring: pointer to a ring context
247 * @ring_size: size of the ring
252 __bcm_ring_next_write(bcm_ring_t *ring, const int ring_size) in __bcm_ring_next_write() argument
254 RING_ASSERT(BCM_RING_IS_VALID(ring) && BCM_RING_SIZE_IS_VALID(ring_size)); in __bcm_ring_next_write()
255 return ((ring->write + 1) % ring_size); in __bcm_ring_next_write()
259 * __bcm_ring_full - support function for ring full test.
260 * @ring: pointer to a ring context
261 * @next_write: next location in ring where an element is to be produced
266 __bcm_ring_full(bcm_ring_t *ring, int next_write) in __bcm_ring_full() argument
268 return (next_write == ring->read); in __bcm_ring_full()
272 * bcm_ring_is_full - "Boolean" test whether a ring is full.
273 * @ring: pointer to a ring context
274 * @ring_size: size of the ring
279 bcm_ring_is_full(bcm_ring_t *ring, const int ring_size) in bcm_ring_is_full() argument
282 RING_ASSERT(BCM_RING_IS_VALID(ring) && BCM_RING_SIZE_IS_VALID(ring_size)); in bcm_ring_is_full()
283 next_write = __bcm_ring_next_write(ring, ring_size); in bcm_ring_is_full()
284 return __bcm_ring_full(ring, next_write); in bcm_ring_is_full()
290 * @ring: pointer to a ring context
291 * @write: index into ring upto where production was done.
295 bcm_ring_prod_done(bcm_ring_t *ring, int write) in bcm_ring_prod_done() argument
297 RING_ASSERT(BCM_RING_IS_VALID(ring)); in bcm_ring_prod_done()
298 ring->write = write; in bcm_ring_prod_done()
304 * @ring: pointer to a ring context
306 * @ring_size: size of the ring
309 bcm_ring_prod_pend(bcm_ring_t *ring, int *pend_write, const int ring_size) in bcm_ring_prod_pend() argument
312 RING_ASSERT(BCM_RING_IS_VALID(ring) && BCM_RING_SIZE_IS_VALID(ring_size)); in bcm_ring_prod_pend()
313 *pend_write = __bcm_ring_next_write(ring, ring_size); in bcm_ring_prod_pend()
314 if (__bcm_ring_full(ring, *pend_write)) { in bcm_ring_prod_pend()
319 rtn = ring->write; in bcm_ring_prod_pend()
325 * bcm_ring_prod - Fetch and "commit" the next index where a ring element may
327 * @ring: pointer to a ring context
328 * @ring_size: size of the ring
331 bcm_ring_prod(bcm_ring_t *ring, const int ring_size) in bcm_ring_prod() argument
334 RING_ASSERT(BCM_RING_IS_VALID(ring) && BCM_RING_SIZE_IS_VALID(ring_size)); in bcm_ring_prod()
336 next_write = __bcm_ring_next_write(ring, ring_size); in bcm_ring_prod()
337 if (__bcm_ring_full(ring, next_write)) { in bcm_ring_prod()
340 prod_write = ring->write; in bcm_ring_prod()
341 bcm_ring_prod_done(ring, next_write); /* "commit" production */ in bcm_ring_prod()
348 * @ring: pointer to a ring context
352 bcm_ring_cons_done(bcm_ring_t *ring, int read) in bcm_ring_cons_done() argument
354 RING_ASSERT(BCM_RING_IS_VALID(ring)); in bcm_ring_cons_done()
355 ring->read = read; in bcm_ring_cons_done()
359 * bcm_ring_cons_pend - fetch in "pend" mode, the next index where a ring
361 * @ring: pointer to a ring context
362 * @pend_read: index into ring upto which elements may be consumed.
363 * @ring_size: size of the ring
366 bcm_ring_cons_pend(bcm_ring_t *ring, int *pend_read, const int ring_size) in bcm_ring_cons_pend() argument
369 RING_ASSERT(BCM_RING_IS_VALID(ring) && BCM_RING_SIZE_IS_VALID(ring_size)); in bcm_ring_cons_pend()
370 if (bcm_ring_is_empty(ring)) { in bcm_ring_cons_pend()
374 *pend_read = (ring->read + 1) % ring_size; in bcm_ring_cons_pend()
376 rtn = ring->read; in bcm_ring_cons_pend()
382 * bcm_ring_cons - fetch and "commit" the next index where a ring element may
384 * @ring: pointer to a ring context
385 * @ring_size: size of the ring
388 bcm_ring_cons(bcm_ring_t *ring, const int ring_size) in bcm_ring_cons() argument
391 RING_ASSERT(BCM_RING_IS_VALID(ring) && BCM_RING_SIZE_IS_VALID(ring_size)); in bcm_ring_cons()
392 if (bcm_ring_is_empty(ring)) { in bcm_ring_cons()
395 cons_read = ring->read; in bcm_ring_cons()
396 ring->read = (ring->read + 1) % ring_size; /* read is committed */ in bcm_ring_cons()
403 * @peer: pointer to peer's producer ring context
404 * @self: pointer to consumer's ring context
416 * @peer: pointer to peer's consumer ring context
417 * @self: pointer to producer's ring context
429 * ring for production.
430 * @ring: pointer to a ring context
431 * @ring_size: size of the ring
434 bcm_ring_prod_avail(const bcm_ring_t *ring, const int ring_size) in bcm_ring_prod_avail() argument
437 RING_ASSERT(BCM_RING_IS_VALID(ring) && BCM_RING_SIZE_IS_VALID(ring_size)); in bcm_ring_prod_avail()
438 if (ring->write >= ring->read) { in bcm_ring_prod_avail()
439 prod_avail = (ring_size - (ring->write - ring->read) - 1); in bcm_ring_prod_avail()
441 prod_avail = (ring->read - (ring->write + 1)); in bcm_ring_prod_avail()
449 * @ring: pointer to a ring context
450 * @ring_size: size of the ring
453 bcm_ring_cons_avail(const bcm_ring_t *ring, const int ring_size) in bcm_ring_cons_avail() argument
456 RING_ASSERT(BCM_RING_IS_VALID(ring) && BCM_RING_SIZE_IS_VALID(ring_size)); in bcm_ring_cons_avail()
457 if (ring->read == ring->write) { in bcm_ring_cons_avail()
459 } else if (ring->read > ring->write) { in bcm_ring_cons_avail()
460 cons_avail = ((ring_size - ring->read) + ring->write); in bcm_ring_cons_avail()
462 cons_avail = ring->write - ring->read; in bcm_ring_cons_avail()
469 * bcm_ring_cons_all - set ring in state where all elements are consumed.
470 * @ring: pointer to a ring context
473 bcm_ring_cons_all(bcm_ring_t *ring) in bcm_ring_cons_all() argument
475 ring->read = ring->write; in bcm_ring_cons_all()
480 * A work Queue is composed of a ring of work items, of a specified depth.
482 * producer/consumer circular ring.
486 bcm_ring_t ring; /* Ring context abstraction */ member
510 #define WORKQ_RING(workq) (&((workq)->ring))
511 #define WORKQ_PEER_RING(workq) (&((workq)->peer->ring))
533 * @buffer: pointer to a pre-allocated circular buffer to serve as a ring
534 * @ring_size: size of the ring in terms of max number of elements.
566 * bcm_workq_prod_sync - Commit the producer write index to peer workq's ring
579 * bcm_workq_cons_sync - Commit the consumer read index to the peer workq's ring