Changeset View
Changeset View
Standalone View
Standalone View
sys/net/mp_ring.c
Show First 20 Lines • Show All 220 Lines • ▼ Show 20 Lines | while (cidx != pidx) { | ||||
/* | /* | ||||
* We update the cidx only if we've caught up with the pidx, the | * We update the cidx only if we've caught up with the pidx, the | ||||
* real cidx is getting too far ahead of the one visible to | * real cidx is getting too far ahead of the one visible to | ||||
* everyone else, or we have exceeded our budget. | * everyone else, or we have exceeded our budget. | ||||
*/ | */ | ||||
if (cidx != pidx && pending < 64 && total < budget) | if (cidx != pidx && pending < 64 && total < budget) | ||||
continue; | continue; | ||||
critical_enter(); | critical_enter(); | ||||
do { | |||||
os.state = ns.state = r->state; | os.state = ns.state = r->state; | ||||
ns.cidx = cidx; | ns.cidx = cidx; | ||||
ns.flags = state_to_flags(ns, total >= budget); | ns.flags = state_to_flags(ns, total >= budget); | ||||
} while (atomic_cmpset_acq_64(&r->state, os.state, ns.state) == 0); | while (atomic_cmpset_acq_64(&r->state, os.state, ns.state) == 0) { | ||||
cramerj_intel.com: Is this just a coding style preference? I guess I would prefer the do-while since the code… | |||||
Not Done Inline ActionsThe new code adds cpu_sinpwait() after failure. shurd: The new code adds cpu_sinpwait() after failure. | |||||
cpu_spinwait(); | |||||
os.state = ns.state = r->state; | |||||
ns.cidx = cidx; | |||||
ns.flags = state_to_flags(ns, total >= budget); | |||||
} | |||||
critical_exit(); | critical_exit(); | ||||
if (ns.flags == ABDICATED) | if (ns.flags == ABDICATED) | ||||
counter_u64_add(r->abdications, 1); | counter_u64_add(r->abdications, 1); | ||||
if (ns.flags != BUSY) { | if (ns.flags != BUSY) { | ||||
/* Wrong loop exit if we're going to stall. */ | /* Wrong loop exit if we're going to stall. */ | ||||
MPASS(ns.flags != STALLED); | MPASS(ns.flags != STALLED); | ||||
if (prev == STALLED) { | if (prev == STALLED) { | ||||
▲ Show 20 Lines • Show All 207 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 |
Is this just a coding style preference? I guess I would prefer the do-while since the code must be run at least once.