summaryrefslogtreecommitdiff
path: root/src/common/atomic_ops.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/common/atomic_ops.cpp')
-rw-r--r--src/common/atomic_ops.cpp70
1 files changed, 70 insertions, 0 deletions
diff --git a/src/common/atomic_ops.cpp b/src/common/atomic_ops.cpp
new file mode 100644
index 000000000..1098e21ff
--- /dev/null
+++ b/src/common/atomic_ops.cpp
@@ -0,0 +1,70 @@
1// Copyright 2020 yuzu Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include <cstring>
6
7#include "common/atomic_ops.h"
8
9#if _MSC_VER
10#include <intrin.h>
11#endif
12
13namespace Common {
14
15#if _MSC_VER
16
17bool AtomicCompareAndSwap(u8 volatile* pointer, u8 value, u8 expected) {
18 u8 result = _InterlockedCompareExchange8((char*)pointer, value, expected);
19 return result == expected;
20}
21
22bool AtomicCompareAndSwap(u16 volatile* pointer, u16 value, u16 expected) {
23 u16 result = _InterlockedCompareExchange16((short*)pointer, value, expected);
24 return result == expected;
25}
26
27bool AtomicCompareAndSwap(u32 volatile* pointer, u32 value, u32 expected) {
28 u32 result = _InterlockedCompareExchange((long*)pointer, value, expected);
29 return result == expected;
30}
31
32bool AtomicCompareAndSwap(u64 volatile* pointer, u64 value, u64 expected) {
33 u64 result = _InterlockedCompareExchange64((__int64*)pointer, value, expected);
34 return result == expected;
35}
36
37bool AtomicCompareAndSwap(u64 volatile* pointer, u128 value, u128 expected) {
38 return _InterlockedCompareExchange128((__int64*)pointer, value[1], value[0],
39 (__int64*)expected.data()) != 0;
40}
41
42#else
43
44bool AtomicCompareAndSwap(u8 volatile* pointer, u8 value, u8 expected) {
45 return __sync_bool_compare_and_swap(pointer, expected, value);
46}
47
48bool AtomicCompareAndSwap(u16 volatile* pointer, u16 value, u16 expected) {
49 return __sync_bool_compare_and_swap(pointer, expected, value);
50}
51
52bool AtomicCompareAndSwap(u32 volatile* pointer, u32 value, u32 expected) {
53 return __sync_bool_compare_and_swap(pointer, expected, value);
54}
55
56bool AtomicCompareAndSwap(u64 volatile* pointer, u64 value, u64 expected) {
57 return __sync_bool_compare_and_swap(pointer, expected, value);
58}
59
60bool AtomicCompareAndSwap(u64 volatile* pointer, u128 value, u128 expected) {
61 unsigned __int128 value_a;
62 unsigned __int128 expected_a;
63 std::memcpy(&value_a, value.data(), sizeof(u128));
64 std::memcpy(&expected_a, expected.data(), sizeof(u128));
65 return __sync_bool_compare_and_swap((unsigned __int128*)pointer, expected_a, value_a);
66}
67
68#endif
69
70} // namespace Common