+u8
+svm_fifo_is_sane (svm_fifo_t * f)
+{
+ svm_fifo_chunk_t *tmp;
+
+ if (f->head_chunk && !f_chunk_includes_pos (f->head_chunk, f->head))
+ return 0;
+ if (f->tail_chunk && !f_chunk_includes_pos (f->tail_chunk, f->tail))
+ return 0;
+ if (f->ooo_deq)
+ {
+ if (rb_tree_is_init (&f->ooo_deq_lookup))
+ {
+ if (f_pos_lt (f->ooo_deq->start_byte, f->start_chunk->start_byte)
+ || f_pos_gt (f->ooo_deq->start_byte,
+ f_chunk_end (f->end_chunk)))
+ return 0;
+
+ tmp = f_find_chunk_rbtree (&f->ooo_deq_lookup,
+ f->ooo_deq->start_byte);
+ }
+ else
+ tmp = svm_fifo_find_chunk (f, f->ooo_deq->start_byte);
+ if (tmp != f->ooo_deq)
+ return 0;
+ }
+ if (f->ooo_enq)
+ {
+ if (rb_tree_is_init (&f->ooo_enq_lookup))
+ {
+ if (f_pos_lt (f->ooo_enq->start_byte, f->start_chunk->start_byte)
+ || f_pos_gt (f->ooo_enq->start_byte,
+ f_chunk_end (f->end_chunk)))
+ return 0;
+
+ tmp = f_find_chunk_rbtree (&f->ooo_enq_lookup,
+ f->ooo_enq->start_byte);
+ }
+ else
+ {
+ tmp = svm_fifo_find_next_chunk (f, f->tail_chunk,
+ f->ooo_enq->start_byte);
+ }
+ if (tmp != f->ooo_enq)
+ return 0;
+ }
+
+ if (f->start_chunk->next)
+ {
+ svm_fifo_chunk_t *c, *prev = 0, *tmp;
+ u32 chunks_bytes = 0;
+
+ c = f->start_chunk;
+ do
+ {
+ tmp = svm_fifo_find_chunk (f, c->start_byte);
+ if (tmp != c)
+ return 0;
+ if (prev && (prev->start_byte + prev->length != c->start_byte))
+ return 0;
+
+ if (c->enq_rb_index != RBTREE_TNIL_INDEX)
+ {
+ tmp = f_find_chunk_rbtree (&f->ooo_enq_lookup, c->start_byte);
+ if (tmp)
+ {
+ if (tmp != c)
+ return 0;
+ }
+ }
+ if (c->deq_rb_index != RBTREE_TNIL_INDEX)
+ {
+ tmp = f_find_chunk_rbtree (&f->ooo_deq_lookup, c->start_byte);
+ if (tmp)
+ {
+ if (tmp != c)
+ return 0;
+ }
+ }
+
+ chunks_bytes += c->length;
+ prev = c;
+ c = c->next;
+ }
+ while (c);
+
+ if (chunks_bytes < f->tail - f->head)
+ return 0;
+ }
+
+ return 1;
+}
+
+u32
+svm_fifo_n_chunks (svm_fifo_t * f)
+{
+ svm_fifo_chunk_t *c;
+ int n_chunks = 0;
+
+ c = f->start_chunk;
+ while (c)
+ {
+ n_chunks++;
+ c = c->next;
+ }
+
+ return n_chunks;
+}
+