23 pthread_mutexattr_t attr;
24 pthread_condattr_t cattr;
31 memset (f, 0,
sizeof (*f) + data_size_in_bytes);
32 f->
nitems = data_size_in_bytes;
35 memset (&attr, 0,
sizeof (attr));
36 memset (&cattr, 0,
sizeof (cattr));
38 if (pthread_mutexattr_init (&attr))
40 if (pthread_mutexattr_setpshared (&attr, PTHREAD_PROCESS_SHARED))
42 if (pthread_mutex_init (&f->
mutex, &attr))
44 if (pthread_mutexattr_destroy (&attr))
46 if (pthread_condattr_init (&cattr))
48 if (pthread_condattr_setpshared (&cattr, PTHREAD_PROCESS_SHARED))
50 if (pthread_cond_init (&f->
condvar, &cattr))
52 if (pthread_condattr_destroy (&cattr))
82 next->prev = cur->
prev;
106 u32 new_index, position, end_offset, s_sof, s_eof, s_index;
109 end_offset = offset + length;
130 if (end_offset < s_sof)
143 prev->
next = new_index;
157 else if (s_eof < offset)
170 next->
prev = new_index;
208 if (s_eof < end_offset)
225 if (it && ooo_segment_offset (f, it) < end_offset)
234 else if (s_eof <= end_offset)
256 u32 index, bytes = 0, diff;
262 while (0 < diff && diff < n_bytes_enqueued)
265 if (diff < s->length)
303 int pid,
u32 max_bytes,
u8 * copy_from_here)
305 u32 total_copy_bytes, first_copy_bytes, second_copy_bytes;
316 total_copy_bytes = (nitems - cursize) < max_bytes ?
317 (nitems - cursize) : max_bytes;
322 first_copy_bytes = ((nitems - f->
tail) < total_copy_bytes)
323 ? (nitems - f->
tail) : total_copy_bytes;
326 f->
tail += first_copy_bytes;
330 second_copy_bytes = total_copy_bytes - first_copy_bytes;
331 if (second_copy_bytes)
335 f->
tail += second_copy_bytes;
342 ASSERT (max_bytes <= (nitems - cursize));
343 f->
tail += max_bytes;
345 total_copy_bytes = max_bytes;
353 __sync_fetch_and_add (&f->
cursize, total_copy_bytes);
355 return (total_copy_bytes);
360 int pid,
u32 max_bytes,
u8 * copy_from_here)
378 u32 total_copy_bytes, first_copy_bytes, second_copy_bytes;
380 u32 tail_plus_offset;
389 if ((required_bytes + offset) > (nitems - cursize))
395 total_copy_bytes = required_bytes;
396 tail_plus_offset = (f->
tail +
offset) % nitems;
399 first_copy_bytes = ((nitems - tail_plus_offset) < total_copy_bytes)
400 ? (nitems - tail_plus_offset) : total_copy_bytes;
402 clib_memcpy (&f->data[tail_plus_offset], copy_from_here, first_copy_bytes);
405 second_copy_bytes = total_copy_bytes - first_copy_bytes;
406 if (second_copy_bytes)
408 tail_plus_offset += first_copy_bytes;
409 tail_plus_offset %= nitems;
411 ASSERT (tail_plus_offset == 0);
414 copy_from_here + first_copy_bytes, second_copy_bytes);
425 u32 required_bytes,
u8 * copy_from_here)
428 (f, pid, offset, required_bytes, copy_from_here);
434 int pid,
u32 max_bytes,
u8 * copy_here)
436 u32 total_copy_bytes, first_copy_bytes, second_copy_bytes;
447 total_copy_bytes = (cursize < max_bytes) ? cursize : max_bytes;
452 first_copy_bytes = ((nitems - f->
head) < total_copy_bytes)
453 ? (nitems - f->
head) : total_copy_bytes;
455 f->
head += first_copy_bytes;
459 second_copy_bytes = total_copy_bytes - first_copy_bytes;
460 if (second_copy_bytes)
463 &f->data[f->
head], second_copy_bytes);
464 f->
head += second_copy_bytes;
471 ASSERT (max_bytes <= cursize);
472 f->
head += max_bytes;
474 cursize -= max_bytes;
475 total_copy_bytes = max_bytes;
478 __sync_fetch_and_sub (&f->
cursize, total_copy_bytes);
480 return (total_copy_bytes);
485 int pid,
u32 max_bytes,
u8 * copy_here)
494 u32 total_copy_bytes, first_copy_bytes, second_copy_bytes;
505 total_copy_bytes = (cursize < max_bytes) ? cursize : max_bytes;
511 ((nitems - f->
head +
offset) < total_copy_bytes) ?
512 (nitems - f->
head +
offset) : total_copy_bytes;
516 second_copy_bytes = total_copy_bytes - first_copy_bytes;
517 if (second_copy_bytes)
519 clib_memcpy (copy_here + first_copy_bytes, &f->data[0],
523 return total_copy_bytes;
529 u32 total_drop_bytes, first_drop_bytes, second_drop_bytes;
540 total_drop_bytes = (cursize < max_bytes) ? cursize : max_bytes;
544 ((nitems - f->
head) < total_drop_bytes) ?
545 (nitems - f->
head) : total_drop_bytes;
546 f->
head += first_drop_bytes;
550 second_drop_bytes = total_drop_bytes - first_drop_bytes;
551 if (second_drop_bytes)
553 f->
head += second_drop_bytes;
557 __sync_fetch_and_sub (&f->
cursize, total_drop_bytes);
559 return total_drop_bytes;
int svm_fifo_enqueue_nowait(svm_fifo_t *f, int pid, u32 max_bytes, u8 *copy_from_here)
u32 prev
Previous linked-list element pool index.
static int ooo_segment_try_collect(svm_fifo_t *f, u32 n_bytes_enqueued)
Removes segments that can now be enqueued because the fifo's tail has advanced.
#define pool_get(P, E)
Allocate an object E from a pool P (unspecified alignment).
static void ooo_segment_add(svm_fifo_t *f, u32 offset, u32 length)
Add segment to fifo's out-of-order segment list.
static u32 ooo_segment_end_offset(svm_fifo_t *f, ooo_segment_t *s)
static int svm_fifo_enqueue_internal(svm_fifo_t *f, int pid, u32 max_bytes, u8 *copy_from_here)
u32 ooos_newest
Last segment to have been updated.
ooo_segment_t * ooo_segments
Pool of ooo segments.
static int svm_fifo_dequeue_internal2(svm_fifo_t *f, int pid, u32 max_bytes, u8 *copy_here)
#define pool_elt_at_index(p, i)
Returns pointer to element at given index.
static u32 ooo_segment_offset(svm_fifo_t *f, ooo_segment_t *s)
int svm_fifo_dequeue_drop(svm_fifo_t *f, int pid, u32 max_bytes)
#define pool_put(P, E)
Free an object E in pool P.
#define clib_memcpy(a, b, c)
static int svm_fifo_enqueue_with_offset_internal2(svm_fifo_t *f, int pid, u32 offset, u32 required_bytes, u8 *copy_from_here)
Enqueue a future segment.
static void ooo_segment_del(svm_fifo_t *f, u32 index)
#define OOO_SEGMENT_INVALID_INDEX
static void * clib_mem_alloc_aligned_or_null(uword size, uword align)
int svm_fifo_enqueue_with_offset(svm_fifo_t *f, int pid, u32 offset, u32 required_bytes, u8 *copy_from_here)
u32 fifo_position
Start of segment, normalized.
u32 ooos_list_head
Head of out-of-order linked-list.
u32 length
Length of segment.
u32 next
Next linked-list element pool index.
template key/value backing page structure
int svm_fifo_peek(svm_fifo_t *f, int pid, u32 offset, u32 max_bytes, u8 *copy_here)
static ooo_segment_t * ooo_segment_new(svm_fifo_t *f, u32 start, u32 length)
#define clib_unix_warning(format, args...)
struct clib_bihash_value offset
template key/value backing page structure
int svm_fifo_dequeue_nowait(svm_fifo_t *f, int pid, u32 max_bytes, u8 *copy_here)
#define CLIB_CACHE_LINE_BYTES
svm_fifo_t * svm_fifo_create(u32 data_size_in_bytes)
create an svm fifo, in the current heap.