Skip to content

Commit d715dff

Browse files
committed
Prefer platform specific memory barriers
Following the wisdom of postgres, we opt to use platform specific memory barriers when available. These are generally more performant. In this PR, we add specific cases for i386, x86_64. In the future, we could look at using pg's atomics library directly: https://github.com/postgres/postgres/tree/9d4649ca49416111aee2c84b7e4441a0b7aa2fac/src/include/port/atomics
1 parent b461ffc commit d715dff

File tree

1 file changed

+22
-14
lines changed

1 file changed

+22
-14
lines changed

ext/concurrent/atomic_reference.c

Lines changed: 22 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,26 @@
99

1010
#include "atomic_reference.h"
1111

12+
#if (defined(__i386__) || defined(__i386)) && (defined(__GNUC__) || defined(__INTEL_COMPILER))
13+
#define memory_barrier() \
14+
__asm__ __volatile__ ("lock; addl $0,0(%%esp)" : : : "memory", "cc")
15+
#elif defined(__x86_64__) && (defined(__GNUC__) || defined(__INTEL_COMPILER))
16+
#define memory_barrier() \
17+
__asm__ __volatile__ ("lock; addl $0,0(%%rsp)" : : : "memory", "cc")
18+
#elif defined(HAVE_GCC__ATOMIC_INT32_CAS)
19+
#define memory_barrier() \
20+
__atomic_thread_fence(__ATOMIC_SEQ_CST)
21+
#elif (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 1))
22+
#define memory_barrier() \
23+
__sync_synchronize();
24+
#elif defined _MSC_VER
25+
#define memory_barrier() \
26+
MemoryBarrier();
27+
#elif __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ >= 1050
28+
#define memory_barrier() \
29+
OSMemoryBarrier();
30+
#endif
31+
1232
void ir_mark(void *value) {
1333
rb_gc_mark_maybe((VALUE) value);
1434
}
@@ -27,25 +47,13 @@ VALUE ir_initialize(int argc, VALUE* argv, VALUE self) {
2747
}
2848

2949
VALUE ir_get(VALUE self) {
30-
#if HAVE_GCC_SYNC
31-
__sync_synchronize();
32-
#elif defined _MSC_VER
33-
MemoryBarrier();
34-
#elif __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ >= 1050
35-
OSMemoryBarrier();
36-
#endif
50+
memory_barrier();
3751
return (VALUE) DATA_PTR(self);
3852
}
3953

4054
VALUE ir_set(VALUE self, VALUE new_value) {
4155
DATA_PTR(self) = (void *) new_value;
42-
#if HAVE_GCC_SYNC
43-
__sync_synchronize();
44-
#elif defined _MSC_VER
45-
MemoryBarrier();
46-
#elif __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ >= 1050
47-
OSMemoryBarrier();
48-
#endif
56+
memory_barrier();
4957
return new_value;
5058
}
5159

0 commit comments

Comments
 (0)