Panda3D
atomicAdjustGccImpl.I
1 // Filename: atomicAdjustGccImpl.I
2 // Created by: rdb (04Jul14)
3 //
4 ////////////////////////////////////////////////////////////////////
5 //
6 // PANDA 3D SOFTWARE
7 // Copyright (c) Carnegie Mellon University. All rights reserved.
8 //
9 // All use of this software is subject to the terms of the revised BSD
10 // license. You should have received a copy of this license along
11 // with this source code in a file named "LICENSE."
12 //
13 ////////////////////////////////////////////////////////////////////
14 
15 
16 ////////////////////////////////////////////////////////////////////
17 // Function: AtomicAdjustGccImpl::inc
18 // Access: Public, Static
19 // Description: Atomically increments the indicated variable.
20 ////////////////////////////////////////////////////////////////////
21 INLINE void AtomicAdjustGccImpl::
22 inc(TVOLATILE AtomicAdjustGccImpl::Integer &var) {
23  __atomic_fetch_add(&var, 1, __ATOMIC_SEQ_CST);
24 }
25 
26 ////////////////////////////////////////////////////////////////////
27 // Function: AtomicAdjustGccImpl::dec
28 // Access: Public, Static
29 // Description: Atomically decrements the indicated variable and
30 // returns true if the new value is nonzero, false if it
31 // is zero.
32 ////////////////////////////////////////////////////////////////////
33 INLINE bool AtomicAdjustGccImpl::
34 dec(TVOLATILE AtomicAdjustGccImpl::Integer &var) {
35  return (__atomic_sub_fetch(&var, 1, __ATOMIC_SEQ_CST) != 0);
36 }
37 
38 ////////////////////////////////////////////////////////////////////
39 // Function: AtomicAdjustGccImpl::add
40 // Access: Public, Static
41 // Description: Atomically computes var += delta. It is legal for
42 // delta to be negative.
43 ////////////////////////////////////////////////////////////////////
44 INLINE void AtomicAdjustGccImpl::
45 add(TVOLATILE AtomicAdjustGccImpl::Integer &var,
46  AtomicAdjustGccImpl::Integer delta) {
47  __atomic_fetch_add(&var, delta, __ATOMIC_SEQ_CST);
48 }
49 
50 ////////////////////////////////////////////////////////////////////
51 // Function: AtomicAdjustGccImpl::set
52 // Access: Public, Static
53 // Description: Atomically changes the indicated variable and
54 // returns the original value.
55 ////////////////////////////////////////////////////////////////////
56 INLINE AtomicAdjustGccImpl::Integer AtomicAdjustGccImpl::
57 set(TVOLATILE AtomicAdjustGccImpl::Integer &var,
58  AtomicAdjustGccImpl::Integer new_value) {
59 
60  return __atomic_exchange_n(&var, new_value, __ATOMIC_SEQ_CST);
61 }
62 
63 ////////////////////////////////////////////////////////////////////
64 // Function: AtomicAdjustGccImpl::get
65 // Access: Public, Static
66 // Description: Atomically retrieves the snapshot value of the
67 // indicated variable. This is the only guaranteed safe
68 // way to retrieve the value that other threads might be
69 // asynchronously setting, incrementing, or decrementing
70 // (via other AtomicAjust methods).
71 ////////////////////////////////////////////////////////////////////
72 INLINE AtomicAdjustGccImpl::Integer AtomicAdjustGccImpl::
73 get(const TVOLATILE AtomicAdjustGccImpl::Integer &var) {
74  return __atomic_load_n(&var, __ATOMIC_SEQ_CST);
75 }
76 
77 ////////////////////////////////////////////////////////////////////
78 // Function: AtomicAdjustGccImpl::set_ptr
79 // Access: Public, Static
80 // Description: Atomically changes the indicated variable and
81 // returns the original value.
82 ////////////////////////////////////////////////////////////////////
83 INLINE AtomicAdjustGccImpl::Pointer AtomicAdjustGccImpl::
84 set_ptr(TVOLATILE AtomicAdjustGccImpl::Pointer &var,
85  AtomicAdjustGccImpl::Pointer new_value) {
86 
87  return __atomic_exchange_n(&var, new_value, __ATOMIC_SEQ_CST);
88 }
89 
90 ////////////////////////////////////////////////////////////////////
91 // Function: AtomicAdjustGccImpl::get_ptr
92 // Access: Public, Static
93 // Description: Atomically retrieves the snapshot value of the
94 // indicated variable. This is the only guaranteed safe
95 // way to retrieve the value that other threads might be
96 // asynchronously setting, incrementing, or decrementing
97 // (via other AtomicAjust methods).
98 ////////////////////////////////////////////////////////////////////
99 INLINE AtomicAdjustGccImpl::Pointer AtomicAdjustGccImpl::
100 get_ptr(const TVOLATILE AtomicAdjustGccImpl::Pointer &var) {
101  return __atomic_load_n(&var, __ATOMIC_SEQ_CST);
102 }
103 
104 ////////////////////////////////////////////////////////////////////
105 // Function: AtomicAdjustGccImpl::compare_and_exchange
106 // Access: Public, Static
107 // Description: Atomic compare and exchange.
108 //
109 // If mem is equal to old_value, store new_value in mem.
110 // In either case, return the original value of mem.
111 // The caller can test for success by comparing
112 // return_value == old_value.
113 //
114 // The atomic function expressed in pseudo-code:
115 //
116 // orig_value = mem;
117 // if (mem == old_value) {
118 // mem = new_value;
119 // }
120 // return orig_value;
121 //
122 ////////////////////////////////////////////////////////////////////
123 INLINE AtomicAdjustGccImpl::Integer AtomicAdjustGccImpl::
124 compare_and_exchange(TVOLATILE AtomicAdjustGccImpl::Integer &mem,
125  AtomicAdjustGccImpl::Integer old_value,
126  AtomicAdjustGccImpl::Integer new_value) {
127 
128  __atomic_compare_exchange_n(&mem, &old_value, new_value, false,
129  __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST);
130  return old_value;
131 }
132 
133 ////////////////////////////////////////////////////////////////////
134 // Function: AtomicAdjustGccImpl::compare_and_exchange_ptr
135 // Access: Public, Static
136 // Description: Atomic compare and exchange.
137 //
138 // As above, but works on pointers instead of integers.
139 ////////////////////////////////////////////////////////////////////
140 INLINE AtomicAdjustGccImpl::Pointer AtomicAdjustGccImpl::
141 compare_and_exchange_ptr(TVOLATILE AtomicAdjustGccImpl::Pointer &mem,
142  AtomicAdjustGccImpl::Pointer old_value,
143  AtomicAdjustGccImpl::Pointer new_value) {
144 
145  __atomic_compare_exchange_n(&mem, &old_value, new_value, false,
146  __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST);
147  return old_value;
148 }