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