2 * Copyright (C) 2016 Red Hat, Inc.
3 * Author: Michael S. Tsirkin <mst@redhat.com>
4 * This work is licensed under the terms of the GNU GPL, version 2.
6 * Common macros and functions for ring benchmarking.
15 #if defined(__x86_64__) || defined(__i386__)
16 #include "x86intrin.h"
18 static inline void wait_cycles(unsigned long long cycles)
23 while (__rdtsc() - t < cycles) {}
26 #define VMEXIT_CYCLES 500
27 #define VMENTRY_CYCLES 500
29 #elif defined(__s390x__)
30 static inline void wait_cycles(unsigned long long cycles)
32 asm volatile("0: brctg %0,0b" : : "d" (cycles));
36 #define VMEXIT_CYCLES 200
37 #define VMENTRY_CYCLES 200
40 static inline void wait_cycles(unsigned long long cycles)
44 #define VMEXIT_CYCLES 0
45 #define VMENTRY_CYCLES 0
48 static inline void vmexit(void)
53 wait_cycles(VMEXIT_CYCLES);
55 static inline void vmentry(void)
60 wait_cycles(VMENTRY_CYCLES);
63 /* implemented by ring */
64 void alloc_ring(void);
66 int add_inbuf(unsigned, void *, void *);
67 void *get_buf(unsigned *, void **);
71 void kick_available();
76 bool use_buf(unsigned *, void **);
79 /* implemented by main */
82 void wait_for_kick(void);
84 void wait_for_call(void);
86 extern unsigned ring_size;
88 /* Compiler barrier - similar to what Linux uses */
89 #define barrier() asm volatile("" ::: "memory")
91 /* Is there a portable way to do this? */
92 #if defined(__x86_64__) || defined(__i386__)
93 #define cpu_relax() asm ("rep; nop" ::: "memory")
94 #elif defined(__s390x__)
95 #define cpu_relax() barrier()
97 #define cpu_relax() assert(0)
100 extern bool do_relax;
102 static inline void busy_wait(void)
107 /* prevent compiler from removing busy loops */
112 * Not using __ATOMIC_SEQ_CST since gcc docs say they are only synchronized
113 * with other __ATOMIC_SEQ_CST calls.
115 #define smp_mb() __sync_synchronize()
118 * This abuses the atomic builtins for thread fences, and
119 * adds a compiler barrier.
121 #define smp_release() do { \
123 __atomic_thread_fence(__ATOMIC_RELEASE); \
126 #define smp_acquire() do { \
127 __atomic_thread_fence(__ATOMIC_ACQUIRE); \