forked from Minki/linux
ringtest: commonize implementation of poll_avail/poll_used
Provide new primitives used_empty/avail_empty and build poll_avail/poll_used on top of it. Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
This commit is contained in:
parent
44d65ea161
commit
d3c3589b8b
@ -96,6 +96,12 @@ void set_affinity(const char *arg)
|
||||
assert(!ret);
|
||||
}
|
||||
|
||||
void poll_used(void)
|
||||
{
|
||||
while (used_empty())
|
||||
busy_wait();
|
||||
}
|
||||
|
||||
static void __attribute__((__flatten__)) run_guest(void)
|
||||
{
|
||||
int completed_before;
|
||||
@ -149,6 +155,12 @@ static void __attribute__((__flatten__)) run_guest(void)
|
||||
}
|
||||
}
|
||||
|
||||
void poll_avail(void)
|
||||
{
|
||||
while (avail_empty())
|
||||
busy_wait();
|
||||
}
|
||||
|
||||
static void __attribute__((__flatten__)) run_host(void)
|
||||
{
|
||||
int completed_before;
|
||||
|
@ -56,15 +56,15 @@ void alloc_ring(void);
|
||||
int add_inbuf(unsigned, void *, void *);
|
||||
void *get_buf(unsigned *, void **);
|
||||
void disable_call();
|
||||
bool used_empty();
|
||||
bool enable_call();
|
||||
void kick_available();
|
||||
void poll_used();
|
||||
/* host side */
|
||||
void disable_kick();
|
||||
bool avail_empty();
|
||||
bool enable_kick();
|
||||
bool use_buf(unsigned *, void **);
|
||||
void call_used();
|
||||
void poll_avail();
|
||||
|
||||
/* implemented by main */
|
||||
extern bool do_sleep;
|
||||
|
@ -24,8 +24,9 @@ void *get_buf(unsigned *lenp, void **bufp)
|
||||
return "Buffer";
|
||||
}
|
||||
|
||||
void poll_used(void)
|
||||
bool used_empty()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
void disable_call()
|
||||
@ -54,8 +55,9 @@ bool enable_kick()
|
||||
assert(0);
|
||||
}
|
||||
|
||||
void poll_avail(void)
|
||||
bool avail_empty()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool use_buf(unsigned *lenp, void **bufp)
|
||||
|
@ -133,18 +133,9 @@ void *get_buf(unsigned *lenp, void **bufp)
|
||||
return datap;
|
||||
}
|
||||
|
||||
void poll_used(void)
|
||||
bool used_empty()
|
||||
{
|
||||
void *b;
|
||||
|
||||
do {
|
||||
if (tailcnt == headcnt || __ptr_ring_full(&array)) {
|
||||
b = NULL;
|
||||
barrier();
|
||||
} else {
|
||||
b = "Buffer\n";
|
||||
}
|
||||
} while (!b);
|
||||
return (tailcnt == headcnt || __ptr_ring_full(&array));
|
||||
}
|
||||
|
||||
void disable_call()
|
||||
@ -173,14 +164,9 @@ bool enable_kick()
|
||||
assert(0);
|
||||
}
|
||||
|
||||
void poll_avail(void)
|
||||
bool avail_empty()
|
||||
{
|
||||
void *b;
|
||||
|
||||
do {
|
||||
barrier();
|
||||
b = __ptr_ring_peek(&array);
|
||||
} while (!b);
|
||||
return !__ptr_ring_peek(&array);
|
||||
}
|
||||
|
||||
bool use_buf(unsigned *lenp, void **bufp)
|
||||
|
@ -163,12 +163,11 @@ void *get_buf(unsigned *lenp, void **bufp)
|
||||
return datap;
|
||||
}
|
||||
|
||||
void poll_used(void)
|
||||
bool used_empty()
|
||||
{
|
||||
unsigned head = (ring_size - 1) & guest.last_used_idx;
|
||||
|
||||
while (ring[head].flags & DESC_HW)
|
||||
busy_wait();
|
||||
return (ring[head].flags & DESC_HW);
|
||||
}
|
||||
|
||||
void disable_call()
|
||||
@ -180,13 +179,11 @@ void disable_call()
|
||||
|
||||
bool enable_call()
|
||||
{
|
||||
unsigned head = (ring_size - 1) & guest.last_used_idx;
|
||||
|
||||
event->call_index = guest.last_used_idx;
|
||||
/* Flush call index write */
|
||||
/* Barrier D (for pairing) */
|
||||
smp_mb();
|
||||
return ring[head].flags & DESC_HW;
|
||||
return used_empty();
|
||||
}
|
||||
|
||||
void kick_available(void)
|
||||
@ -213,20 +210,17 @@ void disable_kick()
|
||||
|
||||
bool enable_kick()
|
||||
{
|
||||
unsigned head = (ring_size - 1) & host.used_idx;
|
||||
|
||||
event->kick_index = host.used_idx;
|
||||
/* Barrier C (for pairing) */
|
||||
smp_mb();
|
||||
return !(ring[head].flags & DESC_HW);
|
||||
return avail_empty();
|
||||
}
|
||||
|
||||
void poll_avail(void)
|
||||
bool avail_empty()
|
||||
{
|
||||
unsigned head = (ring_size - 1) & host.used_idx;
|
||||
|
||||
while (!(ring[head].flags & DESC_HW))
|
||||
busy_wait();
|
||||
return !(ring[head].flags & DESC_HW);
|
||||
}
|
||||
|
||||
bool use_buf(unsigned *lenp, void **bufp)
|
||||
|
@ -194,24 +194,16 @@ void *get_buf(unsigned *lenp, void **bufp)
|
||||
return datap;
|
||||
}
|
||||
|
||||
void poll_used(void)
|
||||
bool used_empty()
|
||||
{
|
||||
unsigned short last_used_idx = guest.last_used_idx;
|
||||
#ifdef RING_POLL
|
||||
unsigned head = (ring_size - 1) & guest.last_used_idx;
|
||||
unsigned short head = last_used_idx & (ring_size - 1);
|
||||
unsigned index = ring.used->ring[head].id;
|
||||
|
||||
for (;;) {
|
||||
unsigned index = ring.used->ring[head].id;
|
||||
|
||||
if ((index ^ guest.last_used_idx ^ 0x8000) & ~(ring_size - 1))
|
||||
busy_wait();
|
||||
else
|
||||
break;
|
||||
}
|
||||
return (index ^ last_used_idx ^ 0x8000) & ~(ring_size - 1);
|
||||
#else
|
||||
unsigned head = guest.last_used_idx;
|
||||
|
||||
while (ring.used->idx == head)
|
||||
busy_wait();
|
||||
return ring.used->idx == last_used_idx;
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -224,22 +216,11 @@ void disable_call()
|
||||
|
||||
bool enable_call()
|
||||
{
|
||||
unsigned short last_used_idx;
|
||||
|
||||
vring_used_event(&ring) = (last_used_idx = guest.last_used_idx);
|
||||
vring_used_event(&ring) = guest.last_used_idx;
|
||||
/* Flush call index write */
|
||||
/* Barrier D (for pairing) */
|
||||
smp_mb();
|
||||
#ifdef RING_POLL
|
||||
{
|
||||
unsigned short head = last_used_idx & (ring_size - 1);
|
||||
unsigned index = ring.used->ring[head].id;
|
||||
|
||||
return (index ^ last_used_idx ^ 0x8000) & ~(ring_size - 1);
|
||||
}
|
||||
#else
|
||||
return ring.used->idx == last_used_idx;
|
||||
#endif
|
||||
return used_empty();
|
||||
}
|
||||
|
||||
void kick_available(void)
|
||||
@ -266,36 +247,21 @@ void disable_kick()
|
||||
|
||||
bool enable_kick()
|
||||
{
|
||||
unsigned head = host.used_idx;
|
||||
|
||||
vring_avail_event(&ring) = head;
|
||||
vring_avail_event(&ring) = host.used_idx;
|
||||
/* Barrier C (for pairing) */
|
||||
smp_mb();
|
||||
#ifdef RING_POLL
|
||||
{
|
||||
unsigned index = ring.avail->ring[head & (ring_size - 1)];
|
||||
|
||||
return (index ^ head ^ 0x8000) & ~(ring_size - 1);
|
||||
}
|
||||
#else
|
||||
return head == ring.avail->idx;
|
||||
#endif
|
||||
return avail_empty();
|
||||
}
|
||||
|
||||
void poll_avail(void)
|
||||
bool avail_empty()
|
||||
{
|
||||
unsigned head = host.used_idx;
|
||||
#ifdef RING_POLL
|
||||
for (;;) {
|
||||
unsigned index = ring.avail->ring[head & (ring_size - 1)];
|
||||
if ((index ^ head ^ 0x8000) & ~(ring_size - 1))
|
||||
busy_wait();
|
||||
else
|
||||
break;
|
||||
}
|
||||
unsigned index = ring.avail->ring[head & (ring_size - 1)];
|
||||
|
||||
return ((index ^ head ^ 0x8000) & ~(ring_size - 1));
|
||||
#else
|
||||
while (ring.avail->idx == head)
|
||||
busy_wait();
|
||||
return head == ring.avail->idx;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user