summaryrefslogtreecommitdiffstats
path: root/src/svm
diff options
context:
space:
mode:
Diffstat (limited to 'src/svm')
-rw-r--r--src/svm/svm_fifo.c27
-rw-r--r--src/svm/svm_fifo.h5
2 files changed, 22 insertions, 10 deletions
diff --git a/src/svm/svm_fifo.c b/src/svm/svm_fifo.c
index 2cce2bf50b3..22cb64eb475 100644
--- a/src/svm/svm_fifo.c
+++ b/src/svm/svm_fifo.c
@@ -1136,10 +1136,11 @@ svm_fifo_fill_chunk_list (svm_fifo_t * f)
}
int
-svm_fifo_segments (svm_fifo_t * f, svm_fifo_seg_t * fs, u32 n_segs,
- u32 max_bytes)
+svm_fifo_segments (svm_fifo_t * f, u32 offset, svm_fifo_seg_t * fs,
+ u32 n_segs, u32 max_bytes)
{
- u32 cursize, to_read, head, tail, fs_index = 1, n_bytes, head_pos, len;
+ u32 cursize, to_read, head, tail, fs_index = 1;
+ u32 n_bytes, head_pos, len, start;
svm_fifo_chunk_t *c;
f_load_head_tail_cons (f, &head, &tail);
@@ -1150,22 +1151,32 @@ svm_fifo_segments (svm_fifo_t * f, svm_fifo_seg_t * fs, u32 n_segs,
if (PREDICT_FALSE (cursize == 0))
return SVM_FIFO_EEMPTY;
- to_read = clib_min (cursize, max_bytes);
+ if (offset >= cursize)
+ return SVM_FIFO_EEMPTY;
+
+ to_read = clib_min (cursize - offset, max_bytes);
+ start = head + offset;
+
+ if (!f->head_chunk)
+ f->head_chunk = svm_fifo_find_chunk (f, head);
c = f->head_chunk;
- head_pos = head - c->start_byte;
+
+ while (!f_chunk_includes_pos (c, start))
+ c = c->next;
+
+ head_pos = start - c->start_byte;
fs[0].data = c->data + head_pos;
- fs[0].len = c->length - head_pos;
+ fs[0].len = clib_min (c->length - head_pos, cursize - offset);
n_bytes = fs[0].len;
- c = c->next;
while (n_bytes < to_read && fs_index < n_segs)
{
+ c = c->next;
len = clib_min (c->length, to_read - n_bytes);
fs[fs_index].data = c->data;
fs[fs_index].len = len;
n_bytes += len;
- c = c->next;
fs_index += 1;
}
diff --git a/src/svm/svm_fifo.h b/src/svm/svm_fifo.h
index 93ef006fd48..408d99a3188 100644
--- a/src/svm/svm_fifo.h
+++ b/src/svm/svm_fifo.h
@@ -357,13 +357,14 @@ void svm_fifo_dequeue_drop_all (svm_fifo_t * f);
* data is consumed.
*
* @param f fifo
+ * @param offset offset from where to retrieve segments
* @param fs array of fifo segments allocated by caller
* @param n_segs number of fifo segments in array
* @param max_bytes max bytes to be mapped to fifo segments
* @return number of bytes in fifo segments or SVM_FIFO_EEMPTY
*/
-int svm_fifo_segments (svm_fifo_t * f, svm_fifo_seg_t * fs, u32 n_segs,
- u32 max_bytes);
+int svm_fifo_segments (svm_fifo_t * f, u32 offset, svm_fifo_seg_t * fs,
+ u32 n_segs, u32 max_bytes);
/**
* Add io events subscriber to list
*