Commit d3c3589b authored by Paolo Bonzini's avatar Paolo Bonzini Committed by Michael S. Tsirkin

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: default avatarPaolo Bonzini <pbonzini@redhat.com>
Signed-off-by: default avatarMichael S. Tsirkin <mst@redhat.com>
parent 44d65ea1
...@@ -96,6 +96,12 @@ void set_affinity(const char *arg) ...@@ -96,6 +96,12 @@ void set_affinity(const char *arg)
assert(!ret); assert(!ret);
} }
void poll_used(void)
{
while (used_empty())
busy_wait();
}
static void __attribute__((__flatten__)) run_guest(void) static void __attribute__((__flatten__)) run_guest(void)
{ {
int completed_before; int completed_before;
...@@ -149,6 +155,12 @@ static void __attribute__((__flatten__)) run_guest(void) ...@@ -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) static void __attribute__((__flatten__)) run_host(void)
{ {
int completed_before; int completed_before;
......
...@@ -56,15 +56,15 @@ void alloc_ring(void); ...@@ -56,15 +56,15 @@ void alloc_ring(void);
int add_inbuf(unsigned, void *, void *); int add_inbuf(unsigned, void *, void *);
void *get_buf(unsigned *, void **); void *get_buf(unsigned *, void **);
void disable_call(); void disable_call();
bool used_empty();
bool enable_call(); bool enable_call();
void kick_available(); void kick_available();
void poll_used();
/* host side */ /* host side */
void disable_kick(); void disable_kick();
bool avail_empty();
bool enable_kick(); bool enable_kick();
bool use_buf(unsigned *, void **); bool use_buf(unsigned *, void **);
void call_used(); void call_used();
void poll_avail();
/* implemented by main */ /* implemented by main */
extern bool do_sleep; extern bool do_sleep;
......
...@@ -24,8 +24,9 @@ void *get_buf(unsigned *lenp, void **bufp) ...@@ -24,8 +24,9 @@ void *get_buf(unsigned *lenp, void **bufp)
return "Buffer"; return "Buffer";
} }
void poll_used(void) bool used_empty()
{ {
return false;
} }
void disable_call() void disable_call()
...@@ -54,8 +55,9 @@ bool enable_kick() ...@@ -54,8 +55,9 @@ bool enable_kick()
assert(0); assert(0);
} }
void poll_avail(void) bool avail_empty()
{ {
return false;
} }
bool use_buf(unsigned *lenp, void **bufp) bool use_buf(unsigned *lenp, void **bufp)
......
...@@ -133,18 +133,9 @@ void *get_buf(unsigned *lenp, void **bufp) ...@@ -133,18 +133,9 @@ void *get_buf(unsigned *lenp, void **bufp)
return datap; return datap;
} }
void poll_used(void) bool used_empty()
{ {
void *b; return (tailcnt == headcnt || __ptr_ring_full(&array));
do {
if (tailcnt == headcnt || __ptr_ring_full(&array)) {
b = NULL;
barrier();
} else {
b = "Buffer\n";
}
} while (!b);
} }
void disable_call() void disable_call()
...@@ -173,14 +164,9 @@ bool enable_kick() ...@@ -173,14 +164,9 @@ bool enable_kick()
assert(0); assert(0);
} }
void poll_avail(void) bool avail_empty()
{ {
void *b; return !__ptr_ring_peek(&array);
do {
barrier();
b = __ptr_ring_peek(&array);
} while (!b);
} }
bool use_buf(unsigned *lenp, void **bufp) bool use_buf(unsigned *lenp, void **bufp)
......
...@@ -163,12 +163,11 @@ void *get_buf(unsigned *lenp, void **bufp) ...@@ -163,12 +163,11 @@ void *get_buf(unsigned *lenp, void **bufp)
return datap; return datap;
} }
void poll_used(void) bool used_empty()
{ {
unsigned head = (ring_size - 1) & guest.last_used_idx; unsigned head = (ring_size - 1) & guest.last_used_idx;
while (ring[head].flags & DESC_HW) return (ring[head].flags & DESC_HW);
busy_wait();
} }
void disable_call() void disable_call()
...@@ -180,13 +179,11 @@ void disable_call() ...@@ -180,13 +179,11 @@ void disable_call()
bool enable_call() bool enable_call()
{ {
unsigned head = (ring_size - 1) & guest.last_used_idx;
event->call_index = guest.last_used_idx; event->call_index = guest.last_used_idx;
/* Flush call index write */ /* Flush call index write */
/* Barrier D (for pairing) */ /* Barrier D (for pairing) */
smp_mb(); smp_mb();
return ring[head].flags & DESC_HW; return used_empty();
} }
void kick_available(void) void kick_available(void)
...@@ -213,20 +210,17 @@ void disable_kick() ...@@ -213,20 +210,17 @@ void disable_kick()
bool enable_kick() bool enable_kick()
{ {
unsigned head = (ring_size - 1) & host.used_idx;
event->kick_index = host.used_idx; event->kick_index = host.used_idx;
/* Barrier C (for pairing) */ /* Barrier C (for pairing) */
smp_mb(); 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; unsigned head = (ring_size - 1) & host.used_idx;
while (!(ring[head].flags & DESC_HW)) return !(ring[head].flags & DESC_HW);
busy_wait();
} }
bool use_buf(unsigned *lenp, void **bufp) bool use_buf(unsigned *lenp, void **bufp)
......
...@@ -194,24 +194,16 @@ void *get_buf(unsigned *lenp, void **bufp) ...@@ -194,24 +194,16 @@ void *get_buf(unsigned *lenp, void **bufp)
return datap; return datap;
} }
void poll_used(void) bool used_empty()
{ {
unsigned short last_used_idx = guest.last_used_idx;
#ifdef RING_POLL #ifdef RING_POLL
unsigned head = (ring_size - 1) & guest.last_used_idx; unsigned short head = last_used_idx & (ring_size - 1);
for (;;) {
unsigned index = ring.used->ring[head].id; unsigned index = ring.used->ring[head].id;
if ((index ^ guest.last_used_idx ^ 0x8000) & ~(ring_size - 1)) return (index ^ last_used_idx ^ 0x8000) & ~(ring_size - 1);
busy_wait();
else
break;
}
#else #else
unsigned head = guest.last_used_idx; return ring.used->idx == last_used_idx;
while (ring.used->idx == head)
busy_wait();
#endif #endif
} }
...@@ -224,22 +216,11 @@ void disable_call() ...@@ -224,22 +216,11 @@ void disable_call()
bool enable_call() bool enable_call()
{ {
unsigned short last_used_idx; vring_used_event(&ring) = guest.last_used_idx;
vring_used_event(&ring) = (last_used_idx = guest.last_used_idx);
/* Flush call index write */ /* Flush call index write */
/* Barrier D (for pairing) */ /* Barrier D (for pairing) */
smp_mb(); smp_mb();
#ifdef RING_POLL return used_empty();
{
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
} }
void kick_available(void) void kick_available(void)
...@@ -266,36 +247,21 @@ void disable_kick() ...@@ -266,36 +247,21 @@ void disable_kick()
bool enable_kick() bool enable_kick()
{ {
unsigned head = host.used_idx; vring_avail_event(&ring) = host.used_idx;
vring_avail_event(&ring) = head;
/* Barrier C (for pairing) */ /* Barrier C (for pairing) */
smp_mb(); smp_mb();
#ifdef RING_POLL return avail_empty();
{
unsigned index = ring.avail->ring[head & (ring_size - 1)];
return (index ^ head ^ 0x8000) & ~(ring_size - 1);
}
#else
return head == ring.avail->idx;
#endif
} }
void poll_avail(void) bool avail_empty()
{ {
unsigned head = host.used_idx; unsigned head = host.used_idx;
#ifdef RING_POLL #ifdef RING_POLL
for (;;) {
unsigned index = ring.avail->ring[head & (ring_size - 1)]; unsigned index = ring.avail->ring[head & (ring_size - 1)];
if ((index ^ head ^ 0x8000) & ~(ring_size - 1))
busy_wait(); return ((index ^ head ^ 0x8000) & ~(ring_size - 1));
else
break;
}
#else #else
while (ring.avail->idx == head) return head == ring.avail->idx;
busy_wait();
#endif #endif
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment