+u32
+svm_fifo_segment_num_free_fifos (svm_fifo_segment_private_t * fifo_segment,
+ u32 fifo_size_in_bytes)
+{
+ ssvm_shared_header_t *sh;
+ svm_fifo_segment_header_t *fsh;
+ svm_fifo_t *f;
+ int i;
+ u32 count = 0, rounded_data_size, freelist_index;
+
+ sh = fifo_segment->ssvm.sh;
+ fsh = (svm_fifo_segment_header_t *) sh->opaque[0];
+
+ /* Count all free fifos? */
+ if (fifo_size_in_bytes == ~0)
+ {
+ for (i = 0; i < vec_len (fsh->free_fifos); i++)
+ {
+ f = fsh->free_fifos[i];
+ if (f == 0)
+ continue;
+
+ while (f)
+ {
+ f = f->next;
+ count++;
+ }
+ }
+ return count;
+ }
+
+ rounded_data_size = (1 << (max_log2 (fifo_size_in_bytes)));
+ freelist_index = max_log2 (rounded_data_size)
+ - max_log2 (FIFO_SEGMENT_MIN_FIFO_SIZE);
+
+ if (freelist_index > vec_len (fsh->free_fifos))
+ return 0;
+
+ f = fsh->free_fifos[freelist_index];
+ if (f == 0)
+ return 0;
+
+ while (f)
+ {
+ f = f->next;
+ count++;
+ }
+ return count;
+}
+
+void
+svm_fifo_segment_info (svm_fifo_segment_private_t * seg, uword * address,
+ u64 * size)
+{
+ if (seg->h->flags & FIFO_SEGMENT_F_IS_PRIVATE)
+ {
+ mheap_t *heap_header;
+
+ *address = pointer_to_uword (seg->ssvm.sh->heap);
+ heap_header = mheap_header (seg->ssvm.sh->heap);
+ *size = heap_header->max_size;
+ }
+ else
+ {
+ *address = seg->ssvm.sh->ssvm_va;
+ *size = seg->ssvm.ssvm_size;
+ }
+}
+
+mheap_t *
+svm_fifo_segment_heap (svm_fifo_segment_private_t * seg)
+{
+ return seg->ssvm.sh->heap;
+}
+
+u8 *
+format_svm_fifo_segment_type (u8 * s, va_list * args)
+{
+ svm_fifo_segment_private_t *sp;
+ sp = va_arg (*args, svm_fifo_segment_private_t *);
+ ssvm_segment_type_t st = ssvm_type (&sp->ssvm);
+
+ if ((sp->h->flags & FIFO_SEGMENT_F_IS_PRIVATE)
+ && !(sp->h->flags & FIFO_SEGMENT_F_IS_MAIN_HEAP))
+ s = format (s, "%s", "private-heap");
+ else if ((sp->h->flags & FIFO_SEGMENT_F_IS_PRIVATE)
+ && (sp->h->flags & FIFO_SEGMENT_F_IS_MAIN_HEAP))
+ s = format (s, "%s", "main-heap");
+ else if (st == SSVM_SEGMENT_MEMFD)
+ s = format (s, "%s", "memfd");
+ else if (st == SSVM_SEGMENT_SHM)
+ s = format (s, "%s", "shm");
+ else
+ s = format (s, "%s", "unknown");
+ return s;
+}
+
+/**
+ * Segment format function
+ */
+u8 *
+format_svm_fifo_segment (u8 * s, va_list * args)
+{
+ svm_fifo_segment_private_t *sp
+ = va_arg (*args, svm_fifo_segment_private_t *);
+ int verbose = va_arg (*args, int);
+ svm_fifo_segment_header_t *fsh = sp->h;
+ u32 count, indent;
+ svm_fifo_t *f;
+ int i;
+
+ indent = format_get_indent (s) + 2;
+ s = format (s, "%U segment heap: %U\n", format_white_space, indent,
+ format_mheap, svm_fifo_segment_heap (sp), verbose);
+ s = format (s, "%U segment has %u active fifos\n",
+ format_white_space, indent, svm_fifo_segment_num_fifos (sp));
+
+ for (i = 0; i < vec_len (fsh->free_fifos); i++)
+ {
+ f = fsh->free_fifos[i];
+ if (f == 0)
+ continue;
+ count = 0;
+ while (f)
+ {
+ f = f->next;
+ count++;
+ }
+
+ s = format (s, "%U%-5u Kb: %u free",
+ format_white_space, indent + 2,
+ 1 << (i + max_log2 (FIFO_SEGMENT_MIN_FIFO_SIZE) - 10),
+ count);
+ }
+ return s;
+}
+