Mercurial
diff third_party/wrk/src/atomicvar.h @ 178:94705b5986b3
[ThirdParty] Added WRK and luajit for load testing.
| author | MrJuneJune <me@mrjunejune.com> |
|---|---|
| date | Thu, 22 Jan 2026 20:10:30 -0800 |
| parents | |
| children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/third_party/wrk/src/atomicvar.h Thu Jan 22 20:10:30 2026 -0800 @@ -0,0 +1,133 @@ +/* This file implements atomic counters using __atomic or __sync macros if + * available, otherwise synchronizing different threads using a mutex. + * + * The exported interaface is composed of three macros: + * + * atomicIncr(var,count) -- Increment the atomic counter + * atomicGetIncr(var,oldvalue_var,count) -- Get and increment the atomic counter + * atomicDecr(var,count) -- Decrement the atomic counter + * atomicGet(var,dstvar) -- Fetch the atomic counter value + * atomicSet(var,value) -- Set the atomic counter value + * + * The variable 'var' should also have a declared mutex with the same + * name and the "_mutex" postfix, for instance: + * + * long myvar; + * pthread_mutex_t myvar_mutex; + * atomicSet(myvar,12345); + * + * If atomic primitives are availble (tested in config.h) the mutex + * is not used. + * + * Never use return value from the macros, instead use the AtomicGetIncr() + * if you need to get the current value and increment it atomically, like + * in the followign example: + * + * long oldvalue; + * atomicGetIncr(myvar,oldvalue,1); + * doSomethingWith(oldvalue); + * + * ---------------------------------------------------------------------------- + * + * Copyright (c) 2015, Salvatore Sanfilippo <antirez at gmail dot com> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Redis nor the names of its contributors may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <pthread.h> + +#ifndef __ATOMIC_VAR_H +#define __ATOMIC_VAR_H + +/* To test Redis with Helgrind (a Valgrind tool) it is useful to define + * the following macro, so that __sync macros are used: those can be detected + * by Helgrind (even if they are less efficient) so that no false positive + * is reported. */ +// #define __ATOMIC_VAR_FORCE_SYNC_MACROS + +#if !defined(__ATOMIC_VAR_FORCE_SYNC_MACROS) && defined(__ATOMIC_RELAXED) && !defined(__sun) && (!defined(__clang__) || !defined(__APPLE__) || __apple_build_version__ > 4210057) +/* Implementation using __atomic macros. */ + +#define atomicIncr(var,count) __atomic_add_fetch(&var,(count),__ATOMIC_RELAXED) +#define atomicGetIncr(var,oldvalue_var,count) do { \ + oldvalue_var = __atomic_fetch_add(&var,(count),__ATOMIC_RELAXED); \ +} while(0) +#define atomicDecr(var,count) __atomic_sub_fetch(&var,(count),__ATOMIC_RELAXED) +#define atomicGet(var,dstvar) do { \ + dstvar = __atomic_load_n(&var,__ATOMIC_RELAXED); \ +} while(0) +#define atomicSet(var,value) __atomic_store_n(&var,value,__ATOMIC_RELAXED) +#define REDIS_ATOMIC_API "atomic-builtin" + +#elif defined(HAVE_ATOMIC) +/* Implementation using __sync macros. */ + +#define atomicIncr(var,count) __sync_add_and_fetch(&var,(count)) +#define atomicGetIncr(var,oldvalue_var,count) do { \ + oldvalue_var = __sync_fetch_and_add(&var,(count)); \ +} while(0) +#define atomicDecr(var,count) __sync_sub_and_fetch(&var,(count)) +#define atomicGet(var,dstvar) do { \ + dstvar = __sync_sub_and_fetch(&var,0); \ +} while(0) +#define atomicSet(var,value) do { \ + while(!__sync_bool_compare_and_swap(&var,var,value)); \ +} while(0) +#define REDIS_ATOMIC_API "sync-builtin" + +#else +/* Implementation using pthread mutex. */ + +#define atomicIncr(var,count) do { \ + pthread_mutex_lock(&var ## _mutex); \ + var += (count); \ + pthread_mutex_unlock(&var ## _mutex); \ +} while(0) +#define atomicGetIncr(var,oldvalue_var,count) do { \ + pthread_mutex_lock(&var ## _mutex); \ + oldvalue_var = var; \ + var += (count); \ + pthread_mutex_unlock(&var ## _mutex); \ +} while(0) +#define atomicDecr(var,count) do { \ + pthread_mutex_lock(&var ## _mutex); \ + var -= (count); \ + pthread_mutex_unlock(&var ## _mutex); \ +} while(0) +#define atomicGet(var,dstvar) do { \ + pthread_mutex_lock(&var ## _mutex); \ + dstvar = var; \ + pthread_mutex_unlock(&var ## _mutex); \ +} while(0) +#define atomicSet(var,value) do { \ + pthread_mutex_lock(&var ## _mutex); \ + var = value; \ + pthread_mutex_unlock(&var ## _mutex); \ +} while(0) +#define REDIS_ATOMIC_API "pthread-mutex" + +#endif +#endif /* __ATOMIC_VAR_H */