Panda3D
|
00001 // Filename: atomicAdjustWin32Impl.I 00002 // Created by: drose (07Feb06) 00003 // 00004 //////////////////////////////////////////////////////////////////// 00005 // 00006 // PANDA 3D SOFTWARE 00007 // Copyright (c) Carnegie Mellon University. All rights reserved. 00008 // 00009 // All use of this software is subject to the terms of the revised BSD 00010 // license. You should have received a copy of this license along 00011 // with this source code in a file named "LICENSE." 00012 // 00013 //////////////////////////////////////////////////////////////////// 00014 00015 00016 //////////////////////////////////////////////////////////////////// 00017 // Function: AtomicAdjustWin32Impl::inc 00018 // Access: Public, Static 00019 // Description: Atomically increments the indicated variable. 00020 //////////////////////////////////////////////////////////////////// 00021 INLINE void AtomicAdjustWin32Impl:: 00022 inc(TVOLATILE AtomicAdjustWin32Impl::Integer &var) { 00023 InterlockedIncrement(&var); 00024 } 00025 00026 //////////////////////////////////////////////////////////////////// 00027 // Function: AtomicAdjustWin32Impl::dec 00028 // Access: Public, Static 00029 // Description: Atomically decrements the indicated variable and 00030 // returns true if the new value is nonzero, false if it 00031 // is zero. 00032 //////////////////////////////////////////////////////////////////// 00033 INLINE bool AtomicAdjustWin32Impl:: 00034 dec(TVOLATILE AtomicAdjustWin32Impl::Integer &var) { 00035 return (InterlockedDecrement(&var) != 0); 00036 } 00037 00038 //////////////////////////////////////////////////////////////////// 00039 // Function: AtomicAdjustWin32Impl::add 00040 // Access: Public, Static 00041 // Description: Atomically computes var += delta. It is legal for 00042 // delta to be negative. 00043 //////////////////////////////////////////////////////////////////// 00044 INLINE void AtomicAdjustWin32Impl:: 00045 add(TVOLATILE AtomicAdjustWin32Impl::Integer &var, AtomicAdjustWin32Impl::Integer delta) { 00046 AtomicAdjustWin32Impl::Integer orig_value = var; 00047 while (compare_and_exchange(var, orig_value, orig_value + delta) != orig_value) { 00048 orig_value = var; 00049 } 00050 } 00051 00052 //////////////////////////////////////////////////////////////////// 00053 // Function: AtomicAdjustWin32Impl::set 00054 // Access: Public, Static 00055 // Description: Atomically changes the indicated variable and 00056 // returns the original value. 00057 //////////////////////////////////////////////////////////////////// 00058 INLINE AtomicAdjustWin32Impl::Integer AtomicAdjustWin32Impl:: 00059 set(TVOLATILE AtomicAdjustWin32Impl::Integer &var, AtomicAdjustWin32Impl::Integer new_value) { 00060 return InterlockedExchange(&var, new_value); 00061 } 00062 00063 //////////////////////////////////////////////////////////////////// 00064 // Function: AtomicAdjustWin32Impl::get 00065 // Access: Public, Static 00066 // Description: Atomically retrieves the snapshot value of the 00067 // indicated variable. This is the only guaranteed safe 00068 // way to retrieve the value that other threads might be 00069 // asynchronously setting, incrementing, or decrementing 00070 // (via other AtomicAjust methods). 00071 //////////////////////////////////////////////////////////////////// 00072 INLINE AtomicAdjustWin32Impl::Integer AtomicAdjustWin32Impl:: 00073 get(const TVOLATILE AtomicAdjustWin32Impl::Integer &var) { 00074 return var; 00075 } 00076 00077 //////////////////////////////////////////////////////////////////// 00078 // Function: AtomicAdjustWin32Impl::set_ptr 00079 // Access: Public, Static 00080 // Description: Atomically changes the indicated variable and 00081 // returns the original value. 00082 //////////////////////////////////////////////////////////////////// 00083 INLINE void *AtomicAdjustWin32Impl:: 00084 set_ptr(void * TVOLATILE &var, void *new_value) { 00085 void *orig_value = var; 00086 var = new_value; 00087 return orig_value; 00088 } 00089 00090 //////////////////////////////////////////////////////////////////// 00091 // Function: AtomicAdjustWin32Impl::get_ptr 00092 // Access: Public, Static 00093 // Description: Atomically retrieves the snapshot value of the 00094 // indicated variable. This is the only guaranteed safe 00095 // way to retrieve the value that other threads might be 00096 // asynchronously setting, incrementing, or decrementing 00097 // (via other AtomicAjust methods). 00098 //////////////////////////////////////////////////////////////////// 00099 INLINE void *AtomicAdjustWin32Impl:: 00100 get_ptr(void * const TVOLATILE &var) { 00101 return var; 00102 } 00103 00104 //////////////////////////////////////////////////////////////////// 00105 // Function: AtomicAdjustWin32Impl::compare_and_exchange 00106 // Access: Public, Static 00107 // Description: Atomic compare and exchange. 00108 // 00109 // If mem is equal to old_value, store new_value in mem. 00110 // In either case, return the original value of mem. 00111 // The caller can test for success by comparing 00112 // return_value == old_value. 00113 // 00114 // The atomic function expressed in pseudo-code: 00115 // 00116 // orig_value = mem; 00117 // if (mem == old_value) { 00118 // mem = new_value; 00119 // } 00120 // return orig_value; 00121 // 00122 //////////////////////////////////////////////////////////////////// 00123 INLINE AtomicAdjustWin32Impl::Integer AtomicAdjustWin32Impl:: 00124 compare_and_exchange(TVOLATILE AtomicAdjustWin32Impl::Integer &mem, AtomicAdjustWin32Impl::Integer old_value, 00125 AtomicAdjustWin32Impl::Integer new_value) { 00126 // Note that the AtomicAdjust parameter order is different from 00127 // Windows convention! 00128 return InterlockedCompareExchange((TVOLATILE LONG *)&mem, new_value, old_value); 00129 } 00130 00131 //////////////////////////////////////////////////////////////////// 00132 // Function: AtomicAdjustWin32Impl::compare_and_exchange_ptr 00133 // Access: Public, Static 00134 // Description: Atomic compare and exchange. 00135 // 00136 // As above, but works on pointers instead of integers. 00137 //////////////////////////////////////////////////////////////////// 00138 INLINE void *AtomicAdjustWin32Impl:: 00139 compare_and_exchange_ptr(void * TVOLATILE &mem, void *old_value, 00140 void *new_value) { 00141 // Note that the AtomicAdjust parameter order is different from 00142 // Windows convention! 00143 return InterlockedCompareExchangePointer(&mem, new_value, old_value); 00144 }