|
From: <ric...@us...> - 2011-09-29 20:36:45
|
Revision: 1118
http://loki-lib.svn.sourceforge.net/loki-lib/?rev=1118&view=rev
Author: rich_sposato
Date: 2011-09-29 20:36:38 +0000 (Thu, 29 Sep 2011)
Log Message:
-----------
Moved some code in main.cpp to separate files.
Modified Paths:
--------------
trunk/test/ThreadLocal/ThreadLocal.cbp
trunk/test/ThreadLocal/main.cpp
Added Paths:
-----------
trunk/test/ThreadLocal/ThreadPool.cpp
trunk/test/ThreadLocal/ThreadPool.hpp
trunk/test/ThreadLocal/ThreadTests.cpp
Modified: trunk/test/ThreadLocal/ThreadLocal.cbp
===================================================================
--- trunk/test/ThreadLocal/ThreadLocal.cbp 2011-09-29 19:56:39 UTC (rev 1117)
+++ trunk/test/ThreadLocal/ThreadLocal.cbp 2011-09-29 20:36:38 UTC (rev 1118)
@@ -7,21 +7,24 @@
<Option compiler="gcc" />
<Build>
<Target title="Debug_GCC">
- <Option output="obj\Debug_GCC\ThreadLocal" prefix_auto="1" extension_auto="1" />
- <Option object_output="obj\Debug_GCC\" />
+ <Option output="obj/Debug_GCC/ThreadLocal" prefix_auto="1" extension_auto="1" />
+ <Option object_output="obj/Debug_GCC/" />
<Option type="1" />
<Option compiler="gcc" />
<Compiler>
<Add option="-Wmain" />
<Add option="-pedantic" />
- <Add option="-W" />
<Add option="-g" />
- <Add directory="..\..\include" />
+ <Add option="-W -lc" />
+ <Add directory="../../include" />
</Compiler>
+ <Linker>
+ <Add library="/usr/lib/libpthread.a" />
+ </Linker>
</Target>
<Target title="Release_GCC">
- <Option output="obj\Release_GCC\ThreadLocal" prefix_auto="1" extension_auto="1" />
- <Option object_output="obj\Release_GCC\" />
+ <Option output="obj/Release_GCC/ThreadLocal" prefix_auto="1" extension_auto="1" />
+ <Option object_output="obj/Release_GCC/" />
<Option type="1" />
<Option compiler="gcc" />
<Compiler>
@@ -41,6 +44,7 @@
<code_completion />
<debugger />
<lib_finder disable_auto="1" />
+ <envvars />
</Extensions>
</Project>
</CodeBlocks_project_file>
Added: trunk/test/ThreadLocal/ThreadPool.cpp
===================================================================
--- trunk/test/ThreadLocal/ThreadPool.cpp (rev 0)
+++ trunk/test/ThreadLocal/ThreadPool.cpp 2011-09-29 20:36:38 UTC (rev 1118)
@@ -0,0 +1,117 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+// 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>
+#include <iostream>
+
+// ----------------------------------------------------------------------------
+
+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;
+ buffer << "Creating thread " << ii << ::std::endl;
+ ::std::cout << buffer.rdbuf();
+ 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;
+ buffer << "Starting thread " << ii << ::std::endl;
+ ::std::cout << buffer.rdbuf();
+ 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/ThreadLocal/ThreadPool.hpp
===================================================================
--- trunk/test/ThreadLocal/ThreadPool.hpp (rev 0)
+++ trunk/test/ThreadLocal/ThreadPool.hpp 2011-09-29 20:36:38 UTC (rev 1118)
@@ -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;
+};
+
+// ----------------------------------------------------------------------------
Added: trunk/test/ThreadLocal/ThreadTests.cpp
===================================================================
--- trunk/test/ThreadLocal/ThreadTests.cpp (rev 0)
+++ trunk/test/ThreadLocal/ThreadTests.cpp 2011-09-29 20:36:38 UTC (rev 1118)
@@ -0,0 +1,246 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+// 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 <loki/ThreadLocal.h>
+
+#include <vector>
+#include <sstream>
+#include <iostream>
+
+#include <cassert>
+
+
+// ----------------------------------------------------------------------------
+
+typedef ::std::vector< unsigned int > IntVector;
+
+static LOKI_THREAD_LOCAL unsigned int StandaloneStaticValue = 0;
+
+static const unsigned int ThreadCount = 4;
+
+// ----------------------------------------------------------------------------
+
+IntVector & GetIntVector( void )
+{
+ unsigned int v = 0;
+ static IntVector addresses( ThreadCount, v );
+ return addresses;
+}
+
+// ----------------------------------------------------------------------------
+
+void * AddToIntVector( void * p )
+{
+ assert( 0 == StandaloneStaticValue );
+ const unsigned int ii = reinterpret_cast< unsigned int >( p );
+ assert( 0 < ii );
+ assert( ii < ThreadCount + 1 );
+ StandaloneStaticValue = ii;
+ IntVector & v = GetIntVector();
+ v[ ii - 1 ] = StandaloneStaticValue;
+ assert( ii == StandaloneStaticValue );
+ assert( v[ ii - 1 ] == StandaloneStaticValue );
+ return nullptr;
+}
+
+// ----------------------------------------------------------------------------
+
+bool TestThreadLocalStaticValue( void )
+{
+ assert( StandaloneStaticValue == 0 );
+ {
+ ThreadPool pool;
+ pool.Create( ThreadCount, &AddToIntVector );
+ pool.Start();
+ pool.Join();
+ }
+
+ bool allDifferent = true;
+ IntVector & v = GetIntVector();
+ for ( unsigned int i1 = 0; i1 < ThreadCount - 1; ++i1 )
+ {
+ const unsigned int v1 = v[ i1 ];
+ for ( unsigned int i2 = i1 + 1; i2 < ThreadCount; ++i2 )
+ {
+ const unsigned int v2 = v[ i2 ];
+ if ( v1 == v2 )
+ {
+ allDifferent = false;
+ break;
+ }
+ }
+ if ( !allDifferent )
+ break;
+ }
+ assert( StandaloneStaticValue == 0 );
+
+ return allDifferent;
+}
+
+// ----------------------------------------------------------------------------
+
+unsigned int & GetFunctionThreadLocalValue( void )
+{
+ static LOKI_THREAD_LOCAL unsigned int FunctionStaticValue = 0;
+ return FunctionStaticValue;
+}
+
+// ----------------------------------------------------------------------------
+
+void * ChangeFunctionStaticValue( void * p )
+{
+ unsigned int & thatValue = GetFunctionThreadLocalValue();
+ assert( 0 == thatValue );
+ const unsigned int ii = reinterpret_cast< unsigned int >( p );
+ assert( 0 < ii );
+ assert( ii < ThreadCount + 1 );
+ thatValue = ii + ThreadCount;
+ IntVector & v = GetIntVector();
+ v[ ii - 1 ] = thatValue + ThreadCount;
+ assert( ii + ThreadCount == thatValue );
+ assert( v[ ii - 1 ] == thatValue + ThreadCount );
+ return nullptr;
+}
+
+// ----------------------------------------------------------------------------
+
+bool TestThreadLocalFunctionStaticValue( void )
+{
+ assert( GetFunctionThreadLocalValue() == 0 );
+
+ IntVector & v = GetIntVector();
+ for ( unsigned int i0 = 0; i0 < v.size(); ++i0 )
+ {
+ v[ i0 ] = 0;
+ }
+
+ {
+ ThreadPool pool;
+ pool.Create( ThreadCount, &ChangeFunctionStaticValue );
+ pool.Start();
+ pool.Join();
+ }
+
+ bool allDifferent = true;
+ for ( unsigned int i1 = 0; i1 < ThreadCount - 1; ++i1 )
+ {
+ const unsigned int v1 = v[ i1 ];
+ for ( unsigned int i2 = i1 + 1; i2 < ThreadCount; ++i2 )
+ {
+ const unsigned int v2 = v[ i2 ];
+ if ( v1 == v2 )
+ {
+ allDifferent = false;
+ break;
+ }
+ }
+ if ( !allDifferent )
+ break;
+ }
+ assert( GetFunctionThreadLocalValue() == 0 );
+
+ return allDifferent;
+}
+
+// ----------------------------------------------------------------------------
+
+class ThreadAware
+{
+public:
+
+ static inline void SetValue( unsigned int value ) { ClassThreadLocal = value; }
+
+ static inline unsigned int GetValue( void ) { return ClassThreadLocal; }
+
+private:
+
+ static LOKI_THREAD_LOCAL unsigned int ClassThreadLocal;
+
+};
+
+LOKI_THREAD_LOCAL unsigned int ThreadAware::ClassThreadLocal = 0;
+
+// ----------------------------------------------------------------------------
+
+void * ChangeClassStaticValue( void * p )
+{
+ assert( ThreadAware::GetValue() == 0 );
+ const unsigned int ii = reinterpret_cast< unsigned int >( p );
+ assert( 0 < ii );
+ assert( ii < ThreadCount + 1 );
+ ThreadAware::SetValue( ii + 2 * ThreadCount );
+ IntVector & v = GetIntVector();
+ v[ ii - 1 ] = ThreadAware::GetValue();
+ assert( v[ ii - 1 ] == ThreadAware::GetValue() );
+ assert( ThreadAware::GetValue() == ii + 2 * ThreadCount );
+ return nullptr;
+}
+
+// ----------------------------------------------------------------------------
+
+bool TestThreadLocalClassStaticValue( void )
+{
+ assert( ThreadAware::GetValue() == 0 );
+
+ IntVector & v = GetIntVector();
+ for ( unsigned int i0 = 0; i0 < v.size(); ++i0 )
+ {
+ v[ i0 ] = 0;
+ }
+
+ {
+ ThreadPool pool;
+ pool.Create( ThreadCount, &ChangeClassStaticValue );
+ pool.Start();
+ pool.Join();
+ }
+
+ bool allDifferent = true;
+ for ( unsigned int i1 = 0; i1 < ThreadCount - 1; ++i1 )
+ {
+ const unsigned int v1 = v[ i1 ];
+ for ( unsigned int i2 = i1 + 1; i2 < ThreadCount; ++i2 )
+ {
+ const unsigned int v2 = v[ i2 ];
+ if ( v1 == v2 )
+ {
+ allDifferent = false;
+ break;
+ }
+ }
+ if ( !allDifferent )
+ break;
+ }
+ assert( ThreadAware::GetValue() == 0 );
+
+ return allDifferent;
+}
+
+// ----------------------------------------------------------------------------
Modified: trunk/test/ThreadLocal/main.cpp
===================================================================
--- trunk/test/ThreadLocal/main.cpp 2011-09-29 19:56:39 UTC (rev 1117)
+++ trunk/test/ThreadLocal/main.cpp 2011-09-29 20:36:38 UTC (rev 1118)
@@ -4,367 +4,48 @@
// Copyright (c) 2009 by 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 notice appear in supporting documentation.
+// 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 author makes no representations about the suitability of this software
-// for any purpose. It is provided "as is" without express or implied warranty.
+// 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.
+//
////////////////////////////////////////////////////////////////////////////////
-// $Id$
+// ----------------------------------------------------------------------------
+#include <cstdlib>
-// ----------------------------------------------------------------------------
+#include <iostream>
-#include <loki/ThreadLocal.h>
-#include <loki/Threads.h>
-
-#include <vector>
-#include <sstream>
-#include <iostream>
-
-
using namespace ::std;
-
-#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>
+extern bool TestThreadLocalClassStaticValue( void );
- typedef unsigned int ( WINAPI * ThreadFunction_ )( void * );
+extern bool TestThreadLocalFunctionStaticValue( void );
- #define LOKI_pthread_t HANDLE
+extern bool TestThreadLocalStaticValue( void );
- #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
-
- #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
+int main( int argc, const char * const argv[] )
{
-public:
-
- typedef void * ( * CallFunction )( void * );
-
- Thread( CallFunction func, void * parm )
- : pthread_()
- , func_( func )
- , parm_( parm )
- {
- }
-
- void AssignTask( CallFunction func, void * parm )
- {
- func_ = func;
- parm_ = parm;
- }
-
- int Start( void )
- {
- return LOKI_pthread_create( &pthread_, NULL, func_, parm_ );
- }
-
- int WaitForThread( void ) const
- {
- return LOKI_pthread_join( pthread_ );
- }
-
-private:
- LOKI_pthread_t pthread_;
- CallFunction func_;
- void * parm_;
-};
-
-// ----------------------------------------------------------------------------
-
-class ThreadPool
-{
-public:
- ThreadPool( void ) : m_threads()
- {
- }
-
- void Create( size_t threadCount, Thread::CallFunction function )
- {
- for( size_t ii = 0; ii < threadCount; ii++ )
- {
- stringstream buffer;
- buffer << "Creating thread " << ii << endl;
- cout << buffer.rdbuf();
- Thread * thread = new Thread( function,
- reinterpret_cast< void * >( ii + 1 ) );
- m_threads.push_back( thread );
- }
- }
-
- void Start( void )
- {
- for ( size_t ii = 0; ii < m_threads.size(); ii++ )
- {
- stringstream buffer;
- buffer << "Starting thread " << ii << endl;
- cout << buffer.rdbuf();
- m_threads.at( ii )->Start();
- }
- }
-
- void Join( void ) const
- {
- for ( size_t ii = 0; ii < m_threads.size(); ii++ )
- m_threads.at( ii )->WaitForThread();
- }
-
- ~ThreadPool( void )
- {
- for ( size_t ii = 0; ii < m_threads.size(); ii++ )
- {
- delete m_threads.at(ii);
- }
- }
-
-private:
- typedef std::vector< Thread * > Threads;
-
- Threads m_threads;
-};
-
-// ----------------------------------------------------------------------------
+ (void)argc;
+ (void)argv;
-typedef ::std::vector< unsigned int > IntVector;
-
-static LOKI_THREAD_LOCAL unsigned int StandaloneStaticValue = 0;
-
-static const unsigned int ThreadCount = 4;
-
-// ----------------------------------------------------------------------------
-
-IntVector & GetIntVector( void )
-{
- unsigned int v = 0;
- static IntVector addresses( ThreadCount, v );
- return addresses;
-}
-
-// ----------------------------------------------------------------------------
-
-void * AddToIntVector( void * p )
-{
- assert( 0 == StandaloneStaticValue );
- const unsigned int ii = reinterpret_cast< unsigned int >( p );
- assert( 0 < ii );
- assert( ii < ThreadCount + 1 );
- StandaloneStaticValue = ii;
- IntVector & v = GetIntVector();
- v[ ii - 1 ] = StandaloneStaticValue;
- assert( ii == StandaloneStaticValue );
- assert( v[ ii - 1 ] == StandaloneStaticValue );
- return nullptr;
-}
-
-// ----------------------------------------------------------------------------
-
-bool TestThreadLocalStaticValue( void )
-{
- assert( StandaloneStaticValue == 0 );
- {
- ThreadPool pool;
- pool.Create( ThreadCount, &AddToIntVector );
- pool.Start();
- pool.Join();
- }
-
- bool allDifferent = true;
- IntVector & v = GetIntVector();
- for ( unsigned int i1 = 0; i1 < ThreadCount - 1; ++i1 )
- {
- const unsigned int v1 = v[ i1 ];
- for ( unsigned int i2 = i1 + 1; i2 < ThreadCount; ++i2 )
- {
- const unsigned int v2 = v[ i2 ];
- if ( v1 == v2 )
- {
- allDifferent = false;
- break;
- }
- }
- if ( !allDifferent )
- break;
- }
- assert( StandaloneStaticValue == 0 );
-
- return allDifferent;
-}
-
-// ----------------------------------------------------------------------------
-
-unsigned int & GetFunctionThreadLocalValue( void )
-{
- static LOKI_THREAD_LOCAL unsigned int FunctionStaticValue = 0;
- return FunctionStaticValue;
-}
-
-// ----------------------------------------------------------------------------
-
-void * ChangeFunctionStaticValue( void * p )
-{
- unsigned int & thatValue = GetFunctionThreadLocalValue();
- assert( 0 == thatValue );
- const unsigned int ii = reinterpret_cast< unsigned int >( p );
- assert( 0 < ii );
- assert( ii < ThreadCount + 1 );
- thatValue = ii + ThreadCount;
- IntVector & v = GetIntVector();
- v[ ii - 1 ] = thatValue + ThreadCount;
- assert( ii + ThreadCount == thatValue );
- assert( v[ ii - 1 ] == thatValue + ThreadCount );
- return nullptr;
-}
-
-// ----------------------------------------------------------------------------
-
-bool TestThreadLocalFunctionStaticValue( void )
-{
- assert( GetFunctionThreadLocalValue() == 0 );
-
- IntVector & v = GetIntVector();
- for ( unsigned int i0 = 0; i0 < v.size(); ++i0 )
- {
- v[ i0 ] = 0;
- }
-
- {
- ThreadPool pool;
- pool.Create( ThreadCount, &ChangeFunctionStaticValue );
- pool.Start();
- pool.Join();
- }
-
- bool allDifferent = true;
- for ( unsigned int i1 = 0; i1 < ThreadCount - 1; ++i1 )
- {
- const unsigned int v1 = v[ i1 ];
- for ( unsigned int i2 = i1 + 1; i2 < ThreadCount; ++i2 )
- {
- const unsigned int v2 = v[ i2 ];
- if ( v1 == v2 )
- {
- allDifferent = false;
- break;
- }
- }
- if ( !allDifferent )
- break;
- }
- assert( GetFunctionThreadLocalValue() == 0 );
-
- return allDifferent;
-}
-
-// ----------------------------------------------------------------------------
-
-class ThreadAware
-{
-public:
-
- static inline void SetValue( unsigned int value ) { ClassThreadLocal = value; }
-
- static inline unsigned int GetValue( void ) { return ClassThreadLocal; }
-
-private:
-
- static LOKI_THREAD_LOCAL unsigned int ClassThreadLocal;
-
-};
-
-LOKI_THREAD_LOCAL unsigned int ThreadAware::ClassThreadLocal = 0;
-
-// ----------------------------------------------------------------------------
-
-void * ChangeClassStaticValue( void * p )
-{
- assert( ThreadAware::GetValue() == 0 );
- const unsigned int ii = reinterpret_cast< unsigned int >( p );
- assert( 0 < ii );
- assert( ii < ThreadCount + 1 );
- ThreadAware::SetValue( ii + 2 * ThreadCount );
- IntVector & v = GetIntVector();
- v[ ii - 1 ] = ThreadAware::GetValue();
- assert( v[ ii - 1 ] == ThreadAware::GetValue() );
- assert( ThreadAware::GetValue() == ii + 2 * ThreadCount );
- return nullptr;
-}
-
-// ----------------------------------------------------------------------------
-
-bool TestThreadLocalClassStaticValue( void )
-{
- assert( ThreadAware::GetValue() == 0 );
-
- IntVector & v = GetIntVector();
- for ( unsigned int i0 = 0; i0 < v.size(); ++i0 )
- {
- v[ i0 ] = 0;
- }
-
- {
- ThreadPool pool;
- pool.Create( ThreadCount, &ChangeClassStaticValue );
- pool.Start();
- pool.Join();
- }
-
- bool allDifferent = true;
- for ( unsigned int i1 = 0; i1 < ThreadCount - 1; ++i1 )
- {
- const unsigned int v1 = v[ i1 ];
- for ( unsigned int i2 = i1 + 1; i2 < ThreadCount; ++i2 )
- {
- const unsigned int v2 = v[ i2 ];
- if ( v1 == v2 )
- {
- allDifferent = false;
- break;
- }
- }
- if ( !allDifferent )
- break;
- }
- assert( ThreadAware::GetValue() == 0 );
-
- return allDifferent;
-}
-
-// ----------------------------------------------------------------------------
-
-int main( int argc, const char * const argv[] )
-{
bool okay = true;
cout << "Starting ThreadLocal tests." << endl;
cout << "If any tests fail, or any assertions fail," << endl
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|