Equalizer  1.2.1
monitor.h
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
Generated on Fri Jun 8 2012 15:44:31 for Equalizer 1.2.1 by  doxygen 1.8.0