1 | // |
2 | // detail/gcc_x86_fenced_block.hpp |
3 | // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
4 | // |
5 | // Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com) |
6 | // |
7 | // Distributed under the Boost Software License, Version 1.0. (See accompanying |
8 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
9 | // |
10 | |
11 | #ifndef BOOST_ASIO_DETAIL_GCC_X86_FENCED_BLOCK_HPP |
12 | #define BOOST_ASIO_DETAIL_GCC_X86_FENCED_BLOCK_HPP |
13 | |
14 | #if defined(_MSC_VER) && (_MSC_VER >= 1200) |
15 | # pragma once |
16 | #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) |
17 | |
18 | #include <boost/asio/detail/config.hpp> |
19 | |
20 | #if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)) |
21 | |
22 | #include <boost/asio/detail/push_options.hpp> |
23 | |
24 | namespace boost { |
25 | namespace asio { |
26 | namespace detail { |
27 | |
28 | class gcc_x86_fenced_block |
29 | : private noncopyable |
30 | { |
31 | public: |
32 | enum half_t { half }; |
33 | enum full_t { full }; |
34 | |
35 | // Constructor for a half fenced block. |
36 | explicit gcc_x86_fenced_block(half_t) |
37 | { |
38 | } |
39 | |
40 | // Constructor for a full fenced block. |
41 | explicit gcc_x86_fenced_block(full_t) |
42 | { |
43 | lbarrier(); |
44 | } |
45 | |
46 | // Destructor. |
47 | ~gcc_x86_fenced_block() |
48 | { |
49 | sbarrier(); |
50 | } |
51 | |
52 | private: |
53 | static int barrier() |
54 | { |
55 | int r = 0, m = 1; |
56 | __asm__ __volatile__ ( |
57 | "xchgl %0, %1" : |
58 | "=r" (r), "=m" (m) : |
59 | "0" (1), "m" (m) : |
60 | "memory" , "cc" ); |
61 | return r; |
62 | } |
63 | |
64 | static void lbarrier() |
65 | { |
66 | #if defined(__SSE2__) |
67 | # if (__GNUC__ >= 4) && !defined(__INTEL_COMPILER) && !defined(__ICL) |
68 | __builtin_ia32_lfence(); |
69 | # else // (__GNUC__ >= 4) && !defined(__INTEL_COMPILER) && !defined(__ICL) |
70 | __asm__ __volatile__ ("lfence" ::: "memory" ); |
71 | # endif // (__GNUC__ >= 4) && !defined(__INTEL_COMPILER) && !defined(__ICL) |
72 | #else // defined(__SSE2__) |
73 | barrier(); |
74 | #endif // defined(__SSE2__) |
75 | } |
76 | |
77 | static void sbarrier() |
78 | { |
79 | #if defined(__SSE2__) |
80 | # if (__GNUC__ >= 4) && !defined(__INTEL_COMPILER) && !defined(__ICL) |
81 | __builtin_ia32_sfence(); |
82 | # else // (__GNUC__ >= 4) && !defined(__INTEL_COMPILER) && !defined(__ICL) |
83 | __asm__ __volatile__ ("sfence" ::: "memory" ); |
84 | # endif // (__GNUC__ >= 4) && !defined(__INTEL_COMPILER) && !defined(__ICL) |
85 | #else // defined(__SSE2__) |
86 | barrier(); |
87 | #endif // defined(__SSE2__) |
88 | } |
89 | }; |
90 | |
91 | } // namespace detail |
92 | } // namespace asio |
93 | } // namespace boost |
94 | |
95 | #include <boost/asio/detail/pop_options.hpp> |
96 | |
97 | #endif // defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)) |
98 | |
99 | #endif // BOOST_ASIO_DETAIL_GCC_X86_FENCED_BLOCK_HPP |
100 | |