Equalizer
1.2.1
|
00001 00002 /* Copyright (c) 2006-2011, Stefan Eilemann <eile@equalizergraphics.com> 00003 * 2011, Cedric Stalder <cedric.stalder@gmail.com> 00004 * 00005 * This library is free software; you can redistribute it and/or modify it under 00006 * the terms of the GNU Lesser General Public License version 2.1 as published 00007 * by the Free Software Foundation. 00008 * 00009 * This library is distributed in the hope that it will be useful, but WITHOUT 00010 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 00011 * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 00012 * details. 00013 * 00014 * You should have received a copy of the GNU Lesser General Public License 00015 * along with this library; if not, write to the Free Software Foundation, Inc., 00016 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 00017 */ 00018 00019 #ifndef COBASE_MONITOR_H 00020 #define COBASE_MONITOR_H 00021 00022 #include <co/base/nonCopyable.h> // base class 00023 #include <co/base/condition.h> // member 00024 #include <co/base/types.h> 00025 00026 #include <errno.h> 00027 #include <string.h> 00028 #include <iostream> 00029 #include <typeinfo> 00030 00031 namespace co 00032 { 00033 namespace base 00034 { 00042 template< typename T > class Monitor 00043 { 00044 public: 00046 Monitor() : _value( T( 0 )) {} 00047 00049 explicit Monitor( const T& value ) : _value( value ) {} 00050 00052 Monitor( const Monitor< T >& from ) : _value( from._value ) {} 00053 00055 ~Monitor() {} 00056 00060 Monitor& operator++ () 00061 { 00062 _cond.lock(); 00063 ++_value; 00064 _cond.broadcast(); 00065 _cond.unlock(); 00066 return *this; 00067 } 00068 00070 Monitor& operator-- () 00071 { 00072 _cond.lock(); 00073 --_value; 00074 _cond.broadcast(); 00075 _cond.unlock(); 00076 return *this; 00077 } 00078 00080 Monitor& operator = ( const T& value ) 00081 { 00082 set( value ); 00083 return *this; 00084 } 00085 00087 const Monitor& operator = ( const Monitor< T >& from ) 00088 { 00089 set( from._value ); 00090 return *this; 00091 } 00092 00094 Monitor& operator |= ( const T& value ) 00095 { 00096 _cond.lock(); 00097 _value |= value; 00098 _cond.broadcast(); 00099 _cond.unlock(); 00100 return *this; 00101 } 00102 00104 void set( const T& value ) 00105 { 00106 _cond.lock(); 00107 _value = value; 00108 _cond.broadcast(); 00109 _cond.unlock(); 00110 } 00112 00120 const T& waitEQ( const T& value ) const 00121 { 00122 if( _value == value ) 00123 return value; 00124 _cond.lock(); 00125 while( _value != value ) 00126 _cond.wait(); 00127 _cond.unlock(); 00128 return value; 00129 } 00130 00136 const T waitNE( const T& value ) const 00137 { 00138 const T current = _value; 00139 if( current != value ) 00140 return current; 00141 00142 _cond.lock(); 00143 while( _value == value ) 00144 _cond.wait(); 00145 const T newValue = _value; 00146 _cond.unlock(); 00147 return newValue; 00148 } 00149 00155 const T waitNE( const T& v1, const T& v2 ) const 00156 { 00157 const T current = _value; 00158 if( current != v1 && current != v2 ) 00159 return current; 00160 00161 _cond.lock(); 00162 while( _value == v1 || _value == v2 ) 00163 _cond.wait(); 00164 const T newValue = _value; 00165 _cond.unlock(); 00166 return newValue; 00167 } 00168 00175 const T waitGE( const T& value ) const 00176 { 00177 const T current = _value; 00178 if( current >= value ) 00179 return current; 00180 00181 _cond.lock(); 00182 while( _value < value ) 00183 _cond.wait(); 00184 const T newValue = _value; 00185 _cond.unlock(); 00186 return newValue; 00187 } 00194 const T waitLE( const T& value ) const 00195 { 00196 const T current = _value; 00197 if( current <= value ) 00198 return current; 00199 00200 _cond.lock(); 00201 while( _value > value ) 00202 _cond.wait(); 00203 const T newValue = _value; 00204 _cond.unlock(); 00205 return newValue; 00206 } 00207 00217 bool timedWaitEQ( const T& value, const uint32_t timeout ) const 00218 { 00219 if( _value == value ) 00220 return true; 00221 00222 _cond.lock(); 00223 while( _value != value ) 00224 { 00225 if( !_cond.timedWait( timeout ) ) 00226 { 00227 _cond.unlock(); 00228 return false; 00229 } 00230 } 00231 _cond.unlock(); 00232 return true; 00233 } 00234 00243 bool timedWaitGE( const T& value, const uint32_t timeout ) const 00244 { 00245 if( _value >= value ) 00246 return true; 00247 00248 _cond.lock(); 00249 while( _value < value ) 00250 { 00251 if ( !_cond.timedWait( timeout ) ) 00252 { 00253 _cond.unlock(); 00254 return false; 00255 } 00256 } 00257 _cond.unlock(); 00258 return true; 00259 } 00261 00264 bool operator == ( const T& value ) const { return _value == value; } 00265 bool operator != ( const T& value ) const { return _value != value; } 00266 bool operator < ( const T& value ) const { return _value < value; } 00267 bool operator > ( const T& value ) const { return _value > value; } 00268 bool operator <= ( const T& value ) const { return _value <= value; } 00269 bool operator >= ( const T& value ) const { return _value >= value; } 00270 00271 bool operator == ( const Monitor<T>& rhs ) const 00272 { return _value == rhs._value; } 00273 bool operator != ( const Monitor<T>& rhs ) const 00274 { return _value != rhs._value; } 00275 bool operator < ( const Monitor<T>& rhs ) const 00276 { return _value < rhs._value; } 00277 bool operator > ( const Monitor<T>& rhs ) const 00278 { return _value > rhs._value; } 00279 bool operator <= ( const Monitor<T>& rhs ) const 00280 { return _value <= rhs._value; } 00281 bool operator >= ( const Monitor<T>& rhs ) const 00282 { return _value >= rhs._value; } 00284 00288 const T& operator->() const { return _value; } 00289 00291 const T& get() const { return _value; } 00292 00294 T operator + ( const T& value ) const { return _value + value; } 00295 00297 T operator | ( const T& value ) const 00298 { return static_cast< T >( _value | value ); } 00299 00301 T operator & ( const T& value ) const 00302 { return static_cast< T >( _value & value ); } 00304 00305 private: 00306 T _value; 00307 mutable Condition _cond; 00308 }; 00309 00310 typedef Monitor< bool > Monitorb; 00311 typedef Monitor< uint32_t > Monitoru; 00312 00314 template< typename T > 00315 inline std::ostream& operator << ( std::ostream& os, 00316 const Monitor<T>& monitor ) 00317 { 00318 os << "Monitor< " << monitor.get() << " >"; 00319 return os; 00320 } 00321 00322 template<> inline Monitor< bool >& Monitor< bool >::operator++ () 00323 { 00324 _cond.lock(); 00325 assert( !_value ); 00326 _value = !_value; 00327 _cond.broadcast(); 00328 _cond.unlock(); 00329 return *this; 00330 } 00331 00332 template<> inline Monitor< bool >& Monitor< bool >::operator-- () 00333 { 00334 _cond.lock(); 00335 assert( !_value ); 00336 _value = !_value; 00337 _cond.broadcast(); 00338 _cond.unlock(); 00339 return *this; 00340 } 00341 00342 template<> 00343 inline Monitor< bool >& Monitor< bool >::operator |= ( const bool& value ) 00344 { 00345 if( value ) 00346 _value = value; 00347 return *this; 00348 } 00349 } 00350 } 00351 #endif //COBASE_MONITOR_H