Changeset View
Changeset View
Standalone View
Standalone View
sys/net/mp_ring.c
Show First 20 Lines • Show All 448 Lines • ▼ Show 20 Lines | ifmp_ring_enqueue(struct ifmp_ring *r, void **items, int n, int budget) | ||||
/* | /* | ||||
* Update the ring's pidx_tail. The release style atomic guarantees | * Update the ring's pidx_tail. The release style atomic guarantees | ||||
* that the items are visible to any thread that sees the updated pidx. | * that the items are visible to any thread that sees the updated pidx. | ||||
*/ | */ | ||||
do { | do { | ||||
os.state = ns.state = r->state; | os.state = ns.state = r->state; | ||||
ns.pidx_tail = pidx_stop; | ns.pidx_tail = pidx_stop; | ||||
ns.flags = BUSY; | if (os.flags == IDLE) | ||||
ns.flags = ABDICATED; | |||||
} while (atomic_cmpset_rel_64(&r->state, os.state, ns.state) == 0); | } while (atomic_cmpset_rel_64(&r->state, os.state, ns.state) == 0); | ||||
critical_exit(); | critical_exit(); | ||||
counter_u64_add(r->enqueues, n); | counter_u64_add(r->enqueues, n); | ||||
/* | |||||
* Turn into a consumer if some other thread isn't active as a consumer | |||||
* already. | |||||
*/ | |||||
if (os.flags != BUSY) | |||||
drain_ring_lockless(r, ns, os.flags, budget); | |||||
return (0); | return (0); | ||||
} | } | ||||
#endif | #endif | ||||
void | void | ||||
ifmp_ring_check_drainage(struct ifmp_ring *r, int budget) | ifmp_ring_check_drainage(struct ifmp_ring *r, int budget) | ||||
{ | { | ||||
union ring_state os, ns; | union ring_state os, ns; | ||||
os.state = r->state; | os.state = r->state; | ||||
if (os.flags != STALLED || os.pidx_head != os.pidx_tail || r->can_drain(r) == 0) | if ((os.flags != STALLED && os.flags != ABDICATED) || // Only continue in STALLED and ABDICATED | ||||
os.pidx_head != os.pidx_tail || // Require work to be available | |||||
(os.flags != ABDICATED && r->can_drain(r) == 0)) // Can either drain, or everyone left | |||||
return; | return; | ||||
MPASS(os.cidx != os.pidx_tail); /* implied by STALLED */ | MPASS(os.cidx != os.pidx_tail); /* implied by STALLED */ | ||||
ns.state = os.state; | ns.state = os.state; | ||||
ns.flags = BUSY; | ns.flags = BUSY; | ||||
#ifdef NO_64BIT_ATOMICS | #ifdef NO_64BIT_ATOMICS | ||||
▲ Show 20 Lines • Show All 57 Lines • Show Last 20 Lines |