ck_ring: add two new utility functions for persistent rings.

ck_ring_repair: fix up state in the case of an incomplete write.
ck_ring_valid: returns false if ring is in an inconsistent state.
awsm
Samy Al Bahra 5 years ago
parent 1321f703c8
commit 8959e94fb6

@ -66,9 +66,56 @@ ck_ring_size(const struct ck_ring *ring)
CK_CC_INLINE static unsigned int CK_CC_INLINE static unsigned int
ck_ring_capacity(const struct ck_ring *ring) ck_ring_capacity(const struct ck_ring *ring)
{ {
return ring->size; return ring->size;
} }
/*
* This function is only safe to call when there are no concurrent operations
* on the ring. This is primarily meant for persistent ck_ring use-cases. The
* function returns true if any mutations were performed on the ring.
*/
CK_CC_INLINE static bool
ck_ring_repair(struct ck_ring *ring)
{
bool r = false;
if (ring->p_tail != ring->p_head) {
ring->p_tail = ring->p_head;
r = true;
}
return r;
}
/*
* This can be called when no concurrent updates are occurring on the ring
* structure to check for consistency. This is primarily meant to be used for
* persistent storage of the ring. If this functions returns false, the ring
* is in an inconsistent state.
*/
CK_CC_INLINE static bool
ck_ring_valid(const struct ck_ring *ring)
{
unsigned int size = ring->size;
unsigned int c_head = ring->c_head;
unsigned int p_head = ring->p_head;
/* The ring must be a power of 2. */
if (size & (size - 1))
return false;
/* The consumer counter must always be smaller than the producer. */
if (c_head > p_head)
return false;
/* The producer may only be up to size slots ahead of consumer. */
if (p_head - c_head > size)
return false;
return true;
}
CK_CC_INLINE static void CK_CC_INLINE static void
ck_ring_init(struct ck_ring *ring, unsigned int size) ck_ring_init(struct ck_ring *ring, unsigned int size)
{ {

Loading…
Cancel
Save