LCOV - code coverage report
Current view: top level - tests - monitor.cpp (source / functions) Hit Total Coverage
Test: Lunchbox Lines: 116 118 98.3 %
Date: 2016-03-29 17:09:06 Functions: 12 14 85.7 %

          Line data    Source code
       1             : 
       2             : /* Copyright (c) 2010-2012, Stefan Eilemann <eile@equalizergraphics.com>
       3             :  *
       4             :  * This library is free software; you can redistribute it and/or modify it under
       5             :  * the terms of the GNU Lesser General Public License version 2.1 as published
       6             :  * by the Free Software Foundation.
       7             :  *
       8             :  * This library is distributed in the hope that it will be useful, but WITHOUT
       9             :  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
      10             :  * FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
      11             :  * details.
      12             :  *
      13             :  * You should have received a copy of the GNU Lesser General Public License
      14             :  * along with this library; if not, write to the Free Software Foundation, Inc.,
      15             :  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
      16             :  */
      17             : 
      18             : #define TEST_RUNTIME 300 // seconds
      19             : #include "test.h"
      20             : 
      21             : #include <lunchbox/clock.h>
      22             : #include <lunchbox/monitor.h>
      23             : #include <lunchbox/thread.h>
      24             : #include <iostream>
      25             : 
      26             : using servus::uint128_t;
      27             : 
      28           1 : lunchbox::Monitor< int64_t > monitor;
      29           1 : lunchbox::Monitor< bool > boolMonitor;
      30             : 
      31             : class Thread1 : public lunchbox::Thread
      32             : {
      33             : public:
      34           1 :     explicit Thread1( int64_t loops ) : _loops( loops ) {}
      35           1 :     virtual ~Thread1() {}
      36           1 :     virtual void run()
      37             :         {
      38           1 :             int64_t nOps = _loops;
      39           1 :             lunchbox::Clock clock;
      40      200002 :             while( nOps-- )
      41             :             {
      42      200000 :                 monitor.waitEQ( nOps );
      43      200000 :                 monitor = -nOps;
      44             :             }
      45             : 
      46           1 :             const float time = clock.getTimef();
      47           1 :             std::cout << 2*_loops / time << " ops/ms" << std::endl;
      48           1 :         }
      49             : private:
      50             :     int64_t _loops;
      51             : };
      52             : 
      53           1 : void testSimpleMonitor()
      54             : {
      55           1 :     TEST( !boolMonitor );
      56           1 :     boolMonitor = true;
      57           1 :     TEST( boolMonitor );
      58             : 
      59           1 :     const int64_t loops = 200000;
      60           1 :     int64_t nOps = loops;
      61           1 :     Thread1 waiter( nOps );
      62             : 
      63           1 :     TEST( waiter.start( ));
      64           2 :     lunchbox::Clock clock;
      65             : 
      66      200002 :     while( nOps-- )
      67             :     {
      68      200000 :         monitor = nOps;
      69      200000 :         monitor.waitEQ( -nOps );
      70             :     }
      71             : 
      72           1 :     const float time = clock.getTimef();
      73             : 
      74           1 :     TEST( waiter.join( ));
      75           2 :     std::cout << 2*loops / time << " ops/ms" << std::endl;
      76           1 : }
      77             : 
      78             : class Thread2 : public lunchbox::Thread
      79             : {
      80             : public:
      81           2 :     explicit Thread2( size_t loops )
      82             :         : innerLoops( 0 )
      83           2 :         , _outerLoops( loops )
      84           2 :     {}
      85             : 
      86           2 :     virtual ~Thread2() {}
      87           2 :     virtual void run()
      88             :         {
      89           2 :             lunchbox::Clock clock;
      90           2 :             size_t ops = 0;
      91           6 :             for( size_t k = 0; k != 2; ++k )
      92             :             {
      93        4004 :                 for( size_t i = 0; i != _outerLoops; ++i )
      94             :                 {
      95        4000 :                     const int64_t loops = innerLoops.waitNE( 0 );
      96        4000 :                     innerLoops = 0;
      97     2006000 :                     for( int64_t j = 0; j != loops; ++j )
      98             :                     {
      99     2002000 :                         if (innerLoops > 0)
     100           0 :                             abort();
     101     2002000 :                         ++monitor;
     102             :                     }
     103        4000 :                     ops += loops * 2 + 2;
     104             :                 }
     105             :             }
     106             : 
     107           6 :             for( size_t k = 0; k != 2; ++k )
     108             :             {
     109        4004 :                 for( size_t i = 0; i != _outerLoops; ++i )
     110             :                 {
     111        4000 :                     const int64_t loops = innerLoops.waitNE( 0 );
     112        4000 :                     innerLoops = 0;
     113     2006000 :                     for( int64_t j = 0; j != loops; ++j )
     114             :                     {
     115     2002000 :                         if (innerLoops > 0)
     116           0 :                             abort();
     117     2002000 :                         --monitor;
     118             :                     }
     119        4000 :                     ops += loops * 2 + 2;
     120             :                 }
     121             :             }
     122             : 
     123           2 :             const float time = clock.getTimef();
     124           2 :             std::cout << ops/time << " ops/ms" << std::endl;
     125           2 :         }
     126             : 
     127             :     lunchbox::Monitor< int64_t > innerLoops;
     128             : private:
     129             :     size_t _outerLoops;
     130             : };
     131             : 
     132           1 : void testMonitorComparisons()
     133             : {
     134           1 :     boolMonitor = true;
     135           1 :     const int64_t loops = 1000;
     136           1 :     Thread2 waiter( loops );
     137           1 :     TEST( waiter.start( ));
     138             : 
     139        1001 :     for( int64_t i = 0; i != loops; ++i )
     140             :     {
     141        1000 :         monitor = 0;
     142        1000 :         waiter.innerLoops = i + 1;
     143        1000 :         TEST( monitor.waitGE( i + 1 ) >= i + 1 );
     144        1000 :         TEST( monitor >= i + 1 );
     145             :     }
     146             : 
     147        1001 :     for( int64_t i = 0; i != loops; ++i )
     148             :     {
     149        1000 :         monitor = 0;
     150        1000 :         waiter.innerLoops = i + 1;
     151        1000 :         TEST( monitor.waitGT( i ) > i );
     152        1000 :         TEST( monitor > i );
     153             :     }
     154             : 
     155        1001 :     for( int64_t i = 0; i != loops; ++i )
     156             :     {
     157        1000 :         monitor = i + 1;
     158        1000 :         waiter.innerLoops = i + 1;
     159        1000 :         TEST( monitor.waitLE( 0 ) <= 0 );
     160        1000 :         TEST( monitor <= 0 );
     161             :     }
     162             : 
     163        1001 :     for( int64_t i = 0; i != loops; ++i )
     164             :     {
     165        1000 :         monitor = i + 1;
     166        1000 :         waiter.innerLoops = i + 1;
     167        1000 :         TEST( monitor.waitLT( 1 ) < 1 );
     168        1000 :         TEST( monitor < 1 );
     169             :     }
     170             : 
     171           1 :     TEST( waiter.join( ));
     172           1 : }
     173             : 
     174           1 : void testTimedMonitorComparisons()
     175             : {
     176           1 :     boolMonitor = true;
     177           1 :     const size_t loops = 1000;
     178           1 :     Thread2 waiter( loops );
     179           1 :     TEST( waiter.start( ));
     180           1 :     const uint32_t timeout = 1;
     181             : 
     182        1001 :     for( size_t i = 0; i != loops; ++i )
     183             :     {
     184        1000 :         monitor = 0;
     185        1000 :         waiter.innerLoops = i + 1;
     186        1000 :         while( !monitor.timedWaitGE( i + 1, timeout ))
     187             :             ;
     188        1000 :         TEST( monitor >= i + 1 );
     189             :     }
     190        1001 :     for( size_t i = 0; i != loops; ++i )
     191             :     {
     192        1000 :         monitor = 0;
     193        1000 :         waiter.innerLoops = i + 1;
     194        1000 :         while( !monitor.timedWaitGT( i, timeout ))
     195             :             ;
     196        1000 :         TEST( monitor > i );
     197             :     }
     198        1001 :     for( size_t i = 0; i != loops; ++i )
     199             :     {
     200        1000 :         monitor = i + 1;
     201        1000 :         waiter.innerLoops = i + 1;
     202        1000 :         while( !monitor.timedWaitLE( 0, timeout ))
     203             :             ;
     204        1000 :         TEST( monitor <= 0 );
     205             :     }
     206        1001 :     for( size_t i = 0; i != loops; ++i )
     207             :     {
     208        1000 :         monitor = i + 1;
     209        1000 :         waiter.innerLoops = i + 1;
     210        1000 :         while( !monitor.timedWaitLT( 1, timeout ))
     211             :             ;
     212        1000 :         TEST( monitor < 1 );
     213             :     }
     214             : 
     215           1 :     TEST( waiter.join( ));
     216           1 : }
     217             : 
     218           1 : int main( int, char** )
     219             : {
     220           1 :     testSimpleMonitor();
     221           1 :     testMonitorComparisons();
     222           1 :     testTimedMonitorComparisons();
     223           1 :     return EXIT_SUCCESS;
     224           3 : }

Generated by: LCOV version 1.11