AtomicsOperations.cpp 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. //-------------------------------------------------------------------------------------------------------
  2. // Copyright (C) Microsoft. All rights reserved.
  3. // Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
  4. //-------------------------------------------------------------------------------------------------------
  5. #include "RuntimeLibraryPch.h"
  6. #include "AtomicsOperations.h"
  7. #ifdef _WIN32
  8. #define InterlockedExchangeAdd8 _InterlockedExchangeAdd8
  9. #define InterlockedExchangeAdd16 _InterlockedExchangeAdd16
  10. #define InterlockedAnd8 _InterlockedAnd8
  11. #define InterlockedAnd16 _InterlockedAnd16
  12. #define InterlockedOr8 _InterlockedOr8
  13. #define InterlockedOr16 _InterlockedOr16
  14. #define InterlockedXor8 _InterlockedXor8
  15. #define InterlockedXor16 _InterlockedXor16
  16. #define InterlockedCompareExchange8 _InterlockedCompareExchange8
  17. #define InterlockedCompareExchange16 _InterlockedCompareExchange16
  18. #define InterlockedExchange8 _InterlockedExchange8
  19. #define InterlockedExchange16 _InterlockedExchange16
  20. #endif
  21. #define InterlockedExchangeAdd32 InterlockedExchangeAdd
  22. #define InterlockedAnd32 InterlockedAnd
  23. #define InterlockedOr32 InterlockedOr
  24. #define InterlockedXor32 InterlockedXor
  25. #define InterlockedCompareExchange32 InterlockedCompareExchange
  26. #define InterlockedExchange32 InterlockedExchange
  27. template<typename T> struct ConvertType {};
  28. template<> struct ConvertType<int8> { typedef char _t; };
  29. template<> struct ConvertType<uint8> { typedef char _t; };
  30. template<> struct ConvertType<int16> { typedef short _t; };
  31. template<> struct ConvertType<uint16> { typedef short _t; };
  32. template<> struct ConvertType<int32> { typedef LONG _t; };
  33. template<> struct ConvertType<uint32> { typedef LONG _t; };
  34. template<> struct ConvertType<int64> { typedef LONGLONG _t; };
  35. #define MakeInterLockArgDef1(type) type value
  36. #define MakeInterLockArgDef2(type) type v1, type v2
  37. #define MakeInterLockArgUse1 value
  38. #define MakeInterLockArgUse2 v1, v2
  39. #define _MakeInterlockTemplate(op, argDef, argUse) \
  40. template<typename T> T Interlocked##op##_t(T* target, argDef(T));\
  41. template<> char Interlocked##op##_t(char* target, argDef(char)) { return Interlocked##op##8 (target, argUse); }\
  42. template<> short Interlocked##op##_t(short* target, argDef(short)){ return Interlocked##op##16(target, argUse); }\
  43. template<> LONG Interlocked##op##_t(LONG* target, argDef(LONG)) { return Interlocked##op##32(target, argUse); }\
  44. template<> LONGLONG Interlocked##op##_t(LONGLONG* target, argDef(LONGLONG)) { return Interlocked##op##64(target, argUse); }
  45. #define MakeInterlockTemplate(op, nArgs) _MakeInterlockTemplate(op, MakeInterLockArgDef##nArgs, MakeInterLockArgUse##nArgs)
  46. MakeInterlockTemplate(ExchangeAdd, 1)
  47. MakeInterlockTemplate(And, 1)
  48. MakeInterlockTemplate(Or, 1)
  49. MakeInterlockTemplate(Xor, 1)
  50. MakeInterlockTemplate(Exchange, 1)
  51. MakeInterlockTemplate(CompareExchange, 2)
  52. namespace Js
  53. {
  54. template<typename T> T AtomicsOperations::Load(T* buffer)
  55. {
  56. // MemoryBarrier only works when the memory size is not greater than the register size
  57. CompileAssert(sizeof(T) <= sizeof(size_t));
  58. MemoryBarrier();
  59. T result = (T)*buffer;
  60. return result;
  61. }
  62. #if TARGET_32
  63. template<> int64 AtomicsOperations::Load(int64* buffer)
  64. {
  65. CompileAssert(sizeof(size_t) == 4);
  66. // Implement 64bits atomic load on 32bits platform with a CompareExchange
  67. // It is slower, but at least it is garantied to be an atomic operation
  68. return CompareExchange<int64>(buffer, 0, 0);
  69. }
  70. #endif
  71. template<typename T> T AtomicsOperations::Store(T* buffer, T value)
  72. {
  73. typedef typename ConvertType<T>::_t convertType;
  74. InterlockedExchange_t<convertType>((convertType*)buffer, (convertType)value);
  75. return value;
  76. }
  77. template<typename T> T AtomicsOperations::Add(T* buffer, T value)
  78. {
  79. typedef typename ConvertType<T>::_t convertType;
  80. T result = (T)InterlockedExchangeAdd_t<convertType>((convertType*)buffer, (convertType)value);
  81. return result;
  82. }
  83. template<typename T> T AtomicsOperations::And(T* buffer, T value)
  84. {
  85. typedef typename ConvertType<T>::_t convertType;
  86. T result = (T)InterlockedAnd_t<convertType>((convertType*)buffer, (convertType)value);
  87. return result;
  88. }
  89. template<typename T> T AtomicsOperations::CompareExchange(T* buffer, T comparand, T replacementValue)
  90. {
  91. typedef typename ConvertType<T>::_t convertType;
  92. T result = (T)InterlockedCompareExchange_t<convertType>((convertType*)buffer, (convertType)replacementValue, (convertType)comparand);
  93. return result;
  94. }
  95. template<typename T> T AtomicsOperations::Exchange(T* buffer, T value)
  96. {
  97. typedef typename ConvertType<T>::_t convertType;
  98. T result = (T)InterlockedExchange_t<convertType>((convertType*)buffer, (convertType)value);
  99. return result;
  100. }
  101. template<typename T> T AtomicsOperations::Or(T* buffer, T value)
  102. {
  103. typedef typename ConvertType<T>::_t convertType;
  104. T result = (T)InterlockedOr_t<convertType>((convertType*)buffer, (convertType)value);
  105. return result;
  106. }
  107. template<typename T> T AtomicsOperations::Sub(T* buffer, T value)
  108. {
  109. typedef typename ConvertType<T>::_t convertType;
  110. T result = (T)InterlockedExchangeAdd_t<convertType>((convertType*)buffer, -(convertType)value);
  111. return result;
  112. }
  113. template<typename T> T AtomicsOperations::Xor(T* buffer, T value)
  114. {
  115. typedef typename ConvertType<T>::_t convertType;
  116. T result = (T)InterlockedXor_t<convertType>((convertType*)buffer, (convertType)value);
  117. return result;
  118. }
  119. #define ExplicitImplementation(type) \
  120. template type AtomicsOperations::Load(type*); \
  121. template type AtomicsOperations::Store(type*, type); \
  122. template type AtomicsOperations::Add(type*, type); \
  123. template type AtomicsOperations::And(type*, type); \
  124. template type AtomicsOperations::CompareExchange(type*, type, type); \
  125. template type AtomicsOperations::Exchange(type*, type); \
  126. template type AtomicsOperations::Or(type*, type); \
  127. template type AtomicsOperations::Sub(type*, type); \
  128. template type AtomicsOperations::Xor(type*, type); \
  129. ExplicitImplementation(int8);
  130. ExplicitImplementation(uint8);
  131. ExplicitImplementation(int16);
  132. ExplicitImplementation(uint16);
  133. ExplicitImplementation(int32);
  134. ExplicitImplementation(uint32);
  135. ExplicitImplementation(int64);
  136. };