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>
diff --git a/tools/virtio/ringtest/main.c b/tools/virtio/ringtest/main.c
index bda7f0d..b00ecd6 100644
--- a/tools/virtio/ringtest/main.c
+++ b/tools/virtio/ringtest/main.c
@@ -96,6 +96,12 @@
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 @@
}
}
+void poll_avail(void)
+{
+ while (avail_empty())
+ busy_wait();
+}
+
static void __attribute__((__flatten__)) run_host(void)
{
int completed_before;
diff --git a/tools/virtio/ringtest/main.h b/tools/virtio/ringtest/main.h
index 16917ac..34e63cc 100644
--- a/tools/virtio/ringtest/main.h
+++ b/tools/virtio/ringtest/main.h
@@ -56,15 +56,15 @@
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;
diff --git a/tools/virtio/ringtest/noring.c b/tools/virtio/ringtest/noring.c
index eda2f48..b8d1c1d 100644
--- a/tools/virtio/ringtest/noring.c
+++ b/tools/virtio/ringtest/noring.c
@@ -24,8 +24,9 @@
return "Buffer";
}
-void poll_used(void)
+bool used_empty()
{
+ return false;
}
void disable_call()
@@ -54,8 +55,9 @@
assert(0);
}
-void poll_avail(void)
+bool avail_empty()
{
+ return false;
}
bool use_buf(unsigned *lenp, void **bufp)
diff --git a/tools/virtio/ringtest/ptr_ring.c b/tools/virtio/ringtest/ptr_ring.c
index bd2ad1d..635b07b 100644
--- a/tools/virtio/ringtest/ptr_ring.c
+++ b/tools/virtio/ringtest/ptr_ring.c
@@ -133,18 +133,9 @@
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 @@
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)
diff --git a/tools/virtio/ringtest/ring.c b/tools/virtio/ringtest/ring.c
index c25c8d2..747c5dd 100644
--- a/tools/virtio/ringtest/ring.c
+++ b/tools/virtio/ringtest/ring.c
@@ -163,12 +163,11 @@
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 @@
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 @@
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)
diff --git a/tools/virtio/ringtest/virtio_ring_0_9.c b/tools/virtio/ringtest/virtio_ring_0_9.c
index 7618662..bbc3043 100644
--- a/tools/virtio/ringtest/virtio_ring_0_9.c
+++ b/tools/virtio/ringtest/virtio_ring_0_9.c
@@ -194,24 +194,16 @@
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 @@
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 @@
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
}