15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
24
25 #ifndef OS_CPU_LINUX_X86_VM_ATOMIC_LINUX_X86_HPP
26 #define OS_CPU_LINUX_X86_VM_ATOMIC_LINUX_X86_HPP
27
28 // Implementation of class atomic
29
30 template<size_t byte_size>
31 struct Atomic::PlatformAdd
32 : Atomic::FetchAndAdd<Atomic::PlatformAdd<byte_size> >
33 {
34 template<typename I, typename D>
35 D fetch_and_add(I add_value, D volatile* dest) const;
36 };
37
38 template<>
39 template<typename I, typename D>
40 inline D Atomic::PlatformAdd<4>::fetch_and_add(I add_value, D volatile* dest) const {
41 STATIC_ASSERT(4 == sizeof(I));
42 STATIC_ASSERT(4 == sizeof(D));
43 D old_value;
44 __asm__ volatile ( "lock xaddl %0,(%2)"
45 : "=r" (old_value)
46 : "0" (add_value), "r" (dest)
47 : "cc", "memory");
48 return old_value;
49 }
50
51 template<>
52 template<typename T>
53 inline T Atomic::PlatformXchg<4>::operator()(T exchange_value,
54 T volatile* dest) const {
55 STATIC_ASSERT(4 == sizeof(T));
56 __asm__ volatile ( "xchgl (%2),%0"
57 : "=r" (exchange_value)
58 : "0" (exchange_value), "r" (dest)
59 : "memory");
60 return exchange_value;
75 }
76
77 template<>
78 template<typename T>
79 inline T Atomic::PlatformCmpxchg<4>::operator()(T exchange_value,
80 T volatile* dest,
81 T compare_value,
82 cmpxchg_memory_order /* order */) const {
83 STATIC_ASSERT(4 == sizeof(T));
84 __asm__ volatile ("lock cmpxchgl %1,(%3)"
85 : "=a" (exchange_value)
86 : "r" (exchange_value), "a" (compare_value), "r" (dest)
87 : "cc", "memory");
88 return exchange_value;
89 }
90
91 #ifdef AMD64
92
93 template<>
94 template<typename I, typename D>
95 inline D Atomic::PlatformAdd<8>::fetch_and_add(I add_value, D volatile* dest) const {
96 STATIC_ASSERT(8 == sizeof(I));
97 STATIC_ASSERT(8 == sizeof(D));
98 D old_value;
99 __asm__ __volatile__ ("lock xaddq %0,(%2)"
100 : "=r" (old_value)
101 : "0" (add_value), "r" (dest)
102 : "cc", "memory");
103 return old_value;
104 }
105
106 template<>
107 template<typename T>
108 inline T Atomic::PlatformXchg<8>::operator()(T exchange_value,
109 T volatile* dest) const {
110 STATIC_ASSERT(8 == sizeof(T));
111 __asm__ __volatile__ ("xchgq (%2),%0"
112 : "=r" (exchange_value)
113 : "0" (exchange_value), "r" (dest)
114 : "memory");
115 return exchange_value;
116 }
117
118 template<>
119 template<typename T>
120 inline T Atomic::PlatformCmpxchg<8>::operator()(T exchange_value,
121 T volatile* dest,
122 T compare_value,
123 cmpxchg_memory_order /* order */) const {
124 STATIC_ASSERT(8 == sizeof(T));
125 __asm__ __volatile__ ("lock cmpxchgq %1,(%3)"
126 : "=a" (exchange_value)
127 : "r" (exchange_value), "a" (compare_value), "r" (dest)
128 : "cc", "memory");
129 return exchange_value;
|
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
24
25 #ifndef OS_CPU_LINUX_X86_VM_ATOMIC_LINUX_X86_HPP
26 #define OS_CPU_LINUX_X86_VM_ATOMIC_LINUX_X86_HPP
27
28 // Implementation of class atomic
29
30 template<size_t byte_size>
31 struct Atomic::PlatformAdd
32 : Atomic::FetchAndAdd<Atomic::PlatformAdd<byte_size> >
33 {
34 template<typename I, typename D>
35 D fetch_and_add(I add_value, D volatile* dest, cmpxchg_memory_order order) const;
36 };
37
38 template<>
39 template<typename I, typename D>
40 inline D Atomic::PlatformAdd<4>::fetch_and_add(I add_value, D volatile* dest,
41 cmpxchg_memory_order order) const {
42 STATIC_ASSERT(4 == sizeof(I));
43 STATIC_ASSERT(4 == sizeof(D));
44 D old_value;
45 __asm__ volatile ( "lock xaddl %0,(%2)"
46 : "=r" (old_value)
47 : "0" (add_value), "r" (dest)
48 : "cc", "memory");
49 return old_value;
50 }
51
52 template<>
53 template<typename T>
54 inline T Atomic::PlatformXchg<4>::operator()(T exchange_value,
55 T volatile* dest) const {
56 STATIC_ASSERT(4 == sizeof(T));
57 __asm__ volatile ( "xchgl (%2),%0"
58 : "=r" (exchange_value)
59 : "0" (exchange_value), "r" (dest)
60 : "memory");
61 return exchange_value;
76 }
77
78 template<>
79 template<typename T>
80 inline T Atomic::PlatformCmpxchg<4>::operator()(T exchange_value,
81 T volatile* dest,
82 T compare_value,
83 cmpxchg_memory_order /* order */) const {
84 STATIC_ASSERT(4 == sizeof(T));
85 __asm__ volatile ("lock cmpxchgl %1,(%3)"
86 : "=a" (exchange_value)
87 : "r" (exchange_value), "a" (compare_value), "r" (dest)
88 : "cc", "memory");
89 return exchange_value;
90 }
91
92 #ifdef AMD64
93
94 template<>
95 template<typename I, typename D>
96 inline D Atomic::PlatformAdd<8>::fetch_and_add(I add_value, D volatile* dest,
97 cmpxchg_memory_order order) const {
98 STATIC_ASSERT(8 == sizeof(I));
99 STATIC_ASSERT(8 == sizeof(D));
100 D old_value;
101 __asm__ __volatile__ ("lock xaddq %0,(%2)"
102 : "=r" (old_value)
103 : "0" (add_value), "r" (dest)
104 : "cc", "memory");
105 return old_value;
106 }
107
108 template<>
109 template<typename T>
110 inline T Atomic::PlatformXchg<8>::operator()(T exchange_value, T volatile* dest) const {
111 STATIC_ASSERT(8 == sizeof(T));
112 __asm__ __volatile__ ("xchgq (%2),%0"
113 : "=r" (exchange_value)
114 : "0" (exchange_value), "r" (dest)
115 : "memory");
116 return exchange_value;
117 }
118
119 template<>
120 template<typename T>
121 inline T Atomic::PlatformCmpxchg<8>::operator()(T exchange_value,
122 T volatile* dest,
123 T compare_value,
124 cmpxchg_memory_order /* order */) const {
125 STATIC_ASSERT(8 == sizeof(T));
126 __asm__ __volatile__ ("lock cmpxchgq %1,(%3)"
127 : "=a" (exchange_value)
128 : "r" (exchange_value), "a" (compare_value), "r" (dest)
129 : "cc", "memory");
130 return exchange_value;
|