aboutsummaryrefslogtreecommitdiffstats
path: root/src/svm/svm_fifo.h
diff options
context:
space:
mode:
authorFlorin Coras <fcoras@cisco.com>2019-05-02 12:52:19 -0700
committerDave Barach <openvpp@barachs.net>2019-05-03 14:34:46 +0000
commit29a59c3ae18573043d9f9baa2796ab0b841bf6aa (patch)
treee14b3f88d6ec06d9d6c54ca740fe81a9a99ef703 /src/svm/svm_fifo.h
parent14e2e2a5715ddf938db5b3884e268ec09e112935 (diff)
svm: store normalized head/tail for fifo
If head/tail are stored as "absolute" values that are normalized to [0, fifo_size] interval, when fifo is shrunk/grown the consumer and producer have to independently update to the new fifo size and fix head and tail, respectively. If the head and tail are stored as normalized values, under the right conditions, they don't need to be fixed when fifo size changes. This reverts one of the changes in gerrit 18223. Change-Id: I55a908828afe90925cf7c20186a940b25e5805f9 Signed-off-by: Florin Coras <fcoras@cisco.com>
Diffstat (limited to 'src/svm/svm_fifo.h')
-rw-r--r--src/svm/svm_fifo.h48
1 files changed, 20 insertions, 28 deletions
diff --git a/src/svm/svm_fifo.h b/src/svm/svm_fifo.h
index 96ca3ee01c6..390e1170e27 100644
--- a/src/svm/svm_fifo.h
+++ b/src/svm/svm_fifo.h
@@ -186,47 +186,47 @@ f_load_head_tail_all_acq (svm_fifo_t * f, u32 * head, u32 * tail)
}
/**
- * Fifo free bytes, i.e., number of free bytes
+ * Distance to a from b, i.e., a - b in the fifo
*
- * Internal function
+ * Internal function.
*/
static inline u32
-f_free_count (svm_fifo_t * f, u32 head, u32 tail)
+f_distance_to (svm_fifo_t * f, u32 a, u32 b)
{
- return (f->nitems + head - tail);
+ return ((f->size + a - b) % f->size);
}
/**
- * Fifo current size, i.e., number of bytes enqueued
+ * Distance from a to b, i.e., b - a in the fifo
*
* Internal function.
*/
static inline u32
-f_cursize (svm_fifo_t * f, u32 head, u32 tail)
+f_distance_from (svm_fifo_t * f, u32 a, u32 b)
{
- return (f->nitems - f_free_count (f, head, tail));
+ return ((f->size + b - a) % f->size);
}
/**
- * Distance to a from b, i.e., a - b in the fifo
+ * Fifo current size, i.e., number of bytes enqueued
*
* Internal function.
*/
static inline u32
-f_distance_to (svm_fifo_t * f, u32 a, u32 b)
+f_cursize (svm_fifo_t * f, u32 head, u32 tail)
{
- return ((f->size + a - b) % f->size);
+ return (head <= tail ? tail - head : f->size + tail - head);
}
/**
- * Distance from a to b, i.e., b - a in the fifo
+ * Fifo free bytes, i.e., number of free bytes
*
- * Internal function.
+ * Internal function
*/
static inline u32
-f_distance_from (svm_fifo_t * f, u32 a, u32 b)
+f_free_count (svm_fifo_t * f, u32 head, u32 tail)
{
- return ((f->size + b - a) % f->size);
+ return (f->nitems - f_cursize (f, head, tail));
}
/**
@@ -535,7 +535,7 @@ svm_fifo_is_wrapped (svm_fifo_t * f)
{
u32 head, tail;
f_load_head_tail_all_acq (f, &head, &tail);
- return head % f->size > tail % f->size;
+ return head > tail;
}
/**
@@ -575,11 +575,8 @@ static inline u32
svm_fifo_max_read_chunk (svm_fifo_t * f)
{
u32 head, tail;
- u32 head_idx, tail_idx;
f_load_head_tail_cons (f, &head, &tail);
- head_idx = head % f->size;
- tail_idx = tail % f->size;
- return tail_idx > head_idx ? (tail_idx - head_idx) : (f->size - head_idx);
+ return tail >= head ? (tail - head) : (f->size - head);
}
/**
@@ -589,11 +586,8 @@ static inline u32
svm_fifo_max_write_chunk (svm_fifo_t * f)
{
u32 head, tail;
- u32 head_idx, tail_idx;
f_load_head_tail_prod (f, &head, &tail);
- head_idx = head % f->size;
- tail_idx = tail % f->size;
- return tail_idx >= head_idx ? (f->size - tail_idx) : (head_idx - tail_idx);
+ return tail > head ? f->size - tail : f_free_count (f, head, tail);
}
/**
@@ -610,7 +604,7 @@ svm_fifo_enqueue_nocopy (svm_fifo_t * f, u32 len)
ASSERT (len <= svm_fifo_max_enqueue_prod (f));
/* load-relaxed: producer owned index */
u32 tail = f->tail;
- tail += len;
+ tail = (tail + len) % f->size;
/* store-rel: producer owned index (paired with load-acq in consumer) */
clib_atomic_store_rel_n (&f->tail, tail);
}
@@ -619,16 +613,14 @@ static inline u8 *
svm_fifo_head (svm_fifo_t * f)
{
/* load-relaxed: consumer owned index */
- return (f->head_chunk->data
- + ((f->head % f->size) - f->head_chunk->start_byte));
+ return (f->head_chunk->data + (f->head - f->head_chunk->start_byte));
}
static inline u8 *
svm_fifo_tail (svm_fifo_t * f)
{
/* load-relaxed: producer owned index */
- return (f->tail_chunk->data
- + ((f->tail % f->size) - f->tail_chunk->start_byte));
+ return (f->tail_chunk->data + (f->tail - f->tail_chunk->start_byte));
}
static inline u8