-
-
Notifications
You must be signed in to change notification settings - Fork 106
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add ringtest based unit test for ptr ring. Signed-off-by: Michael S. Tsirkin <mst@redhat.com> Signed-off-by: David S. Miller <davem@davemloft.net>
- Loading branch information
Showing
2 changed files
with
196 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,25 +1,28 @@ | ||
all: | ||
|
||
all: ring virtio_ring_0_9 virtio_ring_poll virtio_ring_inorder | ||
all: ring virtio_ring_0_9 virtio_ring_poll virtio_ring_inorder ptr_ring | ||
|
||
CFLAGS += -Wall | ||
CFLAGS += -pthread -O2 -ggdb | ||
LDFLAGS += -pthread -O2 -ggdb | ||
|
||
main.o: main.c main.h | ||
ring.o: ring.c main.h | ||
ptr_ring.o: ptr_ring.c main.h ../../../include/linux/ptr_ring.h | ||
virtio_ring_0_9.o: virtio_ring_0_9.c main.h | ||
virtio_ring_poll.o: virtio_ring_poll.c virtio_ring_0_9.c main.h | ||
virtio_ring_inorder.o: virtio_ring_inorder.c virtio_ring_0_9.c main.h | ||
ring: ring.o main.o | ||
virtio_ring_0_9: virtio_ring_0_9.o main.o | ||
virtio_ring_poll: virtio_ring_poll.o main.o | ||
virtio_ring_inorder: virtio_ring_inorder.o main.o | ||
ptr_ring: ptr_ring.o main.o | ||
clean: | ||
-rm main.o | ||
-rm ring.o ring | ||
-rm virtio_ring_0_9.o virtio_ring_0_9 | ||
-rm virtio_ring_poll.o virtio_ring_poll | ||
-rm virtio_ring_inorder.o virtio_ring_inorder | ||
-rm ptr_ring.o ptr_ring | ||
|
||
.PHONY: all clean |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,192 @@ | ||
#define _GNU_SOURCE | ||
#include "main.h" | ||
#include <stdlib.h> | ||
#include <stdio.h> | ||
#include <string.h> | ||
#include <pthread.h> | ||
#include <malloc.h> | ||
#include <assert.h> | ||
#include <errno.h> | ||
#include <limits.h> | ||
|
||
#define SMP_CACHE_BYTES 64 | ||
#define cache_line_size() SMP_CACHE_BYTES | ||
#define ____cacheline_aligned_in_smp __attribute__ ((aligned (SMP_CACHE_BYTES))) | ||
#define unlikely(x) (__builtin_expect(!!(x), 0)) | ||
#define ALIGN(x, a) (((x) + (a) - 1) / (a) * (a)) | ||
typedef pthread_spinlock_t spinlock_t; | ||
|
||
typedef int gfp_t; | ||
static void *kzalloc(unsigned size, gfp_t gfp) | ||
{ | ||
void *p = memalign(64, size); | ||
if (!p) | ||
return p; | ||
memset(p, 0, size); | ||
|
||
return p; | ||
} | ||
|
||
static void kfree(void *p) | ||
{ | ||
if (p) | ||
free(p); | ||
} | ||
|
||
static void spin_lock_init(spinlock_t *lock) | ||
{ | ||
int r = pthread_spin_init(lock, 0); | ||
assert(!r); | ||
} | ||
|
||
static void spin_lock(spinlock_t *lock) | ||
{ | ||
int ret = pthread_spin_lock(lock); | ||
assert(!ret); | ||
} | ||
|
||
static void spin_unlock(spinlock_t *lock) | ||
{ | ||
int ret = pthread_spin_unlock(lock); | ||
assert(!ret); | ||
} | ||
|
||
static void spin_lock_bh(spinlock_t *lock) | ||
{ | ||
spin_lock(lock); | ||
} | ||
|
||
static void spin_unlock_bh(spinlock_t *lock) | ||
{ | ||
spin_unlock(lock); | ||
} | ||
|
||
static void spin_lock_irq(spinlock_t *lock) | ||
{ | ||
spin_lock(lock); | ||
} | ||
|
||
static void spin_unlock_irq(spinlock_t *lock) | ||
{ | ||
spin_unlock(lock); | ||
} | ||
|
||
static void spin_lock_irqsave(spinlock_t *lock, unsigned long f) | ||
{ | ||
spin_lock(lock); | ||
} | ||
|
||
static void spin_unlock_irqrestore(spinlock_t *lock, unsigned long f) | ||
{ | ||
spin_unlock(lock); | ||
} | ||
|
||
#include "../../../include/linux/ptr_ring.h" | ||
|
||
static unsigned long long headcnt, tailcnt; | ||
static struct ptr_ring array ____cacheline_aligned_in_smp; | ||
|
||
/* implemented by ring */ | ||
void alloc_ring(void) | ||
{ | ||
int ret = ptr_ring_init(&array, ring_size, 0); | ||
assert(!ret); | ||
} | ||
|
||
/* guest side */ | ||
int add_inbuf(unsigned len, void *buf, void *datap) | ||
{ | ||
int ret; | ||
|
||
ret = __ptr_ring_produce(&array, buf); | ||
if (ret >= 0) { | ||
ret = 0; | ||
headcnt++; | ||
} | ||
|
||
return ret; | ||
} | ||
|
||
/* | ||
* ptr_ring API provides no way for producer to find out whether a given | ||
* buffer was consumed. Our tests merely require that a successful get_buf | ||
* implies that add_inbuf succeed in the past, and that add_inbuf will succeed, | ||
* fake it accordingly. | ||
*/ | ||
void *get_buf(unsigned *lenp, void **bufp) | ||
{ | ||
void *datap; | ||
|
||
if (tailcnt == headcnt || __ptr_ring_full(&array)) | ||
datap = NULL; | ||
else { | ||
datap = "Buffer\n"; | ||
++tailcnt; | ||
} | ||
|
||
return datap; | ||
} | ||
|
||
void poll_used(void) | ||
{ | ||
void *b; | ||
|
||
do { | ||
if (tailcnt == headcnt || __ptr_ring_full(&array)) { | ||
b = NULL; | ||
barrier(); | ||
} else { | ||
b = "Buffer\n"; | ||
} | ||
} while (!b); | ||
} | ||
|
||
void disable_call() | ||
{ | ||
assert(0); | ||
} | ||
|
||
bool enable_call() | ||
{ | ||
assert(0); | ||
} | ||
|
||
void kick_available(void) | ||
{ | ||
assert(0); | ||
} | ||
|
||
/* host side */ | ||
void disable_kick() | ||
{ | ||
assert(0); | ||
} | ||
|
||
bool enable_kick() | ||
{ | ||
assert(0); | ||
} | ||
|
||
void poll_avail(void) | ||
{ | ||
void *b; | ||
|
||
do { | ||
barrier(); | ||
b = __ptr_ring_peek(&array); | ||
} while (!b); | ||
} | ||
|
||
bool use_buf(unsigned *lenp, void **bufp) | ||
{ | ||
void *ptr; | ||
|
||
ptr = __ptr_ring_consume(&array); | ||
|
||
return ptr; | ||
} | ||
|
||
void call_used(void) | ||
{ | ||
assert(0); | ||
} |