LCOV - code coverage report
Current view: top level - lunchbox - mtQueue.ipp (source / functions) Hit Total Coverage
Test: lcov2.info Lines: 35 36 97.2 %
Date: 2014-08-05 Functions: 5 5 100.0 %

          Line data    Source code
       1             : 
       2             : /* Copyright (c) 2005-2012, Stefan Eilemann <eile@equalizergraphics.com>
       3             :  *                    2012, Daniel Nachbaur <danielnachbaur@gmail.com>
       4             :  *
       5             :  * This library is free software; you can redistribute it and/or modify it under
       6             :  * the terms of the GNU Lesser General Public License version 2.1 as published
       7             :  * by the Free Software Foundation.
       8             :  *
       9             :  * This library is distributed in the hope that it will be useful, but WITHOUT
      10             :  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
      11             :  * FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
      12             :  * details.
      13             :  *
      14             :  * You should have received a copy of the GNU Lesser General Public License
      15             :  * along with this library; if not, write to the Free Software Foundation, Inc.,
      16             :  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
      17             :  */
      18             : 
      19             : namespace lunchbox
      20             : {
      21             : template< typename T, size_t S >
      22             : MTQueue< T, S >& MTQueue< T, S >::operator = ( const MTQueue< T, S >& from )
      23             : {
      24             :     if( this != &from )
      25             :     {
      26             :         from._cond.lock();
      27             :         std::deque< T > copy = from._queue;
      28             :         const size_t maxSize = from._maxSize;
      29             :         from._cond.unlock();
      30             : 
      31             :         _cond.lock();
      32             :         _maxSize = maxSize;
      33             :         _queue.swap( copy );
      34             :         _cond.signal();
      35             :         _cond.unlock();
      36             :     }
      37             :     return *this;
      38             : }
      39             : 
      40             : template< typename T, size_t S >
      41             : const T& MTQueue< T, S >::operator[]( const size_t index ) const
      42             : {
      43             :     _cond.lock();
      44             :     while( _queue.size() <= index )
      45             :         _cond.wait();
      46             : 
      47             :     LBASSERT( _queue.size() > index );
      48             :     const T& element = _queue[index];
      49             :     _cond.unlock();
      50             :     return element;
      51             : }
      52             : 
      53             : template< typename T, size_t S >
      54             : void MTQueue< T, S >::setMaxSize( const size_t maxSize )
      55             : {
      56             :     _cond.lock();
      57             :     while( _queue.size() > maxSize )
      58             :         _cond.wait();
      59             :     _maxSize = maxSize;
      60             :     _cond.signal();
      61             :     _cond.unlock();
      62             : }
      63             : 
      64             : template< typename T, size_t S >
      65             : size_t MTQueue< T, S >::waitSize( const size_t minSize ) const
      66             : {
      67             :     LBASSERT( minSize <= _maxSize );
      68             :     _cond.lock();
      69             :     while( _queue.size() < minSize )
      70             :         _cond.wait();
      71             :     const size_t size = _queue.size();
      72             :     _cond.unlock();
      73             :     return size;
      74             : }
      75             : 
      76             : template< typename T, size_t S >
      77             : void MTQueue< T, S >::clear()
      78             : {
      79             :     _cond.lock();
      80             :     _queue.clear();
      81             :     _cond.signal();
      82             :     _cond.unlock();
      83             : }
      84             : 
      85             : template< typename T, size_t S >
      86           5 : T MTQueue< T, S >::pop()
      87             : {
      88           5 :     _cond.lock();
      89          13 :     while( _queue.empty( ))
      90           3 :         _cond.wait();
      91             : 
      92           5 :     LBASSERT( !_queue.empty( ));
      93           5 :     T element = _queue.front();
      94           5 :     _queue.pop_front();
      95           5 :     _cond.signal();
      96           5 :     _cond.unlock();
      97           5 :     return element;
      98             : }
      99             : 
     100             : template< typename T, size_t S >
     101             : bool MTQueue< T, S >::timedPop( const unsigned timeout, T& element )
     102             : {
     103             :     _cond.lock();
     104             :     while( _queue.empty( ))
     105             :     {
     106             :         if( !_cond.timedWait( timeout ))
     107             :         {
     108             :             _cond.unlock();
     109             :             return false;
     110             :         }
     111             :     }
     112             :     LBASSERT( !_queue.empty( ));
     113             :     element = _queue.front();
     114             :     _queue.pop_front();
     115             :     _cond.signal();
     116             :     _cond.unlock();
     117             :     return true;
     118             : }
     119             : 
     120             : template< typename T, size_t S > std::vector< T >
     121             : MTQueue< T, S >::timedPopRange( const unsigned timeout, const size_t minimum,
     122             :                                 const size_t maximum )
     123             : {
     124             :     std::vector< T > result;
     125             : 
     126             :     _cond.lock();
     127             :     while( _queue.size() < minimum )
     128             :     {
     129             :         if( !_cond.timedWait( timeout ))
     130             :         {
     131             :             _cond.unlock();
     132             :             return result;
     133             :         }
     134             :     }
     135             : 
     136             :     const size_t size = LB_MIN( maximum, _queue.size( ));
     137             : 
     138             :     result.reserve( size );
     139             :     result.insert( result.end(), _queue.begin(), _queue.begin() + size );
     140             :     _queue.erase( _queue.begin(), _queue.begin() + size );
     141             : 
     142             :     _cond.unlock();
     143             :     return result;
     144             : }
     145             : 
     146             : template< typename T, size_t S >
     147             : bool MTQueue< T, S >::tryPop( T& result )
     148             : {
     149             :     _cond.lock();
     150             :     if( _queue.empty( ))
     151             :     {
     152             :         _cond.unlock();
     153             :         return false;
     154             :     }
     155             : 
     156             :     result = _queue.front();
     157             :     _queue.pop_front();
     158             :     _cond.signal();
     159             :     _cond.unlock();
     160             :     return true;
     161             : }
     162             : 
     163             : template< typename T, size_t S >
     164             : void MTQueue< T, S >::tryPop( const size_t num, std::vector< T >& result )
     165             : {
     166             :     _cond.lock();
     167             :     const size_t size = LB_MIN( num, _queue.size( ));
     168             :     if( size > 0 )
     169             :     {
     170             :         result.reserve( result.size() + size );
     171             :         for( size_t i = 0; i < size; ++i )
     172             :         {
     173             :             result.push_back( _queue.front( ));
     174             :             _queue.pop_front();
     175             :         }
     176             :         _cond.signal();
     177             :     }
     178             :     _cond.unlock();
     179             : }
     180             : 
     181             : /** Group descriptor for popBarrier(). @version 1.7.1 */
     182             : template< typename T, size_t S > class MTQueue< T, S >::Group
     183             : {
     184             :     friend class MTQueue< T, S >;
     185             :     size_t height_;
     186             :     size_t waiting_;
     187             : 
     188             : public:
     189             :     /**
     190             :      * Construct a new group of the given size. Can only be used once.
     191             :      * @version 1.7.1
     192             :      */
     193           1 :     explicit Group( const size_t height ) : height_( height ), waiting_( 0 ) {}
     194             : 
     195             :     /** Update the height. @version 1.7.1  */
     196             :     void setHeight( const size_t height ) { height_ = height; }
     197             : };
     198             : 
     199             : template< typename T, size_t S >
     200      100004 : bool MTQueue< T, S >::popBarrier( T& element, Group& barrier )
     201             : {
     202      100004 :     LBASSERT( barrier.height_ > 0 )
     203             : 
     204      100004 :     _cond.lock();
     205      100004 :     ++barrier.waiting_;
     206      227424 :     while( _queue.empty() && barrier.waiting_ < barrier.height_ )
     207       27416 :         _cond.wait();
     208             : 
     209      100004 :     if( _queue.empty( ))
     210             :     {
     211           5 :         LBASSERT( barrier.waiting_ == barrier.height_ );
     212           5 :         _cond.broadcast();
     213           5 :         _cond.unlock();
     214           5 :         return false;
     215             :     }
     216             : 
     217       99999 :     element = _queue.front();
     218       99999 :     _queue.pop_front();
     219       99999 :     --barrier.waiting_;
     220       99999 :     _cond.signal();
     221       99999 :     _cond.unlock();
     222       99999 :     return true;
     223             : 
     224             : }
     225             : 
     226             : template< typename T, size_t S >
     227             : bool MTQueue< T, S >::getFront( T& result ) const
     228             : {
     229             :     _cond.lock();
     230             :     if( _queue.empty( ))
     231             :     {
     232             :         _cond.unlock();
     233             :         return false;
     234             :     }
     235             :     // else
     236             :     result = _queue.front();
     237             :     _cond.unlock();
     238             :     return true;
     239             : }
     240             : 
     241             : template< typename T, size_t S >
     242             : bool MTQueue< T, S >::getBack( T& result ) const
     243             : {
     244             :     _cond.lock();
     245             :     if( _queue.empty( ))
     246             :     {
     247             :         _cond.unlock();
     248             :         return false;
     249             :     }
     250             :     // else
     251             :     result = _queue.back();
     252             :     _cond.unlock();
     253             :     return true;
     254             : }
     255             : 
     256             : template< typename T, size_t S >
     257      100004 : void MTQueue< T, S >::push( const T& element )
     258             : {
     259      100004 :     _cond.lock();
     260      200008 :     while( _queue.size() >= _maxSize )
     261           0 :         _cond.wait();
     262      100004 :     _queue.push_back( element );
     263      100004 :     _cond.signal();
     264      100004 :     _cond.unlock();
     265      100004 : }
     266             : 
     267             : template< typename T, size_t S >
     268             : void MTQueue< T, S >::push( const std::vector< T >& elements )
     269             : {
     270             :     _cond.lock();
     271             :     LBASSERT( elements.size() <= _maxSize );
     272             :     while( (_maxSize - _queue.size( )) < elements.size( ))
     273             :         _cond.wait();
     274             :     _queue.insert( _queue.end(), elements.begin(), elements.end( ));
     275             :     _cond.signal();
     276             :     _cond.unlock();
     277             : }
     278             : 
     279             : template< typename T, size_t S >
     280             : void MTQueue< T, S >::pushFront( const T& element )
     281             : {
     282             :     _cond.lock();
     283             :     while( _queue.size() >= _maxSize )
     284             :         _cond.wait();
     285             :     _queue.push_front( element );
     286             :     _cond.signal();
     287             :     _cond.unlock();
     288             : }
     289             : 
     290             : template< typename T, size_t S >
     291             : void MTQueue< T, S >::pushFront( const std::vector< T >& elements )
     292             : {
     293             :     _cond.lock();
     294             :     LBASSERT( elements.size() <= _maxSize );
     295             :     while( (_maxSize - _queue.size( )) < elements.size( ))
     296             :         _cond.wait();
     297             :     _queue.insert(_queue.begin(), elements.begin(), elements.end());
     298             :     _cond.signal();
     299             :     _cond.unlock();
     300             : }
     301             : }

Generated by: LCOV version 1.10