src/hotspot/os_cpu/windows_x86/atomic_windows_x86.hpp
changeset 50029 ea0a16ba6ac0
parent 48468 7cc7de9bf4a4
child 53244 9807daeb47c4
equal deleted inserted replaced
50028:28eaf7a99a8c 50029:ea0a16ba6ac0
     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)
    96 
    99 
    97 #else // !AMD64
   100 #else // !AMD64
    98 
   101 
    99 template<>
   102 template<>
   100 template<typename I, typename D>
   103 template<typename I, typename D>
   101 inline D Atomic::PlatformAdd<4>::add_and_fetch(I add_value, D volatile* dest) const {
   104 inline D Atomic::PlatformAdd<4>::add_and_fetch(I add_value, D volatile* dest,
       
   105                                                atomic_memory_order order) const {
   102   STATIC_ASSERT(4 == sizeof(I));
   106   STATIC_ASSERT(4 == sizeof(I));
   103   STATIC_ASSERT(4 == sizeof(D));
   107   STATIC_ASSERT(4 == sizeof(D));
   104   __asm {
   108   __asm {
   105     mov edx, dest;
   109     mov edx, dest;
   106     mov eax, add_value;
   110     mov eax, add_value;
   111 }
   115 }
   112 
   116 
   113 template<>
   117 template<>
   114 template<typename T>
   118 template<typename T>
   115 inline T Atomic::PlatformXchg<4>::operator()(T exchange_value,
   119 inline T Atomic::PlatformXchg<4>::operator()(T exchange_value,
   116                                              T volatile* dest) const {
   120                                              T volatile* dest,
       
   121                                              atomic_memory_order order) const {
   117   STATIC_ASSERT(4 == sizeof(T));
   122   STATIC_ASSERT(4 == sizeof(T));
   118   // alternative for InterlockedExchange
   123   // alternative for InterlockedExchange
   119   __asm {
   124   __asm {
   120     mov eax, exchange_value;
   125     mov eax, exchange_value;
   121     mov ecx, dest;
   126     mov ecx, dest;
   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 );