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:
Paolo Bonzini 2016-10-06 11:39:11 +02:00 committed by Michael S. Tsirkin
parent 44d65ea161
commit d3c3589b8b
6 changed files with 43 additions and 83 deletions

View File

@ -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;

View File

@ -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;

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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
}