atomic_ops.cpp 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. // Copyright 2020 yuzu Emulator Project
  2. // Licensed under GPLv2 or any later version
  3. // Refer to the license.txt file included.
  4. #include <cstring>
  5. #include "common/atomic_ops.h"
  6. #if _MSC_VER
  7. #include <intrin.h>
  8. #endif
  9. namespace Common {
  10. #if _MSC_VER
  11. bool AtomicCompareAndSwap(volatile u8* pointer, u8 value, u8 expected) {
  12. const u8 result =
  13. _InterlockedCompareExchange8(reinterpret_cast<volatile char*>(pointer), value, expected);
  14. return result == expected;
  15. }
  16. bool AtomicCompareAndSwap(volatile u16* pointer, u16 value, u16 expected) {
  17. const u16 result =
  18. _InterlockedCompareExchange16(reinterpret_cast<volatile short*>(pointer), value, expected);
  19. return result == expected;
  20. }
  21. bool AtomicCompareAndSwap(volatile u32* pointer, u32 value, u32 expected) {
  22. const u32 result =
  23. _InterlockedCompareExchange(reinterpret_cast<volatile long*>(pointer), value, expected);
  24. return result == expected;
  25. }
  26. bool AtomicCompareAndSwap(volatile u64* pointer, u64 value, u64 expected) {
  27. const u64 result = _InterlockedCompareExchange64(reinterpret_cast<volatile __int64*>(pointer),
  28. value, expected);
  29. return result == expected;
  30. }
  31. bool AtomicCompareAndSwap(volatile u64* pointer, u128 value, u128 expected) {
  32. return _InterlockedCompareExchange128(reinterpret_cast<volatile __int64*>(pointer), value[1],
  33. value[0],
  34. reinterpret_cast<__int64*>(expected.data())) != 0;
  35. }
  36. #else
  37. bool AtomicCompareAndSwap(volatile u8* pointer, u8 value, u8 expected) {
  38. return __sync_bool_compare_and_swap(pointer, expected, value);
  39. }
  40. bool AtomicCompareAndSwap(volatile u16* pointer, u16 value, u16 expected) {
  41. return __sync_bool_compare_and_swap(pointer, expected, value);
  42. }
  43. bool AtomicCompareAndSwap(volatile u32* pointer, u32 value, u32 expected) {
  44. return __sync_bool_compare_and_swap(pointer, expected, value);
  45. }
  46. bool AtomicCompareAndSwap(volatile u64* pointer, u64 value, u64 expected) {
  47. return __sync_bool_compare_and_swap(pointer, expected, value);
  48. }
  49. bool AtomicCompareAndSwap(volatile u64* pointer, u128 value, u128 expected) {
  50. unsigned __int128 value_a;
  51. unsigned __int128 expected_a;
  52. std::memcpy(&value_a, value.data(), sizeof(u128));
  53. std::memcpy(&expected_a, expected.data(), sizeof(u128));
  54. return __sync_bool_compare_and_swap((unsigned __int128*)pointer, expected_a, value_a);
  55. }
  56. #endif
  57. } // namespace Common