ptr_ring.c (3601B)
1// SPDX-License-Identifier: GPL-2.0 2#define _GNU_SOURCE 3#include "main.h" 4#include <stdlib.h> 5#include <stdio.h> 6#include <string.h> 7#include <pthread.h> 8#include <malloc.h> 9#include <assert.h> 10#include <errno.h> 11#include <limits.h> 12 13#define SMP_CACHE_BYTES 64 14#define cache_line_size() SMP_CACHE_BYTES 15#define ____cacheline_aligned_in_smp __attribute__ ((aligned (SMP_CACHE_BYTES))) 16#define unlikely(x) (__builtin_expect(!!(x), 0)) 17#define likely(x) (__builtin_expect(!!(x), 1)) 18#define ALIGN(x, a) (((x) + (a) - 1) / (a) * (a)) 19#define SIZE_MAX (~(size_t)0) 20#define KMALLOC_MAX_SIZE SIZE_MAX 21 22typedef pthread_spinlock_t spinlock_t; 23 24typedef int gfp_t; 25#define __GFP_ZERO 0x1 26 27static void *kmalloc(unsigned size, gfp_t gfp) 28{ 29 void *p = memalign(64, size); 30 if (!p) 31 return p; 32 33 if (gfp & __GFP_ZERO) 34 memset(p, 0, size); 35 return p; 36} 37 38static inline void *kzalloc(unsigned size, gfp_t flags) 39{ 40 return kmalloc(size, flags | __GFP_ZERO); 41} 42 43static inline void *kmalloc_array(size_t n, size_t size, gfp_t flags) 44{ 45 if (size != 0 && n > SIZE_MAX / size) 46 return NULL; 47 return kmalloc(n * size, flags); 48} 49 50static inline void *kcalloc(size_t n, size_t size, gfp_t flags) 51{ 52 return kmalloc_array(n, size, flags | __GFP_ZERO); 53} 54 55static void kfree(void *p) 56{ 57 if (p) 58 free(p); 59} 60 61#define kvmalloc_array kmalloc_array 62#define kvfree kfree 63 64static void spin_lock_init(spinlock_t *lock) 65{ 66 int r = pthread_spin_init(lock, 0); 67 assert(!r); 68} 69 70static void spin_lock(spinlock_t *lock) 71{ 72 int ret = pthread_spin_lock(lock); 73 assert(!ret); 74} 75 76static void spin_unlock(spinlock_t *lock) 77{ 78 int ret = pthread_spin_unlock(lock); 79 assert(!ret); 80} 81 82static void spin_lock_bh(spinlock_t *lock) 83{ 84 spin_lock(lock); 85} 86 87static void spin_unlock_bh(spinlock_t *lock) 88{ 89 spin_unlock(lock); 90} 91 92static void spin_lock_irq(spinlock_t *lock) 93{ 94 spin_lock(lock); 95} 96 97static void spin_unlock_irq(spinlock_t *lock) 98{ 99 spin_unlock(lock); 100} 101 102static void spin_lock_irqsave(spinlock_t *lock, unsigned long f) 103{ 104 spin_lock(lock); 105} 106 107static void spin_unlock_irqrestore(spinlock_t *lock, unsigned long f) 108{ 109 spin_unlock(lock); 110} 111 112#include "../../../include/linux/ptr_ring.h" 113 114static unsigned long long headcnt, tailcnt; 115static struct ptr_ring array ____cacheline_aligned_in_smp; 116 117/* implemented by ring */ 118void alloc_ring(void) 119{ 120 int ret = ptr_ring_init(&array, ring_size, 0); 121 assert(!ret); 122 /* Hacky way to poke at ring internals. Useful for testing though. */ 123 if (param) 124 array.batch = param; 125} 126 127/* guest side */ 128int add_inbuf(unsigned len, void *buf, void *datap) 129{ 130 int ret; 131 132 ret = __ptr_ring_produce(&array, buf); 133 if (ret >= 0) { 134 ret = 0; 135 headcnt++; 136 } 137 138 return ret; 139} 140 141/* 142 * ptr_ring API provides no way for producer to find out whether a given 143 * buffer was consumed. Our tests merely require that a successful get_buf 144 * implies that add_inbuf succeed in the past, and that add_inbuf will succeed, 145 * fake it accordingly. 146 */ 147void *get_buf(unsigned *lenp, void **bufp) 148{ 149 void *datap; 150 151 if (tailcnt == headcnt || __ptr_ring_full(&array)) 152 datap = NULL; 153 else { 154 datap = "Buffer\n"; 155 ++tailcnt; 156 } 157 158 return datap; 159} 160 161bool used_empty() 162{ 163 return (tailcnt == headcnt || __ptr_ring_full(&array)); 164} 165 166void disable_call() 167{ 168 assert(0); 169} 170 171bool enable_call() 172{ 173 assert(0); 174} 175 176void kick_available(void) 177{ 178 assert(0); 179} 180 181/* host side */ 182void disable_kick() 183{ 184 assert(0); 185} 186 187bool enable_kick() 188{ 189 assert(0); 190} 191 192bool avail_empty() 193{ 194 return __ptr_ring_empty(&array); 195} 196 197bool use_buf(unsigned *lenp, void **bufp) 198{ 199 void *ptr; 200 201 ptr = __ptr_ring_consume(&array); 202 203 return ptr; 204} 205 206void call_used(void) 207{ 208 assert(0); 209}