From: <ric...@us...> - 2011-10-04 23:46:36
|
Revision: 1139 http://loki-lib.svn.sourceforge.net/loki-lib/?rev=1139&view=rev Author: rich_sposato Date: 2011-10-04 23:46:30 +0000 (Tue, 04 Oct 2011) Log Message: ----------- Added tests for bug 2694067. Modified Paths: -------------- trunk/test/SafeFormat/SafeFormat.cbp trunk/test/SafeFormat/main.cpp Added Paths: ----------- trunk/test/SafeFormat/ThreadPool.cpp trunk/test/SafeFormat/ThreadPool.hpp Modified: trunk/test/SafeFormat/SafeFormat.cbp =================================================================== --- trunk/test/SafeFormat/SafeFormat.cbp 2011-10-04 23:42:48 UTC (rev 1138) +++ trunk/test/SafeFormat/SafeFormat.cbp 2011-10-04 23:46:30 UTC (rev 1139) @@ -6,23 +6,24 @@ <Option compiler="cygwin" /> <Build> <Target title="Debug_GCC"> - <Option output="bin\Debug_GCC\SafeFormat" prefix_auto="1" extension_auto="1" /> - <Option object_output="obj\Debug_GCC\" /> + <Option output="bin/Debug_GCC/SafeFormat" prefix_auto="1" extension_auto="1" /> + <Option object_output="obj/Debug_GCC/" /> <Option type="1" /> <Option compiler="gcc" /> <Compiler> + <Add option="-g" /> <Add option="-W" /> - <Add option="-g" /> - <Add directory="..\..\include\loki" /> - <Add directory="..\..\include" /> + <Add directory="../../include/loki" /> + <Add directory="../../include" /> </Compiler> <Linker> - <Add library="..\..\lib\GCC\Loki_D.a" /> + <Add library="../../lib/GCC/Loki_D.a" /> + <Add library="/usr/lib/libpthread.so" /> </Linker> </Target> <Target title="Release_GCC"> - <Option output="bin\Release_GCC\SafeFormat" prefix_auto="1" extension_auto="1" /> - <Option object_output="obj\Release_GCC\" /> + <Option output="bin/Release_GCC/SafeFormat" prefix_auto="1" extension_auto="1" /> + <Option object_output="obj/Release_GCC/" /> <Option type="1" /> <Option compiler="gcc" /> <Compiler> @@ -30,31 +31,31 @@ <Add option="-Os" /> <Add option="-O3" /> <Add option="-W" /> - <Add directory="..\..\include\loki" /> - <Add directory="..\..\include" /> + <Add directory="../../include/loki" /> + <Add directory="../../include" /> </Compiler> <Linker> - <Add library="..\..\lib\GCC\Loki.a" /> + <Add library="../../lib/GCC/Loki.a" /> </Linker> </Target> <Target title="Debug_Cygwin"> - <Option output="bin\Debug_Cygwin\SafeFormat" prefix_auto="1" extension_auto="1" /> - <Option object_output="obj\Debug_Cygwin\" /> + <Option output="bin/Debug_Cygwin/SafeFormat" prefix_auto="1" extension_auto="1" /> + <Option object_output="obj/Debug_Cygwin/" /> <Option type="1" /> <Option compiler="cygwin" /> <Compiler> <Add option="-W" /> <Add option="-g" /> - <Add directory="..\..\include\loki" /> - <Add directory="..\..\include" /> + <Add directory="../../include/loki" /> + <Add directory="../../include" /> </Compiler> <Linker> - <Add library="..\..\lib\Cygwin\Loki_D.a" /> + <Add library="../../lib/Cygwin/Loki_D.a" /> </Linker> </Target> <Target title="Release_Cygwin"> - <Option output="bin\Release_Cygwin\SafeFormat" prefix_auto="1" extension_auto="1" /> - <Option object_output="obj\Release_Cygwin\" /> + <Option output="bin/Release_Cygwin/SafeFormat" prefix_auto="1" extension_auto="1" /> + <Option object_output="obj/Release_Cygwin/" /> <Option type="1" /> <Option compiler="cygwin" /> <Compiler> @@ -62,14 +63,16 @@ <Add option="-Os" /> <Add option="-O3" /> <Add option="-W" /> - <Add directory="..\..\include\loki" /> - <Add directory="..\..\include" /> + <Add directory="../../include/loki" /> + <Add directory="../../include" /> </Compiler> <Linker> - <Add library="..\..\lib\Cygwin\Loki.a" /> + <Add library="../../lib/Cygwin/Loki.a" /> </Linker> </Target> </Build> + <Unit filename="ThreadPool.cpp" /> + <Unit filename="ThreadPool.hpp" /> <Unit filename="main.cpp" /> <Extensions> <code_completion /> Added: trunk/test/SafeFormat/ThreadPool.cpp =================================================================== --- trunk/test/SafeFormat/ThreadPool.cpp (rev 0) +++ trunk/test/SafeFormat/ThreadPool.cpp 2011-10-04 23:46:30 UTC (rev 1139) @@ -0,0 +1,112 @@ +//////////////////////////////////////////////////////////////////////////////// +// +// ThreadLocal test program for The Loki Library +// Copyright (c) 2009 by Richard Sposato +// The copyright on this file is protected under the terms of the MIT license. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. +// +//////////////////////////////////////////////////////////////////////////////// + +// ---------------------------------------------------------------------------- + +#include "ThreadPool.hpp" + +#include <sstream> + +// ---------------------------------------------------------------------------- + +Thread::Thread( CallFunction func, void * parm ) + : pthread_() + , func_( func ) + , parm_( parm ) +{ +} + +// ---------------------------------------------------------------------------- + +void Thread::AssignTask( CallFunction func, void * parm ) +{ + func_ = func; + parm_ = parm; +} + +// ---------------------------------------------------------------------------- + +int Thread::Start( void ) +{ + return LOKI_pthread_create( &pthread_, NULL, func_, parm_ ); +} + +// ---------------------------------------------------------------------------- + +int Thread::WaitForThread( void ) const +{ + return LOKI_pthread_join( pthread_ ); +} + +// ---------------------------------------------------------------------------- + +ThreadPool::ThreadPool( void ) : m_threads() +{ +} + +// ---------------------------------------------------------------------------- + +ThreadPool::~ThreadPool( void ) +{ + for ( size_t ii = 0; ii < m_threads.size(); ++ii ) + { + delete m_threads.at(ii); + } +} + +// ---------------------------------------------------------------------------- + +void ThreadPool::Create( size_t threadCount, Thread::CallFunction function ) +{ + for( size_t ii = 0; ii < threadCount; ii++ ) + { + ::std::stringstream buffer; + Thread * thread = new Thread( function, + reinterpret_cast< void * >( ii + 1 ) ); + m_threads.push_back( thread ); + } +} + +// ---------------------------------------------------------------------------- + +void ThreadPool::Start( void ) +{ + for ( size_t ii = 0; ii < m_threads.size(); ii++ ) + { + ::std::stringstream buffer; + m_threads.at( ii )->Start(); + } +} + +// ---------------------------------------------------------------------------- + +void ThreadPool::Join( void ) const +{ + for ( size_t ii = 0; ii < m_threads.size(); ii++ ) + m_threads.at( ii )->WaitForThread(); +} + +// ---------------------------------------------------------------------------- Added: trunk/test/SafeFormat/ThreadPool.hpp =================================================================== --- trunk/test/SafeFormat/ThreadPool.hpp (rev 0) +++ trunk/test/SafeFormat/ThreadPool.hpp 2011-10-04 23:46:30 UTC (rev 1139) @@ -0,0 +1,119 @@ +//////////////////////////////////////////////////////////////////////////////// +// +// ThreadLocal test program for The Loki Library +// Copyright (c) 2009 by Richard Sposato +// The copyright on this file is protected under the terms of the MIT license. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. +// +//////////////////////////////////////////////////////////////////////////////// + + +// ---------------------------------------------------------------------------- + +#include <vector> + +#if !defined( NULL ) + #define NULL 0 +#endif + +// define nullptr even though new compilers will have this keyword just so we +// have a consistent and easy way of identifying which uses of 0 mean null. +#if !defined( nullptr ) + #define nullptr NULL +#endif + +#if defined(_WIN32) + + #include <process.h> + #include <windows.h> + + typedef unsigned int ( WINAPI * ThreadFunction_ )( void * ); + + #define LOKI_pthread_t HANDLE + + #define LOKI_pthread_create( handle, attr, func, arg ) \ + ( int )( ( *handle = ( HANDLE ) _beginthreadex ( NULL, 0, ( ThreadFunction_ )func, arg, 0, NULL ) ) == NULL ) + + #define LOKI_pthread_join( thread ) \ + ( ( WaitForSingleObject( ( thread ), INFINITE ) != WAIT_OBJECT_0 ) || !CloseHandle( thread ) ) + +#else + + #include <pthread.h> + + #define LOKI_pthread_t \ + pthread_t + #define LOKI_pthread_create(handle,attr,func,arg) \ + pthread_create(handle,attr,func,arg) + #define LOKI_pthread_join(thread) \ + pthread_join(thread, NULL) + +#endif + +// ---------------------------------------------------------------------------- + +class Thread +{ +public: + + typedef void * ( * CallFunction )( void * ); + + Thread( CallFunction func, void * parm ); + + void AssignTask( CallFunction func, void * parm ); + + int Start( void ); + + int WaitForThread( void ) const; + +private: + + LOKI_pthread_t pthread_; + + CallFunction func_; + + void * parm_; + +}; + +// ---------------------------------------------------------------------------- + +class ThreadPool +{ +public: + + ThreadPool( void ); + + ~ThreadPool( void ); + + void Create( size_t threadCount, Thread::CallFunction function ); + + void Start( void ); + + void Join( void ) const; + +private: + + typedef ::std::vector< Thread * > Threads; + + Threads m_threads; +}; + +// ---------------------------------------------------------------------------- Modified: trunk/test/SafeFormat/main.cpp =================================================================== --- trunk/test/SafeFormat/main.cpp 2011-10-04 23:42:48 UTC (rev 1138) +++ trunk/test/SafeFormat/main.cpp 2011-10-04 23:46:30 UTC (rev 1139) @@ -20,7 +20,9 @@ #include <cstdlib> #include "../SmallObj/timer.h" +#include "ThreadPool.hpp" + #if defined(_MSC_VER) #if _MSC_VER >= 1400 #define sprintf sprintf_s @@ -146,7 +148,7 @@ t.start(); for (int i=loop; i > 0; --i) - Printf("Hey, %u frobnicators and %u twiddlicators\n")(i)(i); + ::Loki::Printf("Hey, %u frobnicators and %u twiddlicators\n")(i)(i); t.stop(); int t_Printf = t.t(); @@ -354,11 +356,126 @@ } } - cout << endl << "Finished RandomTest" << endl; + cout << "Finished RandomTest" << endl; } // ---------------------------------------------------------------------------- +void * DoLokiPrintfLoop( void * p ) +{ + const unsigned int threadIndex = reinterpret_cast< unsigned int >( p ); + + for ( unsigned int loop = 0; loop < 10; ++loop ) + { + ::Loki::Printf( "Loop: [%u] Thread: [%u]\n" )( loop )( threadIndex ); + } + + return 0; +} + +// ---------------------------------------------------------------------------- + +void * DoLokiFPrintfLoop( void * p ) +{ + const unsigned int threadIndex = reinterpret_cast< unsigned int >( p ); + + for ( unsigned int loop = 0; loop < 10; ++loop ) + { + ::Loki::FPrintf( cout, "Loop: [%u] Thread: [%u]\n" )( loop )( threadIndex ); + } + + return 0; +} + +// ---------------------------------------------------------------------------- + +void * DoCoutLoop( void * p ) +{ + const unsigned int threadIndex = reinterpret_cast< unsigned int >( p ); + + for ( unsigned int loop = 0; loop < 10; ++loop ) + { + cout << "Loop: [" << loop << "] Thread: [" << threadIndex << "]\n"; + } + + return 0; +} + +// ---------------------------------------------------------------------------- + +void * DoStdOutLoop( void * p ) +{ + const unsigned int threadIndex = reinterpret_cast< unsigned int >( p ); + + for ( unsigned int loop = 0; loop < 10; ++loop ) + { + printf( "Loop: [%d] Thread: [%d]\n", loop, threadIndex ); + } + + return 0; +} + +// ---------------------------------------------------------------------------- + +void AtomicTest( void ) +{ + char ender; + + cout << "Starting Loki::Printf AtomicTest" << endl; + { + ThreadPool pool; + pool.Create( 20, &DoLokiPrintfLoop ); + pool.Start(); + pool.Join(); + } + cout << "Finished Loki::Printf AtomicTest." << endl; + cout << "If the output lines up in neat columns, the test passed." << endl; + cout << "If the output is not in columns, then the test failed." << endl; + cout << "Press <Enter> key to continue. "; + cin.get( ender ); + + cout << "Starting Loki::FPrintf AtomicTest" << endl; + { + ThreadPool pool; + pool.Create( 20, &DoLokiFPrintfLoop ); + pool.Start(); + pool.Join(); + } + cout << "Finished Loki::FPrintf AtomicTest." << endl; + cout << "If the output lines up in neat columns, the test passed." << endl; + cout << "If the output is not in columns, then the test failed." << endl; + cout << "Press <Enter> key to continue. "; + cin.get( ender ); + + cout << "Starting stdout AtomicTest" << endl; + { + ThreadPool pool; + pool.Create( 20, &DoStdOutLoop ); + pool.Start(); + pool.Join(); + } + cout << "Finished stdout AtomicTest." << endl; + cout << "If the output lines up in neat columns, your compiler implements printf correctly." << endl; + cout << "If the output is not in columns, then your compiler implements printf incorrectly." << endl; + cout << "Press <Enter> key to continue. "; + cin.get( ender ); + + cout << "Starting cout AtomicTest" << endl; + { + ThreadPool pool; + pool.Create( 20, &DoCoutLoop ); + pool.Start(); + pool.Join(); + } + cout << "Finished cout AtomicTest." << endl; + cout << "If the output lines up in neat columns, your compiler implements cout correctly." << endl; + cout << "If the output is not in columns, then your compiler implements cout incorrectly." << endl; + cout << "Press <Enter> key to continue. "; + cin.get( ender ); +} + +// ---------------------------------------------------------------------------- + class CommandLineArgs { public: @@ -371,6 +488,7 @@ inline bool DoSpeedTest( void ) const { return ( 0 < m_speedLoopCount ); } inline bool DoRandomTest( void ) const { return ( 0 < m_randomLoopCount ); } inline bool DoFormatTest( void ) const { return m_doFormatTest; } + inline bool DoAtomicTest( void ) const { return m_doAtomicTest; } inline bool DoShowHelp( void ) const { return m_showHelp; } void ShowHelp( void ) const; @@ -380,6 +498,7 @@ unsigned int m_speedLoopCount; unsigned int m_randomLoopCount; bool m_doFormatTest; + bool m_doAtomicTest; bool m_showHelp; const char * m_exeName; }; @@ -390,6 +509,7 @@ m_speedLoopCount( 0 ), m_randomLoopCount( 0 ), m_doFormatTest( false ), + m_doAtomicTest( false ), m_showHelp( false ), m_exeName( argv[0] ) { @@ -416,6 +536,7 @@ default: isValid = false; break; case 'h': m_showHelp = true; break; case 'f': m_doFormatTest = true; break; + case 'a': m_doAtomicTest = true; break; case 'r': { @@ -458,6 +579,7 @@ cout << "Usage: " << m_exeName << " [-h] [-f] [-r:#] [-s:#]" << endl; cout << " -h Show this help info and exit. Overrides all other options." << endl; cout << " -f Run formatting tests." << endl; + cout << " -a Run atomic tests." << endl; cout << " -r:# Run random tests for # of loops. # is a positive decimal value greater than 100." << endl; cout << " -s:# Run speed tests for # of loops. # is a positive decimal value greater than 100." << endl; } @@ -487,6 +609,10 @@ { FormatTest(); } + if ( args.DoAtomicTest() ) + { + AtomicTest(); + } } // ---------------------------------------------------------------------------- This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |