From 16bfa361724f31bf433c2811b4f0e594de034bce Mon Sep 17 00:00:00 2001 From: rich_sposato Date: Sat, 22 Oct 2011 00:29:15 +0000 Subject: [PATCH] Moved constructions of ThreadPool into blocks within functions. Added cout lines to say when tests start and finish. git-svn-id: svn://svn.code.sf.net/p/loki-lib/code/trunk@1167 7ec92016-0320-0410-acc4-a06ded1c099a --- test/LevelMutex/MultiThreadTests.cpp | 296 +++++++++++++++++---------- 1 file changed, 188 insertions(+), 108 deletions(-) diff --git a/test/LevelMutex/MultiThreadTests.cpp b/test/LevelMutex/MultiThreadTests.cpp index 06713c0..5774ded 100644 --- a/test/LevelMutex/MultiThreadTests.cpp +++ b/test/LevelMutex/MultiThreadTests.cpp @@ -4,9 +4,9 @@ // Copyright (c) 2008, 2009 Richard Sposato // The copyright on this file is protected under the terms of the MIT license. // -// Permission to use, copy, modify, distribute and sell this software for any -// purpose is hereby granted without fee, provided that the above copyright -// notice appear in all copies and that both that copyright notice and this +// Permission to use, copy, modify, distribute and sell this software for any +// purpose is hereby granted without fee, provided that the above copyright +// notice appear in all copies and that both that copyright notice and this // permission notice appear in supporting documentation. // // The author makes no representations about the suitability of this software @@ -22,11 +22,10 @@ #include "MultiThreadTests.hpp" #include -#include #include #include -#include +#include #include "ThreadPool.hpp" #include "Thing.hpp" @@ -239,29 +238,40 @@ void * ValueUnsafeThread( void * p ) void MultiThreadSimpleTest( void ) { + cout << "Starting MultiThreadSimpleTest." << endl; + + char ender; Thing::Init( 0 ); const unsigned int threadCount = 5; - ThreadPool pool( threadCount ); - cout << endl << "Doing thread-locked print test. This test should pass. and not deadlock" << endl; - ::system( "pause" ); - for ( unsigned int ii = 0; ii < threadCount; ++ii ) { - void * p = reinterpret_cast< void * >( ii ); - pool.Start( PrintSafeThread, p ); + ThreadPool pool( threadCount ); + cout << "Doing thread-locked print test. This test should pass and not deadlock" << endl; + cout << "Press key to start test. "; + cin.get( ender ); + for ( unsigned int ii = 0; ii < threadCount; ++ii ) + { + void * p = reinterpret_cast< void * >( ii ); + pool.Start( PrintSafeThread, p ); + } + pool.JoinAll(); } - pool.JoinAll(); - cout << endl << "Doing thread-unsafe print test. This test may fail." << endl; - ::system( "pause" ); - for ( unsigned int ii = 0; ii < threadCount; ++ii ) { - void * p = reinterpret_cast< void * >( ii ); - pool.Start( PrintUnsafeThread, p ); + ThreadPool pool( threadCount ); + cout << endl << "Doing thread-unsafe print test. This test may fail, but not deadlock." << endl; + cout << "Press key to start test. "; + cin.get( ender ); + for ( unsigned int ii = 0; ii < threadCount; ++ii ) + { + void * p = reinterpret_cast< void * >( ii ); + pool.Start( PrintUnsafeThread, p ); + } + pool.JoinAll(); } - pool.JoinAll(); Thing::Destroy(); + cout << "Finished MultiThreadSimpleTest." << endl; } // ---------------------------------------------------------------------------- @@ -289,6 +299,7 @@ void * TryLockThread( void * p ) } const unsigned int gotValue = thing.GetValue(); assert( gotValue != value ); + (void)gotValue; } assert( mutex.IsLockedByAnotherThread() ); @@ -299,13 +310,13 @@ void * TryLockThread( void * p ) void MultiThreadTryLockTest( void ) { + cout << "Starting MultiThreadTryLockTest." << endl; + + char ender; static const unsigned int threadCount = 3; Thing::Init( 0 ); volatile Thing & thing = Thing::GetIt(); volatile SleepMutex & mutex = thing.GetMutex(); - - cout << endl << "Doing multi-threaded TryLock test. This test should not deadlock." << endl; - ::system( "pause" ); // First step is to lock the mutex in the main thread so no child thread // can ever lock it, change the value, or anything like that. MutexErrors::Type result = mutex.Lock(); @@ -313,15 +324,22 @@ void MultiThreadTryLockTest( void ) bool okay = mutex.IsLockedByCurrentThread(); assert( okay ); thing.SetValue( threadCount ); - ThreadPool pool( threadCount ); - for ( unsigned int ii = 0; ii < threadCount; ++ii ) + { - void * p = reinterpret_cast< void * >( ii ); - pool.Start( TryLockThread, p ); + ThreadPool pool( threadCount ); + cout << endl << "Doing multi-threaded TryLock test. This test should not deadlock." << endl; + cout << "Press key to start test. "; + cin.get( ender ); + for ( unsigned int ii = 0; ii < threadCount; ++ii ) + { + void * p = reinterpret_cast< void * >( ii ); + pool.Start( TryLockThread, p ); + } + pool.JoinAll(); + const unsigned int value = thing.GetValue(); + assert( value == threadCount ); } - pool.JoinAll(); - const unsigned int value = thing.GetValue(); - assert( value == threadCount ); + result = mutex.Unlock(); assert( MutexErrors::Success == result ); okay = !mutex.IsLockedByCurrentThread(); @@ -330,39 +348,53 @@ void MultiThreadTryLockTest( void ) assert( okay ); Thing::Destroy(); + + cout << "Finished MultiThreadTryLockTest." << endl; } // ---------------------------------------------------------------------------- void MultiThreadReentrantTest( void ) { + cout << "Starting MultiThreadReentrantTest." << endl; + + char ender; Thing::Init( 0 ); const unsigned int threadCount = 8; TestResults::Create( threadCount ); - ThreadPool pool( threadCount ); - cout << endl << "Doing thread-safe value test. This test should pass and not deadlock." << endl; - ::system( "pause" ); - for ( unsigned int ii = 0; ii < threadCount; ++ii ) { - void * p = reinterpret_cast< void * >( ii ); - pool.Start( ValueSafeThread, p ); + ThreadPool pool( threadCount ); + cout << endl << "Doing thread-safe value test. This test should pass and not deadlock." << endl; + cout << "Press key to start test. "; + cin.get( ender ); + for ( unsigned int ii = 0; ii < threadCount; ++ii ) + { + void * p = reinterpret_cast< void * >( ii ); + pool.Start( ValueSafeThread, p ); + } + pool.JoinAll(); + TestResults::GetIt()->OutputResults(); } - pool.JoinAll(); - TestResults::GetIt()->OutputResults(); - cout << endl << "Doing thread-unsafe value test. This test may fail." << endl; - ::system( "pause" ); - for ( unsigned int ii = 0; ii < threadCount; ++ii ) { - void * p = reinterpret_cast< void * >( ii ); - pool.Start( ValueUnsafeThread, p ); + ThreadPool pool( threadCount ); + cout << endl << "Doing thread-unsafe value test. This test may fail." << endl; + cout << "Press key to start test. "; + cin.get( ender ); + for ( unsigned int ii = 0; ii < threadCount; ++ii ) + { + void * p = reinterpret_cast< void * >( ii ); + pool.Start( ValueUnsafeThread, p ); + } + pool.JoinAll(); + TestResults::GetIt()->OutputResults(); } - pool.JoinAll(); - TestResults::GetIt()->OutputResults(); TestResults::Destroy(); Thing::Destroy(); + + cout << "Finished MultiThreadReentrantTest." << endl; } // ---------------------------------------------------------------------------- @@ -567,6 +599,7 @@ void * MultiLockSafeThread( void * p ) bool okay = locker.Unlock(); assert( okay ); + (void)okay; ::GoToSleep( 2 ); } } @@ -646,34 +679,46 @@ void * MultiLockUnsafeThread( void * p ) void MultiThreadMultiLockTest( void ) { + cout << "Starting MultiThreadMultiLockTest." << endl; + + char ender; Thing::MakePool( thingCount ); const unsigned int threadCount = 8; TestResults::Create( threadCount ); - ThreadPool pool( threadCount ); - cout << endl << "Doing thread-safe multi-lock test. This test should pass and not deadlock." << endl; - ::system( "pause" ); - for ( unsigned int ii = 0; ii < threadCount; ++ii ) { - void * p = reinterpret_cast< void * >( ii ); - pool.Start( MultiLockSafeThread, p ); + ThreadPool pool( threadCount ); + cout << endl << "Doing thread-safe multi-lock test. This test should pass and not deadlock." << endl; + cout << "Press key to start test. "; + cin.get( ender ); + for ( unsigned int ii = 0; ii < threadCount; ++ii ) + { + void * p = reinterpret_cast< void * >( ii ); + pool.Start( MultiLockSafeThread, p ); + } + pool.JoinAll(); + TestResults::GetIt()->OutputResults(); } - pool.JoinAll(); - TestResults::GetIt()->OutputResults(); - cout << endl << "Doing thread-unsafe multi-lock test. This test may fail." << endl; - TestResults::GetIt()->Reset( threadCount ); - ::system( "pause" ); - for ( unsigned int ii = 0; ii < threadCount; ++ii ) { - void * p = reinterpret_cast< void * >( ii ); - pool.Start( MultiLockUnsafeThread, p ); + ThreadPool pool( threadCount ); + cout << endl << "Doing thread-unsafe multi-lock test. This test may fail." << endl; + TestResults::GetIt()->Reset( threadCount ); + cout << "Press key to start test. "; + cin.get( ender ); + for ( unsigned int ii = 0; ii < threadCount; ++ii ) + { + void * p = reinterpret_cast< void * >( ii ); + pool.Start( MultiLockUnsafeThread, p ); + } + pool.JoinAll(); + TestResults::GetIt()->OutputResults(); } - pool.JoinAll(); - TestResults::GetIt()->OutputResults(); TestResults::Destroy(); Thing::DestroyPool(); + + cout << "Finished MultiThreadMultiLockTest." << endl; } // ---------------------------------------------------------------------------- @@ -770,7 +815,7 @@ void * MultiLockRandomUnsafeThread( void * p ) place += ::rand() % 3; if ( thingCount <= place ) break; - thing = thing = const_cast< Thing * >( Thing::GetFromPool( place ) ); + thing = const_cast< Thing * >( Thing::GetFromPool( place ) ); assert( nullptr != thing ); pool.push_back( thing ); } @@ -808,34 +853,46 @@ void * MultiLockRandomUnsafeThread( void * p ) void MultiThreadRandomMultiLockTest( void ) { + cout << "Starting MultiThreadRandomMultiLockTest." << endl; + + char ender; Thing::MakePool( thingCount ); const unsigned int threadCount = 8; TestResults::Create( threadCount ); - ThreadPool pool( threadCount ); - cout << endl << "Doing thread-safe random multi-lock test. This test should pass and not deadlock." << endl; - ::system( "pause" ); - for ( unsigned int ii = 0; ii < threadCount; ++ii ) { - void * p = reinterpret_cast< void * >( ii ); - pool.Start( MultiLockRandomSafeThread, p ); + ThreadPool pool( threadCount ); + cout << endl << "Doing thread-safe random multi-lock test. This test should pass and not deadlock." << endl; + cout << "Press key to start test. "; + cin.get( ender ); + for ( unsigned int ii = 0; ii < threadCount; ++ii ) + { + void * p = reinterpret_cast< void * >( ii ); + pool.Start( MultiLockRandomSafeThread, p ); + } + pool.JoinAll(); + TestResults::GetIt()->OutputResults(); } - pool.JoinAll(); - TestResults::GetIt()->OutputResults(); - cout << endl << "Doing thread-unsafe random multi-lock test. This test may fail." << endl; - TestResults::GetIt()->Reset( threadCount ); - ::system( "pause" ); - for ( unsigned int ii = 0; ii < threadCount; ++ii ) { - void * p = reinterpret_cast< void * >( ii ); - pool.Start( MultiLockRandomUnsafeThread, p ); + ThreadPool pool( threadCount ); + cout << endl << "Doing thread-unsafe random multi-lock test. This test may fail." << endl; + TestResults::GetIt()->Reset( threadCount ); + cout << "Press key to start test. "; + cin.get( ender ); + for ( unsigned int ii = 0; ii < threadCount; ++ii ) + { + void * p = reinterpret_cast< void * >( ii ); + pool.Start( MultiLockRandomUnsafeThread, p ); + } + pool.JoinAll(); + TestResults::GetIt()->OutputResults(); } - pool.JoinAll(); - TestResults::GetIt()->OutputResults(); TestResults::Destroy(); Thing::DestroyPool(); + + cout << "Finished MultiThreadRandomMultiLockTest." << endl; } // ---------------------------------------------------------------------------- @@ -936,34 +993,46 @@ void * UnsafeHierarchyTest( void * p ) void MultiThreadHierarchySingleLockTest( void ) { + cout << "Starting MultiThreadHierarchySingleLockTest." << endl; + + char ender; LevelThing::MakePool( thingCount ); const unsigned int threadCount = 8; TestResults::Create( threadCount ); - ThreadPool pool( threadCount ); - cout << endl << "Doing thread-safe hierarchy test. This test should pass and not deadlock." << endl; - ::system( "pause" ); - for ( unsigned int ii = 0; ii < threadCount; ++ii ) { - void * p = reinterpret_cast< void * >( ii ); - pool.Start( SafeHierarchyTest, p ); + ThreadPool pool( threadCount ); + cout << endl << "Doing thread-safe hierarchy test. This test should pass and not deadlock." << endl; + cout << "Press key to start test. "; + cin.get( ender ); + for ( unsigned int ii = 0; ii < threadCount; ++ii ) + { + void * p = reinterpret_cast< void * >( ii ); + pool.Start( SafeHierarchyTest, p ); + } + pool.JoinAll(); + TestResults::GetIt()->OutputResults(); } - pool.JoinAll(); - TestResults::GetIt()->OutputResults(); - cout << endl << "Doing thread-unsafe hierarchy test. This test may fail." << endl; - ::system( "pause" ); - TestResults::GetIt()->Reset( threadCount ); - for ( unsigned int ii = 0; ii < threadCount; ++ii ) { - void * p = reinterpret_cast< void * >( ii ); - pool.Start( UnsafeHierarchyTest, p ); + ThreadPool pool( threadCount ); + cout << endl << "Doing thread-unsafe hierarchy test. This test may fail." << endl; + cout << "Press key to start test. "; + cin.get( ender ); + TestResults::GetIt()->Reset( threadCount ); + for ( unsigned int ii = 0; ii < threadCount; ++ii ) + { + void * p = reinterpret_cast< void * >( ii ); + pool.Start( UnsafeHierarchyTest, p ); + } + pool.JoinAll(); + TestResults::GetIt()->OutputResults(); } - pool.JoinAll(); - TestResults::GetIt()->OutputResults(); TestResults::Destroy(); LevelThing::DestroyPool(); + + cout << "Finished MultiThreadHierarchySingleLockTest." << endl; } // ---------------------------------------------------------------------------- @@ -1064,35 +1133,46 @@ void * UnsafeHierarchyMultiLockTest( void * p ) void MultiThreadHierarchyMultiLockTest( void ) { + cout << "Starting MultiThreadHierarchyMultiLockTest." << endl; + char ender; MultiLevelPool::MakePool( 10, thingCount ); const unsigned int threadCount = 8; TestResults::Create( threadCount ); - ThreadPool pool( threadCount ); - cout << endl << "Doing thread-safe multilock hierarchy test. This test should pass and not deadlock." << endl; - ::system( "pause" ); - for ( unsigned int ii = 0; ii < threadCount; ++ii ) { - void * p = reinterpret_cast< void * >( ii ); - pool.Start( SafeHierarchyMultiLockTest, p ); + ThreadPool pool( threadCount ); + cout << endl << "Doing thread-safe multilock hierarchy test. This test should pass and not deadlock." << endl; + cout << "Press key to start test. "; + cin.get( ender ); + for ( unsigned int ii = 0; ii < threadCount; ++ii ) + { + void * p = reinterpret_cast< void * >( ii ); + pool.Start( SafeHierarchyMultiLockTest, p ); + } + pool.JoinAll(); + TestResults::GetIt()->OutputResults(); } - pool.JoinAll(); - TestResults::GetIt()->OutputResults(); - cout << endl << "Doing thread-unsafe multilock hierarchy test. This test may fail." << endl; - ::system( "pause" ); - TestResults::GetIt()->Reset( threadCount ); - for ( unsigned int ii = 0; ii < threadCount; ++ii ) { - void * p = reinterpret_cast< void * >( ii ); - pool.Start( UnsafeHierarchyMultiLockTest, p ); + ThreadPool pool( threadCount ); + cout << endl << "Doing thread-unsafe multilock hierarchy test. This test may fail." << endl; + cout << "Press key to start test. "; + cin.get( ender ); + TestResults::GetIt()->Reset( threadCount ); + for ( unsigned int ii = 0; ii < threadCount; ++ii ) + { + void * p = reinterpret_cast< void * >( ii ); + pool.Start( UnsafeHierarchyMultiLockTest, p ); + } + pool.JoinAll(); + TestResults::GetIt()->OutputResults(); } - pool.JoinAll(); - TestResults::GetIt()->OutputResults(); TestResults::Destroy(); MultiLevelPool::DestroyPool(); + + cout << "Finished MultiThreadHierarchyMultiLockTest." << endl; } // ----------------------------------------------------------------------------