summaryrefslogtreecommitdiffstats
path: root/src/svm/svm_fifo.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/svm/svm_fifo.c')
-rw-r--r--src/svm/svm_fifo.c27
1 files changed, 19 insertions, 8 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;
}