comparison third_party/wrk/src/atomicvar.h @ 186:8cf4ec5e2191 hg-web

Fixed merge conflict.
author MrJuneJune <me@mrjunejune.com>
date Fri, 23 Jan 2026 22:38:59 -0800
parents 94705b5986b3
children
comparison
equal deleted inserted replaced
176:fed99fc04e12 186:8cf4ec5e2191
1 /* This file implements atomic counters using __atomic or __sync macros if
2 * available, otherwise synchronizing different threads using a mutex.
3 *
4 * The exported interaface is composed of three macros:
5 *
6 * atomicIncr(var,count) -- Increment the atomic counter
7 * atomicGetIncr(var,oldvalue_var,count) -- Get and increment the atomic counter
8 * atomicDecr(var,count) -- Decrement the atomic counter
9 * atomicGet(var,dstvar) -- Fetch the atomic counter value
10 * atomicSet(var,value) -- Set the atomic counter value
11 *
12 * The variable 'var' should also have a declared mutex with the same
13 * name and the "_mutex" postfix, for instance:
14 *
15 * long myvar;
16 * pthread_mutex_t myvar_mutex;
17 * atomicSet(myvar,12345);
18 *
19 * If atomic primitives are availble (tested in config.h) the mutex
20 * is not used.
21 *
22 * Never use return value from the macros, instead use the AtomicGetIncr()
23 * if you need to get the current value and increment it atomically, like
24 * in the followign example:
25 *
26 * long oldvalue;
27 * atomicGetIncr(myvar,oldvalue,1);
28 * doSomethingWith(oldvalue);
29 *
30 * ----------------------------------------------------------------------------
31 *
32 * Copyright (c) 2015, Salvatore Sanfilippo <antirez at gmail dot com>
33 * All rights reserved.
34 *
35 * Redistribution and use in source and binary forms, with or without
36 * modification, are permitted provided that the following conditions are met:
37 *
38 * * Redistributions of source code must retain the above copyright notice,
39 * this list of conditions and the following disclaimer.
40 * * Redistributions in binary form must reproduce the above copyright
41 * notice, this list of conditions and the following disclaimer in the
42 * documentation and/or other materials provided with the distribution.
43 * * Neither the name of Redis nor the names of its contributors may be used
44 * to endorse or promote products derived from this software without
45 * specific prior written permission.
46 *
47 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
48 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
49 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
50 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
51 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
52 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
53 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
54 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
55 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
56 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
57 * POSSIBILITY OF SUCH DAMAGE.
58 */
59
60 #include <pthread.h>
61
62 #ifndef __ATOMIC_VAR_H
63 #define __ATOMIC_VAR_H
64
65 /* To test Redis with Helgrind (a Valgrind tool) it is useful to define
66 * the following macro, so that __sync macros are used: those can be detected
67 * by Helgrind (even if they are less efficient) so that no false positive
68 * is reported. */
69 // #define __ATOMIC_VAR_FORCE_SYNC_MACROS
70
71 #if !defined(__ATOMIC_VAR_FORCE_SYNC_MACROS) && defined(__ATOMIC_RELAXED) && !defined(__sun) && (!defined(__clang__) || !defined(__APPLE__) || __apple_build_version__ > 4210057)
72 /* Implementation using __atomic macros. */
73
74 #define atomicIncr(var,count) __atomic_add_fetch(&var,(count),__ATOMIC_RELAXED)
75 #define atomicGetIncr(var,oldvalue_var,count) do { \
76 oldvalue_var = __atomic_fetch_add(&var,(count),__ATOMIC_RELAXED); \
77 } while(0)
78 #define atomicDecr(var,count) __atomic_sub_fetch(&var,(count),__ATOMIC_RELAXED)
79 #define atomicGet(var,dstvar) do { \
80 dstvar = __atomic_load_n(&var,__ATOMIC_RELAXED); \
81 } while(0)
82 #define atomicSet(var,value) __atomic_store_n(&var,value,__ATOMIC_RELAXED)
83 #define REDIS_ATOMIC_API "atomic-builtin"
84
85 #elif defined(HAVE_ATOMIC)
86 /* Implementation using __sync macros. */
87
88 #define atomicIncr(var,count) __sync_add_and_fetch(&var,(count))
89 #define atomicGetIncr(var,oldvalue_var,count) do { \
90 oldvalue_var = __sync_fetch_and_add(&var,(count)); \
91 } while(0)
92 #define atomicDecr(var,count) __sync_sub_and_fetch(&var,(count))
93 #define atomicGet(var,dstvar) do { \
94 dstvar = __sync_sub_and_fetch(&var,0); \
95 } while(0)
96 #define atomicSet(var,value) do { \
97 while(!__sync_bool_compare_and_swap(&var,var,value)); \
98 } while(0)
99 #define REDIS_ATOMIC_API "sync-builtin"
100
101 #else
102 /* Implementation using pthread mutex. */
103
104 #define atomicIncr(var,count) do { \
105 pthread_mutex_lock(&var ## _mutex); \
106 var += (count); \
107 pthread_mutex_unlock(&var ## _mutex); \
108 } while(0)
109 #define atomicGetIncr(var,oldvalue_var,count) do { \
110 pthread_mutex_lock(&var ## _mutex); \
111 oldvalue_var = var; \
112 var += (count); \
113 pthread_mutex_unlock(&var ## _mutex); \
114 } while(0)
115 #define atomicDecr(var,count) do { \
116 pthread_mutex_lock(&var ## _mutex); \
117 var -= (count); \
118 pthread_mutex_unlock(&var ## _mutex); \
119 } while(0)
120 #define atomicGet(var,dstvar) do { \
121 pthread_mutex_lock(&var ## _mutex); \
122 dstvar = var; \
123 pthread_mutex_unlock(&var ## _mutex); \
124 } while(0)
125 #define atomicSet(var,value) do { \
126 pthread_mutex_lock(&var ## _mutex); \
127 var = value; \
128 pthread_mutex_unlock(&var ## _mutex); \
129 } while(0)
130 #define REDIS_ATOMIC_API "pthread-mutex"
131
132 #endif
133 #endif /* __ATOMIC_VAR_H */