Panda3D
atomicAdjustPosixImpl.I
1 // Filename: atomicAdjustPosixImpl.I
2 // Created by: drose (10Feb06)
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: AtomicAdjustPosixImpl::inc
18 // Access: Public, Static
19 // Description: Atomically increments the indicated variable.
20 ////////////////////////////////////////////////////////////////////
21 INLINE void AtomicAdjustPosixImpl::
22 inc(TVOLATILE AtomicAdjustPosixImpl::Integer &var) {
23  pthread_mutex_lock(&_mutex);
24  ++var;
25  pthread_mutex_unlock(&_mutex);
26 }
27 
28 ////////////////////////////////////////////////////////////////////
29 // Function: AtomicAdjustPosixImpl::dec
30 // Access: Public, Static
31 // Description: Atomically decrements the indicated variable and
32 // returns true if the new value is nonzero, false if it
33 // is zero.
34 ////////////////////////////////////////////////////////////////////
35 INLINE bool AtomicAdjustPosixImpl::
36 dec(TVOLATILE AtomicAdjustPosixImpl::Integer &var) {
37  pthread_mutex_lock(&_mutex);
38  Integer result = --var;
39  pthread_mutex_unlock(&_mutex);
40  return (result != 0);
41 }
42 
43 ////////////////////////////////////////////////////////////////////
44 // Function: AtomicAdjustPosixImpl::add
45 // Access: Public, Static
46 // Description: Atomically computes var += delta. It is legal for
47 // delta to be negative.
48 ////////////////////////////////////////////////////////////////////
49 INLINE void AtomicAdjustPosixImpl::
50 add(TVOLATILE AtomicAdjustPosixImpl::Integer &var,
51  AtomicAdjustPosixImpl::Integer delta) {
52  pthread_mutex_lock(&_mutex);
53  var += delta;
54  pthread_mutex_unlock(&_mutex);
55 }
56 
57 ////////////////////////////////////////////////////////////////////
58 // Function: AtomicAdjustPosixImpl::set
59 // Access: Public, Static
60 // Description: Atomically changes the indicated variable and
61 // returns the original value.
62 ////////////////////////////////////////////////////////////////////
63 INLINE AtomicAdjustPosixImpl::Integer AtomicAdjustPosixImpl::
64 set(TVOLATILE AtomicAdjustPosixImpl::Integer &var,
65  AtomicAdjustPosixImpl::Integer new_value) {
66  pthread_mutex_lock(&_mutex);
67  Integer orig_value = var;
68  var = new_value;
69  pthread_mutex_unlock(&_mutex);
70  return orig_value;
71 }
72 
73 ////////////////////////////////////////////////////////////////////
74 // Function: AtomicAdjustPosixImpl::get
75 // Access: Public, Static
76 // Description: Atomically retrieves the snapshot value of the
77 // indicated variable. This is the only guaranteed safe
78 // way to retrieve the value that other threads might be
79 // asynchronously setting, incrementing, or decrementing
80 // (via other AtomicAjust methods).
81 ////////////////////////////////////////////////////////////////////
82 INLINE AtomicAdjustPosixImpl::Integer AtomicAdjustPosixImpl::
83 get(const TVOLATILE AtomicAdjustPosixImpl::Integer &var) {
84  pthread_mutex_lock(&_mutex);
85  Integer orig_value = var;
86  pthread_mutex_unlock(&_mutex);
87  return orig_value;
88 }
89 
90 ////////////////////////////////////////////////////////////////////
91 // Function: AtomicAdjustPosixImpl::set_ptr
92 // Access: Public, Static
93 // Description: Atomically changes the indicated variable and
94 // returns the original value.
95 ////////////////////////////////////////////////////////////////////
96 INLINE AtomicAdjustPosixImpl::Pointer AtomicAdjustPosixImpl::
97 set_ptr(TVOLATILE AtomicAdjustPosixImpl::Pointer &var,
98  AtomicAdjustPosixImpl::Pointer new_value) {
99  pthread_mutex_lock(&_mutex);
100  Pointer orig_value = var;
101  var = new_value;
102  pthread_mutex_unlock(&_mutex);
103  return orig_value;
104 }
105 
106 ////////////////////////////////////////////////////////////////////
107 // Function: AtomicAdjustPosixImpl::get_ptr
108 // Access: Public, Static
109 // Description: Atomically retrieves the snapshot value of the
110 // indicated variable. This is the only guaranteed safe
111 // way to retrieve the value that other threads might be
112 // asynchronously setting, incrementing, or decrementing
113 // (via other AtomicAjust methods).
114 ////////////////////////////////////////////////////////////////////
115 INLINE AtomicAdjustPosixImpl::Pointer AtomicAdjustPosixImpl::
116 get_ptr(const TVOLATILE AtomicAdjustPosixImpl::Pointer &var) {
117  pthread_mutex_lock(&_mutex);
118  Pointer orig_value = var;
119  pthread_mutex_unlock(&_mutex);
120  return orig_value;
121 }
122 
123 ////////////////////////////////////////////////////////////////////
124 // Function: AtomicAdjustPosixImpl::compare_and_exchange
125 // Access: Public, Static
126 // Description: Atomic compare and exchange.
127 //
128 // If mem is equal to old_value, store new_value in mem.
129 // In either case, return the original value of mem.
130 // The caller can test for success by comparing
131 // return_value == old_value.
132 //
133 // The atomic function expressed in pseudo-code:
134 //
135 // orig_value = mem;
136 // if (mem == old_value) {
137 // mem = new_value;
138 // }
139 // return orig_value;
140 //
141 ////////////////////////////////////////////////////////////////////
142 INLINE AtomicAdjustPosixImpl::Integer AtomicAdjustPosixImpl::
143 compare_and_exchange(TVOLATILE AtomicAdjustPosixImpl::Integer &mem,
144  AtomicAdjustPosixImpl::Integer old_value,
145  AtomicAdjustPosixImpl::Integer new_value) {
146  pthread_mutex_lock(&_mutex);
147  Integer orig_value = mem;
148  if (mem == old_value) {
149  mem = new_value;
150  }
151  pthread_mutex_unlock(&_mutex);
152  return orig_value;
153 }
154 
155 ////////////////////////////////////////////////////////////////////
156 // Function: AtomicAdjustPosixImpl::compare_and_exchange_ptr
157 // Access: Public, Static
158 // Description: Atomic compare and exchange.
159 //
160 // As above, but works on pointers instead of integers.
161 ////////////////////////////////////////////////////////////////////
162 INLINE AtomicAdjustPosixImpl::Pointer AtomicAdjustPosixImpl::
163 compare_and_exchange_ptr(TVOLATILE AtomicAdjustPosixImpl::Pointer &mem,
164  AtomicAdjustPosixImpl::Pointer old_value,
165  AtomicAdjustPosixImpl::Pointer new_value) {
166  pthread_mutex_lock(&_mutex);
167  Pointer orig_value = mem;
168  if (mem == old_value) {
169  mem = new_value;
170  }
171  pthread_mutex_unlock(&_mutex);
172  return orig_value;
173 }