00001 /* atomicCounter.h 00002 */ 00003 #ifndef OSL_ATOMICCOUNTER_H 00004 #define OSL_ATOMICCOUNTER_H 00005 00006 #include "osl/config.h" 00007 #ifdef USE_TBB_ATOMIC 00008 # include <tbb/atomic.h> 00009 #else 00010 # include "osl/misc/lightMutex.h" 00011 #endif 00012 #include <algorithm> 00013 00014 namespace osl 00015 { 00016 namespace misc 00017 { 00018 template <class Counter> 00019 struct IncrementLock 00020 { 00021 Counter& counter; 00022 explicit IncrementLock(Counter& c) : counter(c) 00023 { 00024 counter.inc(); 00025 } 00026 ~IncrementLock() 00027 { 00028 counter.dec(); 00029 } 00030 }; 00031 #ifdef USE_TBB_ATOMIC 00032 class AtomicCounter 00033 { 00034 tbb::atomic<int> count; 00035 public: 00036 explicit AtomicCounter(int count_=0) { 00037 this->count=count_; 00038 } 00039 void inc(){ 00040 count.fetch_and_increment(); 00041 } 00042 int valueAndinc(){ 00043 return count.fetch_and_increment(); 00044 } 00045 void dec(){ 00046 count.fetch_and_decrement(); 00047 } 00048 void max(int val){ 00049 int x=count; 00050 if(x<val){ 00051 int oldx; 00052 while((oldx=count.compare_and_swap(val,x))!=x){ 00053 x=oldx; 00054 if(x>=val) break; 00055 } 00056 } 00057 } 00058 int value() const{ 00059 return count; 00060 } 00061 void setValue(int value) { 00062 count = value; 00063 } 00064 typedef IncrementLock<AtomicCounter> IncLock; 00065 }; 00066 #else 00067 class AtomicCounter 00068 { 00069 typedef LightMutex Mutex; 00070 mutable Mutex m; 00071 int count; 00072 public: 00073 explicit AtomicCounter(int count=0) :count(count){} 00074 void inc(){ 00075 Mutex::scoped_lock lk(m); 00076 count++; 00077 } 00078 int valueAndinc(){ 00079 Mutex::scoped_lock lk(m); 00080 return count++; 00081 } 00082 void dec(){ 00083 Mutex::scoped_lock lk(m); 00084 count--; 00085 } 00086 void max(int val){ 00087 Mutex::scoped_lock lk(m); 00088 count=std::max(count,val); 00089 } 00090 int value() const{ 00091 Mutex::scoped_lock lk(m); 00092 return count; 00093 } 00094 void setValue(int value) { 00095 Mutex::scoped_lock lk(m); 00096 count = value; 00097 } 00098 typedef IncrementLock<AtomicCounter> IncLock; 00099 }; 00100 #endif 00101 } 00102 using misc::AtomicCounter; 00103 } 00104 00105 #endif /* OSL_ATOMICCOUNTER_H */ 00106 // ;;; Local Variables: 00107 // ;;; mode:c++ 00108 // ;;; c-basic-offset:2 00109 // ;;; End: 00110