229 // and friends' constructors do a fence, a lock and an acquire *in that |
228 // and friends' constructors do a fence, a lock and an acquire *in that |
230 // order*. And that their destructors do a release and unlock, in *that* |
229 // order*. And that their destructors do a release and unlock, in *that* |
231 // order. If their implementations change such that these assumptions |
230 // order. If their implementations change such that these assumptions |
232 // are violated, a whole lot of code will break. |
231 // are violated, a whole lot of code will break. |
233 |
232 |
234 enum ScopedFenceType { |
233 class OrderAccess : public AllStatic { |
235 X_ACQUIRE |
|
236 , RELEASE_X |
|
237 , RELEASE_X_FENCE |
|
238 }; |
|
239 |
|
240 template <ScopedFenceType T> |
|
241 class ScopedFenceGeneral: public StackObj { |
|
242 public: |
|
243 void prefix() {} |
|
244 void postfix() {} |
|
245 }; |
|
246 |
|
247 template <ScopedFenceType T> |
|
248 class ScopedFence : public ScopedFenceGeneral<T> { |
|
249 void *const _field; |
|
250 public: |
|
251 ScopedFence(void *const field) : _field(field) { prefix(); } |
|
252 ~ScopedFence() { postfix(); } |
|
253 void prefix() { ScopedFenceGeneral<T>::prefix(); } |
|
254 void postfix() { ScopedFenceGeneral<T>::postfix(); } |
|
255 }; |
|
256 |
|
257 class OrderAccess : private Atomic { |
|
258 public: |
234 public: |
259 // barriers |
235 // barriers |
260 static void loadload(); |
236 static void loadload(); |
261 static void storestore(); |
237 static void storestore(); |
262 static void loadstore(); |
238 static void loadstore(); |
265 static void acquire(); |
241 static void acquire(); |
266 static void release(); |
242 static void release(); |
267 static void fence(); |
243 static void fence(); |
268 |
244 |
269 static void cross_modify_fence(); |
245 static void cross_modify_fence(); |
270 |
246 private: |
271 template <typename T> |
|
272 static T load_acquire(const volatile T* p); |
|
273 |
|
274 template <typename T, typename D> |
|
275 static void release_store(volatile D* p, T v); |
|
276 |
|
277 template <typename T, typename D> |
|
278 static void release_store_fence(volatile D* p, T v); |
|
279 |
|
280 private: |
|
281 // This is a helper that invokes the StubRoutines::fence_entry() |
247 // This is a helper that invokes the StubRoutines::fence_entry() |
282 // routine if it exists, It should only be used by platforms that |
248 // routine if it exists, It should only be used by platforms that |
283 // don't have another way to do the inline assembly. |
249 // don't have another way to do the inline assembly. |
284 static void StubRoutines_fence(); |
250 static void StubRoutines_fence(); |
285 |
|
286 // Give platforms a variation point to specialize. |
|
287 template<size_t byte_size, ScopedFenceType type> struct PlatformOrderedStore; |
|
288 template<size_t byte_size, ScopedFenceType type> struct PlatformOrderedLoad; |
|
289 |
|
290 template<typename FieldType, ScopedFenceType FenceType> |
|
291 static void ordered_store(volatile FieldType* p, FieldType v); |
|
292 |
|
293 template<typename FieldType, ScopedFenceType FenceType> |
|
294 static FieldType ordered_load(const volatile FieldType* p); |
|
295 }; |
251 }; |
296 |
252 |
297 // The following methods can be specialized using simple template specialization |
|
298 // in the platform specific files for optimization purposes. Otherwise the |
|
299 // generalized variant is used. |
|
300 |
|
301 template<size_t byte_size, ScopedFenceType type> |
|
302 struct OrderAccess::PlatformOrderedStore { |
|
303 template <typename T> |
|
304 void operator()(T v, volatile T* p) const { |
|
305 ordered_store<T, type>(p, v); |
|
306 } |
|
307 }; |
|
308 |
|
309 template<size_t byte_size, ScopedFenceType type> |
|
310 struct OrderAccess::PlatformOrderedLoad { |
|
311 template <typename T> |
|
312 T operator()(const volatile T* p) const { |
|
313 return ordered_load<T, type>(p); |
|
314 } |
|
315 }; |
|
316 |
|
317 #include OS_CPU_HEADER(orderAccess) |
253 #include OS_CPU_HEADER(orderAccess) |
318 |
254 |
319 template<> inline void ScopedFenceGeneral<X_ACQUIRE>::postfix() { OrderAccess::acquire(); } |
|
320 template<> inline void ScopedFenceGeneral<RELEASE_X>::prefix() { OrderAccess::release(); } |
|
321 template<> inline void ScopedFenceGeneral<RELEASE_X_FENCE>::prefix() { OrderAccess::release(); } |
|
322 template<> inline void ScopedFenceGeneral<RELEASE_X_FENCE>::postfix() { OrderAccess::fence(); } |
|
323 |
|
324 |
|
325 template <typename FieldType, ScopedFenceType FenceType> |
|
326 inline void OrderAccess::ordered_store(volatile FieldType* p, FieldType v) { |
|
327 ScopedFence<FenceType> f((void*)p); |
|
328 Atomic::store(v, p); |
|
329 } |
|
330 |
|
331 template <typename FieldType, ScopedFenceType FenceType> |
|
332 inline FieldType OrderAccess::ordered_load(const volatile FieldType* p) { |
|
333 ScopedFence<FenceType> f((void*)p); |
|
334 return Atomic::load(p); |
|
335 } |
|
336 |
|
337 template <typename T> |
|
338 inline T OrderAccess::load_acquire(const volatile T* p) { |
|
339 return LoadImpl<T, PlatformOrderedLoad<sizeof(T), X_ACQUIRE> >()(p); |
|
340 } |
|
341 |
|
342 template <typename T, typename D> |
|
343 inline void OrderAccess::release_store(volatile D* p, T v) { |
|
344 StoreImpl<T, D, PlatformOrderedStore<sizeof(D), RELEASE_X> >()(v, p); |
|
345 } |
|
346 |
|
347 template <typename T, typename D> |
|
348 inline void OrderAccess::release_store_fence(volatile D* p, T v) { |
|
349 StoreImpl<T, D, PlatformOrderedStore<sizeof(D), RELEASE_X_FENCE> >()(v, p); |
|
350 } |
|
351 #endif // SHARE_RUNTIME_ORDERACCESS_HPP |
255 #endif // SHARE_RUNTIME_ORDERACCESS_HPP |