1 /* |
1 /* |
2 * Copyright (c) 1999, 2017, Oracle and/or its affiliates. All rights reserved. |
2 * Copyright (c) 1999, 2018, Oracle and/or its affiliates. All rights reserved. |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * |
4 * |
5 * This code is free software; you can redistribute it and/or modify it |
5 * This code is free software; you can redistribute it and/or modify it |
6 * under the terms of the GNU General Public License version 2 only, as |
6 * under the terms of the GNU General Public License version 2 only, as |
7 * published by the Free Software Foundation. |
7 * published by the Free Software Foundation. |
45 template<size_t byte_size> |
45 template<size_t byte_size> |
46 struct Atomic::PlatformAdd |
46 struct Atomic::PlatformAdd |
47 : Atomic::AddAndFetch<Atomic::PlatformAdd<byte_size> > |
47 : Atomic::AddAndFetch<Atomic::PlatformAdd<byte_size> > |
48 { |
48 { |
49 template<typename I, typename D> |
49 template<typename I, typename D> |
50 D add_and_fetch(I add_value, D volatile* dest) const; |
50 D add_and_fetch(I add_value, D volatile* dest, atomic_memory_order order) const; |
51 }; |
51 }; |
52 |
52 |
53 #ifdef AMD64 |
53 #ifdef AMD64 |
54 template<> |
54 template<> |
55 template<typename I, typename D> |
55 template<typename I, typename D> |
56 inline D Atomic::PlatformAdd<4>::add_and_fetch(I add_value, D volatile* dest) const { |
56 inline D Atomic::PlatformAdd<4>::add_and_fetch(I add_value, D volatile* dest, |
|
57 atomic_memory_order order) const { |
57 return add_using_helper<int32_t>(os::atomic_add_func, add_value, dest); |
58 return add_using_helper<int32_t>(os::atomic_add_func, add_value, dest); |
58 } |
59 } |
59 |
60 |
60 template<> |
61 template<> |
61 template<typename I, typename D> |
62 template<typename I, typename D> |
62 inline D Atomic::PlatformAdd<8>::add_and_fetch(I add_value, D volatile* dest) const { |
63 inline D Atomic::PlatformAdd<8>::add_and_fetch(I add_value, D volatile* dest, |
|
64 atomic_memory_order order) const { |
63 return add_using_helper<int64_t>(os::atomic_add_long_func, add_value, dest); |
65 return add_using_helper<int64_t>(os::atomic_add_long_func, add_value, dest); |
64 } |
66 } |
65 |
67 |
66 #define DEFINE_STUB_XCHG(ByteSize, StubType, StubName) \ |
68 #define DEFINE_STUB_XCHG(ByteSize, StubType, StubName) \ |
67 template<> \ |
69 template<> \ |
68 template<typename T> \ |
70 template<typename T> \ |
69 inline T Atomic::PlatformXchg<ByteSize>::operator()(T exchange_value, \ |
71 inline T Atomic::PlatformXchg<ByteSize>::operator()(T exchange_value, \ |
70 T volatile* dest) const { \ |
72 T volatile* dest, \ |
|
73 atomic_memory_order order) const { \ |
71 STATIC_ASSERT(ByteSize == sizeof(T)); \ |
74 STATIC_ASSERT(ByteSize == sizeof(T)); \ |
72 return xchg_using_helper<StubType>(StubName, exchange_value, dest); \ |
75 return xchg_using_helper<StubType>(StubName, exchange_value, dest); \ |
73 } |
76 } |
74 |
77 |
75 DEFINE_STUB_XCHG(4, int32_t, os::atomic_xchg_func) |
78 DEFINE_STUB_XCHG(4, int32_t, os::atomic_xchg_func) |
81 template<> \ |
84 template<> \ |
82 template<typename T> \ |
85 template<typename T> \ |
83 inline T Atomic::PlatformCmpxchg<ByteSize>::operator()(T exchange_value, \ |
86 inline T Atomic::PlatformCmpxchg<ByteSize>::operator()(T exchange_value, \ |
84 T volatile* dest, \ |
87 T volatile* dest, \ |
85 T compare_value, \ |
88 T compare_value, \ |
86 cmpxchg_memory_order order) const { \ |
89 atomic_memory_order order) const { \ |
87 STATIC_ASSERT(ByteSize == sizeof(T)); \ |
90 STATIC_ASSERT(ByteSize == sizeof(T)); \ |
88 return cmpxchg_using_helper<StubType>(StubName, exchange_value, dest, compare_value); \ |
91 return cmpxchg_using_helper<StubType>(StubName, exchange_value, dest, compare_value); \ |
89 } |
92 } |
90 |
93 |
91 DEFINE_STUB_CMPXCHG(1, int8_t, os::atomic_cmpxchg_byte_func) |
94 DEFINE_STUB_CMPXCHG(1, int8_t, os::atomic_cmpxchg_byte_func) |
126 template<> |
131 template<> |
127 template<typename T> |
132 template<typename T> |
128 inline T Atomic::PlatformCmpxchg<1>::operator()(T exchange_value, |
133 inline T Atomic::PlatformCmpxchg<1>::operator()(T exchange_value, |
129 T volatile* dest, |
134 T volatile* dest, |
130 T compare_value, |
135 T compare_value, |
131 cmpxchg_memory_order order) const { |
136 atomic_memory_order order) const { |
132 STATIC_ASSERT(1 == sizeof(T)); |
137 STATIC_ASSERT(1 == sizeof(T)); |
133 // alternative for InterlockedCompareExchange |
138 // alternative for InterlockedCompareExchange |
134 __asm { |
139 __asm { |
135 mov edx, dest |
140 mov edx, dest |
136 mov cl, exchange_value |
141 mov cl, exchange_value |
142 template<> |
147 template<> |
143 template<typename T> |
148 template<typename T> |
144 inline T Atomic::PlatformCmpxchg<4>::operator()(T exchange_value, |
149 inline T Atomic::PlatformCmpxchg<4>::operator()(T exchange_value, |
145 T volatile* dest, |
150 T volatile* dest, |
146 T compare_value, |
151 T compare_value, |
147 cmpxchg_memory_order order) const { |
152 atomic_memory_order order) const { |
148 STATIC_ASSERT(4 == sizeof(T)); |
153 STATIC_ASSERT(4 == sizeof(T)); |
149 // alternative for InterlockedCompareExchange |
154 // alternative for InterlockedCompareExchange |
150 __asm { |
155 __asm { |
151 mov edx, dest |
156 mov edx, dest |
152 mov ecx, exchange_value |
157 mov ecx, exchange_value |
158 template<> |
163 template<> |
159 template<typename T> |
164 template<typename T> |
160 inline T Atomic::PlatformCmpxchg<8>::operator()(T exchange_value, |
165 inline T Atomic::PlatformCmpxchg<8>::operator()(T exchange_value, |
161 T volatile* dest, |
166 T volatile* dest, |
162 T compare_value, |
167 T compare_value, |
163 cmpxchg_memory_order order) const { |
168 atomic_memory_order order) const { |
164 STATIC_ASSERT(8 == sizeof(T)); |
169 STATIC_ASSERT(8 == sizeof(T)); |
165 int32_t ex_lo = (int32_t)exchange_value; |
170 int32_t ex_lo = (int32_t)exchange_value; |
166 int32_t ex_hi = *( ((int32_t*)&exchange_value) + 1 ); |
171 int32_t ex_hi = *( ((int32_t*)&exchange_value) + 1 ); |
167 int32_t cmp_lo = (int32_t)compare_value; |
172 int32_t cmp_lo = (int32_t)compare_value; |
168 int32_t cmp_hi = *( ((int32_t*)&compare_value) + 1 ); |
173 int32_t cmp_hi = *( ((int32_t*)&compare_value) + 1 ); |