summaryrefslogtreecommitdiff
path: root/src/common/atomic_gcc.h
diff options
context:
space:
mode:
authorGravatar bunnei2014-04-08 19:25:03 -0400
committerGravatar bunnei2014-04-08 19:25:03 -0400
commit63e46abdb8764bc97e91bae862c8d461e61b1965 (patch)
treee73f4aa25d7b4015a265e7bbfb6004dab7561027 /src/common/atomic_gcc.h
parentfixed some license headers that I missed (diff)
downloadyuzu-63e46abdb8764bc97e91bae862c8d461e61b1965.tar.gz
yuzu-63e46abdb8764bc97e91bae862c8d461e61b1965.tar.xz
yuzu-63e46abdb8764bc97e91bae862c8d461e61b1965.zip
got rid of 'src' folders in each sub-project
Diffstat (limited to 'src/common/atomic_gcc.h')
-rw-r--r--src/common/atomic_gcc.h113
1 files changed, 113 insertions, 0 deletions
diff --git a/src/common/atomic_gcc.h b/src/common/atomic_gcc.h
new file mode 100644
index 000000000..2eb38697b
--- /dev/null
+++ b/src/common/atomic_gcc.h
@@ -0,0 +1,113 @@
1// Copyright 2013 Dolphin Emulator Project
2// Licensed under GPLv2
3// Refer to the license.txt file included.
4
5#ifndef _ATOMIC_GCC_H_
6#define _ATOMIC_GCC_H_
7
8#include "common.h"
9
10// Atomic operations are performed in a single step by the CPU. It is
11// impossible for other threads to see the operation "half-done."
12//
13// Some atomic operations can be combined with different types of memory
14// barriers called "Acquire semantics" and "Release semantics", defined below.
15//
16// Acquire semantics: Future memory accesses cannot be relocated to before the
17// operation.
18//
19// Release semantics: Past memory accesses cannot be relocated to after the
20// operation.
21//
22// These barriers affect not only the compiler, but also the CPU.
23
24namespace Common
25{
26
27inline void AtomicAdd(volatile u32& target, u32 value) {
28 __sync_add_and_fetch(&target, value);
29}
30
31inline void AtomicAnd(volatile u32& target, u32 value) {
32 __sync_and_and_fetch(&target, value);
33}
34
35inline void AtomicDecrement(volatile u32& target) {
36 __sync_add_and_fetch(&target, -1);
37}
38
39inline void AtomicIncrement(volatile u32& target) {
40 __sync_add_and_fetch(&target, 1);
41}
42
43inline u32 AtomicLoad(volatile u32& src) {
44 return src; // 32-bit reads are always atomic.
45}
46inline u32 AtomicLoadAcquire(volatile u32& src) {
47 //keep the compiler from caching any memory references
48 u32 result = src; // 32-bit reads are always atomic.
49 //__sync_synchronize(); // TODO: May not be necessary.
50 // Compiler instruction only. x86 loads always have acquire semantics.
51 __asm__ __volatile__ ( "":::"memory" );
52 return result;
53}
54
55inline void AtomicOr(volatile u32& target, u32 value) {
56 __sync_or_and_fetch(&target, value);
57}
58
59inline void AtomicStore(volatile u32& dest, u32 value) {
60 dest = value; // 32-bit writes are always atomic.
61}
62inline void AtomicStoreRelease(volatile u32& dest, u32 value) {
63 __sync_lock_test_and_set(&dest, value); // TODO: Wrong! This function is has acquire semantics.
64}
65
66}
67
68// Old code kept here for reference in case we need the parts with __asm__ __volatile__.
69#if 0
70LONG SyncInterlockedIncrement(LONG *Dest)
71{
72#if defined(__GNUC__) && defined (__GNUC_MINOR__) && ((4 < __GNUC__) || (4 == __GNUC__ && 1 <= __GNUC_MINOR__))
73 return __sync_add_and_fetch(Dest, 1);
74#else
75 register int result;
76 __asm__ __volatile__("lock; xadd %0,%1"
77 : "=r" (result), "=m" (*Dest)
78 : "0" (1), "m" (*Dest)
79 : "memory");
80 return result;
81#endif
82}
83
84LONG SyncInterlockedExchangeAdd(LONG *Dest, LONG Val)
85{
86#if defined(__GNUC__) && defined (__GNUC_MINOR__) && ((4 < __GNUC__) || (4 == __GNUC__ && 1 <= __GNUC_MINOR__))
87 return __sync_add_and_fetch(Dest, Val);
88#else
89 register int result;
90 __asm__ __volatile__("lock; xadd %0,%1"
91 : "=r" (result), "=m" (*Dest)
92 : "0" (Val), "m" (*Dest)
93 : "memory");
94 return result;
95#endif
96}
97
98LONG SyncInterlockedExchange(LONG *Dest, LONG Val)
99{
100#if defined(__GNUC__) && defined (__GNUC_MINOR__) && ((4 < __GNUC__) || (4 == __GNUC__ && 1 <= __GNUC_MINOR__))
101 return __sync_lock_test_and_set(Dest, Val);
102#else
103 register int result;
104 __asm__ __volatile__("lock; xchg %0,%1"
105 : "=r" (result), "=m" (*Dest)
106 : "0" (Val), "m" (*Dest)
107 : "memory");
108 return result;
109#endif
110}
111#endif
112
113#endif