+
+ nf->shr->slice_index = slice_index;
+ *f = nf;
+}
+
+uword
+fifo_segment_fifo_offset (svm_fifo_t *f)
+{
+ return (u8 *) f->shr - (u8 *) f->fs_hdr;
+}
+
+svm_fifo_chunk_t *
+fifo_segment_alloc_chunk_w_slice (fifo_segment_t *fs, u32 slice_index,
+ u32 chunk_size)
+{
+ fifo_segment_header_t *fsh = fs->h;
+ fifo_segment_slice_t *fss;
+
+ fss = fsh_slice_get (fsh, slice_index);
+ return fsh_try_alloc_chunk (fsh, fss, chunk_size);
+}
+
+void
+fifo_segment_collect_chunk (fifo_segment_t *fs, u32 slice_index,
+ svm_fifo_chunk_t *c)
+{
+ fsh_collect_chunks (fs->h, slice_index, c);
+}
+
+uword
+fifo_segment_chunk_offset (fifo_segment_t *fs, svm_fifo_chunk_t *c)
+{
+ return (u8 *) c - (u8 *) fs->h;
+}
+
+svm_msg_q_t *
+fifo_segment_msg_q_alloc (fifo_segment_t *fs, u32 mq_index,
+ svm_msg_q_cfg_t *cfg)
+{
+ fifo_segment_header_t *fsh = fs->h;
+ svm_msg_q_shared_t *smq;
+ svm_msg_q_t *mq;
+ void *base;
+ u32 size;
+
+ if (!fs->mqs)
+ {
+ u32 n_mqs = clib_max (fs->h->n_mqs, 1);
+ vec_validate (fs->mqs, n_mqs - 1);
+ }
+
+ size = svm_msg_q_size_to_alloc (cfg);
+ base = fsh_alloc_aligned (fsh, size, 8);
+ fsh->n_reserved_bytes += size;
+
+ smq = svm_msg_q_init (base, cfg);
+ mq = vec_elt_at_index (fs->mqs, mq_index);
+ svm_msg_q_attach (mq, smq);
+
+ return mq;
+}
+
+svm_msg_q_t *
+fifo_segment_msg_q_attach (fifo_segment_t *fs, uword offset, u32 mq_index)
+{
+ svm_msg_q_t *mq;
+
+ if (!fs->mqs)
+ {
+ u32 n_mqs = clib_max (fs->h->n_mqs, 1);
+ vec_validate (fs->mqs, n_mqs - 1);
+ }
+
+ mq = vec_elt_at_index (fs->mqs, mq_index);
+
+ if (!mq->q.shr)
+ {
+ svm_msg_q_shared_t *smq;
+ smq = (svm_msg_q_shared_t *) ((u8 *) fs->h + offset);
+ svm_msg_q_attach (mq, smq);
+ }
+
+ ASSERT (fifo_segment_msg_q_offset (fs, mq_index) == offset);
+
+ return mq;
+}
+
+void
+fifo_segment_msg_qs_discover (fifo_segment_t *fs, int *fds, u32 n_fds)
+{
+ svm_msg_q_shared_t *smq;
+ u32 n_mqs, size, i;
+ uword offset = 0, n_alloced;
+ svm_msg_q_t *mq;
+
+ n_mqs = fs->h->n_mqs;
+ if (n_fds && n_mqs != n_fds)
+ {
+ clib_warning ("expected %u fds got %u", n_mqs, n_fds);
+ return;
+ }
+
+ vec_validate (fs->mqs, n_mqs - 1);
+ n_alloced = fs->h->n_reserved_bytes - fs->h->start_byte_index;
+ ASSERT (n_alloced % n_mqs == 0);
+ size = n_alloced / n_mqs;
+
+ offset = fs->h->start_byte_index;
+ for (i = 0; i < n_mqs; i++)
+ {
+ mq = vec_elt_at_index (fs->mqs, i);
+ smq = (svm_msg_q_shared_t *) ((u8 *) fs->h + offset);
+ svm_msg_q_attach (mq, smq);
+ if (n_fds)
+ svm_msg_q_set_eventfd (mq, fds[i]);
+ offset += size;
+ }
+}
+
+uword
+fifo_segment_msg_q_offset (fifo_segment_t *fs, u32 mq_index)
+{
+ svm_msg_q_t *mq = vec_elt_at_index (fs->mqs, mq_index);
+
+ if (mq->q.shr == 0)
+ return ~0ULL;
+
+ return (uword) ((u8 *) mq->q.shr - (u8 *) fs->h) -
+ sizeof (svm_msg_q_shared_t);