Merge pull request #5714 from alexischr/update_bockbuild
[mono.git] / mono / utils / mono-membar.h
1 /**
2  * \file
3  * Memory barrier inline functions
4  *
5  * Author:
6  *      Mark Probst (mark.probst@gmail.com)
7  *
8  * (C) 2007 Novell, Inc
9  */
10
11 #ifndef _MONO_UTILS_MONO_MEMBAR_H_
12 #define _MONO_UTILS_MONO_MEMBAR_H_
13
14 #include <config.h>
15
16 #include <glib.h>
17
18
19 #ifdef TARGET_WASM
20
21 static inline void mono_memory_barrier (void)
22 {
23 }
24
25 static inline void mono_memory_read_barrier (void)
26 {
27 }
28
29 static inline void mono_memory_write_barrier (void)
30 {
31 }
32
33 #elif _MSC_VER
34 #ifndef WIN32_LEAN_AND_MEAN
35 #define WIN32_LEAN_AND_MEAN
36 #endif
37 #include <windows.h>
38 #include <intrin.h>
39
40 static inline void mono_memory_barrier (void)
41 {
42         /* NOTE: _ReadWriteBarrier and friends only prevent the
43            compiler from reordering loads and stores. To prevent
44            the CPU from doing the same, we have to use the
45            MemoryBarrier macro which expands to e.g. a serializing
46            XCHG instruction on x86. Also note that the MemoryBarrier
47            macro does *not* imply _ReadWriteBarrier, so that call
48            cannot be eliminated. */
49         _ReadWriteBarrier ();
50         MemoryBarrier ();
51 }
52
53 static inline void mono_memory_read_barrier (void)
54 {
55         _ReadBarrier ();
56         MemoryBarrier ();
57 }
58
59 static inline void mono_memory_write_barrier (void)
60 {
61         _WriteBarrier ();
62         MemoryBarrier ();
63 }
64 #elif defined(USE_GCC_ATOMIC_OPS)
65 static inline void mono_memory_barrier (void)
66 {
67         __sync_synchronize ();
68 }
69
70 static inline void mono_memory_read_barrier (void)
71 {
72         mono_memory_barrier ();
73 }
74
75 static inline void mono_memory_write_barrier (void)
76 {
77         mono_memory_barrier ();
78 }
79 #else
80 #error "Don't know how to do memory barriers!"
81 #endif
82
83 #endif  /* _MONO_UTILS_MONO_MEMBAR_H_ */