Skip to content

Commit 7e5d690

Browse files
committed
Atomic vars implemented in a more general way.
We have them into zmalloc.c, but this is going to replace that implementation, so that it's possible to use the same idea everywhere inside the code base.
1 parent 7af4eeb commit 7e5d690

File tree

1 file changed

+94
-0
lines changed

1 file changed

+94
-0
lines changed

src/atomicvar.h

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
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,mutex) -- Increment the atomic counter
7+
* atomicDecr(var,count,mutex) -- Decrement the atomic counter
8+
* atomicGet(var,dstvar,mutex) -- Fetch the atomic counter value
9+
*
10+
* If atomic primitives are availble (tested in config.h) the mutex
11+
* is not used.
12+
*
13+
* Never use return value from the macros. To update and get use instead:
14+
*
15+
* atomicIncr(mycounter,...);
16+
* atomicGet(mycounter,newvalue);
17+
* doSomethingWith(newvalue);
18+
*
19+
* ----------------------------------------------------------------------------
20+
*
21+
* Copyright (c) 2015, Salvatore Sanfilippo <antirez at gmail dot com>
22+
* All rights reserved.
23+
*
24+
* Redistribution and use in source and binary forms, with or without
25+
* modification, are permitted provided that the following conditions are met:
26+
*
27+
* * Redistributions of source code must retain the above copyright notice,
28+
* this list of conditions and the following disclaimer.
29+
* * Redistributions in binary form must reproduce the above copyright
30+
* notice, this list of conditions and the following disclaimer in the
31+
* documentation and/or other materials provided with the distribution.
32+
* * Neither the name of Redis nor the names of its contributors may be used
33+
* to endorse or promote products derived from this software without
34+
* specific prior written permission.
35+
*
36+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
37+
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
38+
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
39+
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
40+
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
41+
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
42+
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
43+
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
44+
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
45+
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
46+
* POSSIBILITY OF SUCH DAMAGE.
47+
*/
48+
49+
#include <pthread.h>
50+
51+
#ifndef __ATOMIC_VAR_H
52+
#define __ATOMIC_VAR_H
53+
54+
#if defined(__ATOMIC_RELAXED)
55+
/* Implementation using __atomic macros. */
56+
57+
#define atomicIncr(var,count,mutex) __atomic_add_fetch(&var,(count),__ATOMIC_RELAXED)
58+
#define atomicDecr(var,count,mutex) __atomic_sub_fetch(&var,(count),__ATOMIC_RELAXED)
59+
#define atomicGet(var,dstvar,mutex) do { \
60+
dstvar = __atomic_load_n(&var,__ATOMIC_RELAXED); \
61+
} while(0)
62+
63+
#elif defined(HAVE_ATOMIC)
64+
/* Implementation using __sync macros. */
65+
66+
#define atomicIncr(var,count,mutex) __sync_add_and_fetch(&var,(count))
67+
#define atomicDecr(var,count,mutex) __sync_sub_and_fetch(&var,(count))
68+
#define atomicGet(var,dstvar,mutex) do { \
69+
dstvar = __sync_sub_and_fetch(&var,0); \
70+
} while(0)
71+
72+
#else
73+
/* Implementation using pthread mutex. */
74+
75+
#define atomicIncr(var,count,mutex) do { \
76+
pthread_mutex_lock(&mutex); \
77+
var += (count); \
78+
pthread_mutex_unlock(&mutex); \
79+
} while(0)
80+
81+
#define atomicDecr(var,count,mutex) do { \
82+
pthread_mutex_lock(&mutex); \
83+
var -= (count); \
84+
pthread_mutex_unlock(&mutex); \
85+
} while(0)
86+
87+
#define atomicGet(var,dstvar,mutex) do { \
88+
pthread_mutex_lock(&mutex); \
89+
dstvar = var; \
90+
pthread_mutex_unlock(&mutex); \
91+
} while(0)
92+
#endif
93+
94+
#endif /* __ATOMIC_VAR_H */

0 commit comments

Comments
 (0)