#define OOO_SEGMENT_INVALID_INDEX ((u32)~0)
-typedef struct
+typedef struct _svm_fifo
{
volatile u32 cursize; /**< current fifo size */
u32 nitems;
CLIB_CACHE_LINE_ALIGN_MARK (end_cursize);
- volatile u8 has_event; /**< non-zero if deq event exists */
+ volatile u32 has_event; /**< non-zero if deq event exists */
/* Backpointers */
u32 master_session_index;
ooo_segment_t *ooo_segments; /**< Pool of ooo segments */
u32 ooos_list_head; /**< Head of out-of-order linked-list */
u32 ooos_newest; /**< Last segment to have been updated */
-
+ struct _svm_fifo *next; /**< next in freelist/active chain */
+ struct _svm_fifo *prev; /**< prev in active chain */
CLIB_CACHE_LINE_ALIGN_MARK (data);
} svm_fifo_t;
svm_fifo_unset_event (svm_fifo_t * f)
{
/* Probably doesn't need to be atomic. Still, better avoid surprises */
- __sync_lock_test_and_set (&f->has_event, 0);
+ __sync_lock_release (&f->has_event);
}
svm_fifo_t *svm_fifo_create (u32 data_size_in_bytes);
always_inline ooo_segment_t *
svm_fifo_newest_ooo_segment (svm_fifo_t * f)
{
- return f->ooo_segments + f->ooos_newest;
+ if (f->ooos_newest == OOO_SEGMENT_INVALID_INDEX)
+ return 0;
+ return pool_elt_at_index (f->ooo_segments, f->ooos_newest);
+}
+
+always_inline u32
+ooo_segment_distance_to_tail (svm_fifo_t * f, u32 a)
+{
+ /* Ambiguous. Assumption is that ooo segments don't touch tail */
+ if (a == f->tail && f->tail == f->head)
+ return f->nitems;
+
+ return ((f->nitems + a - f->tail) % f->nitems);
}
always_inline u32
ooo_segment_offset (svm_fifo_t * f, ooo_segment_t * s)
{
-// return ((f->nitems + s->fifo_position - f->tail) % f->nitems);
- return s->start;
+ return ooo_segment_distance_to_tail (f, s->start);
}
always_inline u32
ooo_segment_end_offset (svm_fifo_t * f, ooo_segment_t * s)
{
-// return ((f->nitems + s->fifo_position + s->length - f->tail) % f->nitems);
- return s->start + s->length;
+ return ooo_segment_distance_to_tail (f, s->start) + s->length;
+}
+
+always_inline u32
+ooo_segment_length (svm_fifo_t * f, ooo_segment_t * s)
+{
+ return s->length;
}
always_inline ooo_segment_t *