4
* Copyright Ericsson AB 2011. All Rights Reserved.
6
* The contents of this file are subject to the Erlang Public License,
7
* Version 1.1, (the "License"); you may not use this file except in
8
* compliance with the License. You should have received a copy of the
9
* Erlang Public License along with this software. If not, it can be
10
* retrieved online at http://www.erlang.org/.
12
* Software distributed under the License is distributed on an "AS IS"
13
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
14
* the License for the specific language governing rights and limitations
21
* Description: Memory barriers for x86/x86-64
22
* Author: Rickard Green
25
#ifndef ETHR_X86_MEMBAR_H__
26
#define ETHR_X86_MEMBAR_H__
28
#define ETHR_LoadLoad (1 << 0)
29
#define ETHR_LoadStore (1 << 1)
30
#define ETHR_StoreLoad (1 << 2)
31
#define ETHR_StoreStore (1 << 3)
33
#define ETHR_NO_SSE2_MEMORY_BARRIER__ \
35
volatile ethr_sint32_t x__ = 0; \
36
__asm__ __volatile__ ("lock; orl $0x0, %0\n\t" \
42
static __inline__ void
45
__asm__ __volatile__ ("" : : : "memory");
48
static __inline__ void
51
#if ETHR_SIZEOF_PTR == 4
52
if (ETHR_X86_RUNTIME_CONF_HAVE_NO_SSE2__)
53
ETHR_NO_SSE2_MEMORY_BARRIER__;
56
__asm__ __volatile__ ("mfence\n\t" : : : "memory");
59
static __inline__ void
62
#if ETHR_SIZEOF_PTR == 4
63
if (ETHR_X86_RUNTIME_CONF_HAVE_NO_SSE2__)
64
ETHR_NO_SSE2_MEMORY_BARRIER__;
67
__asm__ __volatile__ ("sfence\n\t" : : : "memory");
70
static __inline__ void
73
#if ETHR_SIZEOF_PTR == 4
74
if (ETHR_X86_RUNTIME_CONF_HAVE_NO_SSE2__)
75
ETHR_NO_SSE2_MEMORY_BARRIER__;
78
__asm__ __volatile__ ("lfence\n\t" : : : "memory");
81
#define ETHR_X86_OUT_OF_ORDER_MEMBAR(B) \
82
ETHR_CHOOSE_EXPR((B) == ETHR_StoreStore, \
84
ETHR_CHOOSE_EXPR((B) == ETHR_LoadLoad, \
88
#ifdef ETHR_X86_OUT_OF_ORDER
90
#define ETHR_MEMBAR(B) \
91
ETHR_X86_OUT_OF_ORDER_MEMBAR((B))
93
#else /* !ETHR_X86_OUT_OF_ORDER (the default) */
96
* We assume that only stores before loads may be reordered. That is,
97
* we assume that *no* instructions like these are used:
99
* - streaming stores executed with non-temporal move,
100
* - string operations, or
101
* - other instructions which aren't LoadLoad, LoadStore, and StoreStore
102
* ordered by themselves
103
* If such instructions are used, either insert memory barriers
104
* using ETHR_X86_OUT_OF_ORDER_MEMBAR() at appropriate places, or
105
* define ETHR_X86_OUT_OF_ORDER. For more info see Intel 64 and IA-32
106
* Architectures Software Developer's Manual; Vol 3A; Chapter 8.2.2.
109
#define ETHR_MEMBAR(B) \
110
ETHR_CHOOSE_EXPR((B) & ETHR_StoreLoad, ethr_mfence__(), ethr_cfence__())
112
#endif /* !ETHR_X86_OUT_OF_ORDER */
114
#endif /* ETHR_X86_MEMBAR_H__ */