MCPcopy Create free account
hub / github.com/F-Stack/f-stack / ifmp_ring_enqueue

Function ifmp_ring_enqueue

freebsd/net/mp_ring.c:320–393  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

318 */
319#ifdef MP_RING_NO_64BIT_ATOMICS
320int
321ifmp_ring_enqueue(struct ifmp_ring *r, void **items, int n, int budget, int abdicate)
322{
323 union ring_state os, ns;
324 uint16_t pidx_start, pidx_stop;
325 int i;
326
327 MPASS(items != NULL);
328 MPASS(n > 0);
329
330 mtx_lock(&r->lock);
331 /*
332 * Reserve room for the new items. Our reservation, if successful, is
333 * from 'pidx_start' to 'pidx_stop'.
334 */
335 os.state = r->state;
336 if (n >= space_available(r, os)) {
337 counter_u64_add(r->drops, n);
338 MPASS(os.flags != IDLE);
339 mtx_unlock(&r->lock);
340 if (os.flags == STALLED)
341 ifmp_ring_check_drainage(r, 0);
342 return (ENOBUFS);
343 }
344 ns.state = os.state;
345 ns.pidx_head = increment_idx(r, os.pidx_head, n);
346 r->state = ns.state;
347 pidx_start = os.pidx_head;
348 pidx_stop = ns.pidx_head;
349
350 /*
351 * Wait for other producers who got in ahead of us to enqueue their
352 * items, one producer at a time. It is our turn when the ring's
353 * pidx_tail reaches the beginning of our reservation (pidx_start).
354 */
355 while (ns.pidx_tail != pidx_start) {
356 cpu_spinwait();
357 ns.state = r->state;
358 }
359
360 /* Now it is our turn to fill up the area we reserved earlier. */
361 i = pidx_start;
362 do {
363 r->items[i] = *items++;
364 if (__predict_false(++i == r->size))
365 i = 0;
366 } while (i != pidx_stop);
367
368 /*
369 * Update the ring's pidx_tail. The release style atomic guarantees
370 * that the items are visible to any thread that sees the updated pidx.
371 */
372 os.state = ns.state = r->state;
373 ns.pidx_tail = pidx_stop;
374 if (abdicate) {
375 if (os.flags == IDLE)
376 ns.flags = ABDICATED;
377 } else

Callers 2

_task_fn_txFunction · 0.85
iflib_if_transmitFunction · 0.85

Calls 12

space_availableFunction · 0.85
ifmp_ring_check_drainageFunction · 0.85
increment_idxFunction · 0.85
drain_ring_lockedFunction · 0.85
atomic_fcmpset_rel_64Function · 0.85
drain_ring_locklessFunction · 0.85
mtx_lockFunction · 0.50
counter_u64_addFunction · 0.50
mtx_unlockFunction · 0.50
critical_enterFunction · 0.50
atomic_fcmpset_64Function · 0.50
critical_exitFunction · 0.50

Tested by

no test coverage detected