svm: refactor fifo chunk tracking
[vpp.git] / src / svm / svm_fifo.h
index d5dfc9c..2b6e854 100644 (file)
@@ -60,6 +60,7 @@ typedef struct svm_fifo_chunk_
   u32 start_byte;              /**< chunk start byte */
   u32 length;                  /**< length of chunk in bytes */
   struct svm_fifo_chunk_ *next;        /**< pointer to next chunk in linked-lists */
+  rb_node_index_t rb_index;    /**< node index if chunk in rbtree */
   u8 data[0];                  /**< start of chunk data */
 } svm_fifo_chunk_t;
 
@@ -70,6 +71,7 @@ typedef enum svm_fifo_flag_
   SVM_FIFO_F_SHRINK = 1 << 2,
   SVM_FIFO_F_COLLECT_CHUNKS = 1 << 3,
   SVM_FIFO_F_LL_TRACKED = 1 << 4,
+  SVM_FIFO_F_SINGLE_THREAD_OWNED = 1 << 5,
 } svm_fifo_flag_t;
 
 typedef struct _svm_fifo
@@ -77,11 +79,12 @@ typedef struct _svm_fifo
   CLIB_CACHE_LINE_ALIGN_MARK (shared_first);
   u32 size;                    /**< size of the fifo in bytes */
   u32 nitems;                  /**< usable size (size-1) */
-  u8 flags;                    /**< fifo flags */
   svm_fifo_chunk_t *start_chunk;/**< first chunk in fifo chunk list */
   svm_fifo_chunk_t *end_chunk; /**< end chunk in fifo chunk list */
-  svm_fifo_chunk_t *new_chunks;        /**< chunks yet to be added to list */
-  rb_tree_t chunk_lookup;
+  rb_tree_t ooo_enq_lookup;    /**< rbtree for ooo enq chunk lookup */
+  rb_tree_t ooo_deq_lookup;    /**< rbtree for ooo deq chunk lookup */
+  u8 flags;                    /**< fifo flags */
+  u8 slice_index;              /**< segment slice for fifo */
 
     CLIB_CACHE_LINE_ALIGN_MARK (shared_second);
   volatile u32 has_event;      /**< non-zero if deq event exists */
@@ -94,6 +97,7 @@ typedef struct _svm_fifo
   u32 segment_index;           /**< segment index in segment manager */
   struct _svm_fifo *next;      /**< next in freelist/active chain */
   struct _svm_fifo *prev;      /**< prev in active chain */
+  svm_fifo_chunk_t *new_chunks;        /**< chunks yet to be added to list */
   u32 size_decrement;          /**< bytes to remove from fifo */
 
     CLIB_CACHE_LINE_ALIGN_MARK (consumer);
@@ -477,6 +481,14 @@ ooo_segment_t *svm_fifo_first_ooo_segment (svm_fifo_t * f);
  * @return     1 if sane, 0 otherwise
  */
 u8 svm_fifo_is_sane (svm_fifo_t * f);
+/**
+ * Declare this fifo is used by only a single thread.
+ * In this special case, fifo-growth can be done in an efficient way without delay.
+ *
+ * @param f             fifo
+ * @return              1 if the fifo is already owned by another thread, 0 otherwise
+ */
+u8 svm_fifo_set_single_thread_owned (svm_fifo_t * f);
 format_function_t format_svm_fifo;
 
 /**
@@ -650,7 +662,7 @@ svm_fifo_max_write_chunk (svm_fifo_t * f)
 {
   u32 head, tail;
   f_load_head_tail_prod (f, &head, &tail);
-  return tail > head ? f->size - tail : f_free_count (f, head, tail);
+  return tail >= head ? f->size - tail : f_free_count (f, head, tail);
 }
 
 static inline u8 *