Boost logo

Boost-Commit :

From: pdimov_at_[hidden]
Date: 2008-04-20 11:37:09


Author: pdimov
Date: 2008-04-20 11:37:08 EDT (Sun, 20 Apr 2008)
New Revision: 44638
URL: http://svn.boost.org/trac/boost/changeset/44638

Log:
Factored out boost/detail/lightweight_thread.hpp.
Added:
   trunk/boost/detail/lightweight_thread.hpp (contents, props changed)
Text files modified:
   trunk/libs/smart_ptr/test/shared_ptr_mt_test.cpp | 139 ++++++---------------------------------
   trunk/libs/smart_ptr/test/weak_ptr_mt_test.cpp | 132 +++++--------------------------------
   2 files changed, 44 insertions(+), 227 deletions(-)

Added: trunk/boost/detail/lightweight_thread.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/detail/lightweight_thread.hpp 2008-04-20 11:37:08 EDT (Sun, 20 Apr 2008)
@@ -0,0 +1,135 @@
+#ifndef BOOST_DETAIL_LIGHTWEIGHT_THREAD_HPP_INCLUDED
+#define BOOST_DETAIL_LIGHTWEIGHT_THREAD_HPP_INCLUDED
+
+// MS compatible compilers support #pragma once
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif
+
+// boost/detail/lightweight_thread.hpp
+//
+// Copyright (c) 2002 Peter Dimov and Multi Media Ltd.
+// Copyright (c) 2008 Peter Dimov
+//
+// Distributed under the Boost Software License, Version 1.0.
+// See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt
+
+#include <boost/config.hpp>
+#include <memory>
+#include <cerrno>
+
+// pthread_create, pthread_join
+
+#if defined( BOOST_HAS_PTHREADS )
+
+#include <pthread.h>
+
+#else
+
+#include <windows.h>
+#include <process.h>
+
+typedef HANDLE pthread_t;
+
+int pthread_create( pthread_t * thread, void const *, unsigned (__stdcall * start_routine) (void*), void* arg )
+{
+ HANDLE h = (HANDLE)_beginthreadex( 0, 0, start_routine, arg, 0, 0 );
+
+ if( h != 0 )
+ {
+ *thread = h;
+ return 0;
+ }
+ else
+ {
+ return EAGAIN;
+ }
+}
+
+int pthread_join( pthread_t thread, void ** /*value_ptr*/ )
+{
+ ::WaitForSingleObject( thread, INFINITE );
+ ::CloseHandle( thread );
+ return 0;
+}
+
+#endif
+
+// template<class F> int lw_thread_create( pthread_t & pt, F f );
+
+namespace boost
+{
+
+namespace detail
+{
+
+class lw_abstract_thread
+{
+public:
+
+ virtual ~lw_abstract_thread() {}
+ virtual void run() = 0;
+};
+
+#if defined( BOOST_HAS_PTHREADS )
+
+extern "C" void * lw_thread_routine( void * pv )
+{
+ std::auto_ptr<lw_abstract_thread> pt( static_cast<lw_abstract_thread *>( pv ) );
+
+ pt->run();
+
+ return 0;
+}
+
+#else
+
+unsigned __stdcall lw_thread_routine( void * pv )
+{
+ std::auto_ptr<lw_abstract_thread> pt( static_cast<lw_abstract_thread *>( pv ) );
+
+ pt->run();
+
+ return 0;
+}
+
+#endif
+
+template<class F> class lw_thread_impl: public lw_abstract_thread
+{
+public:
+
+ explicit lw_thread_impl( F f ): f_( f )
+ {
+ }
+
+ void run()
+ {
+ f_();
+ }
+
+private:
+
+ F f_;
+};
+
+template<class F> int lw_thread_create( pthread_t & pt, F f )
+{
+ std::auto_ptr<lw_abstract_thread> p( new lw_thread_impl<F>( f ) );
+
+ int r = pthread_create( &pt, 0, lw_thread_routine, p.get() );
+
+ if( r == 0 )
+ {
+ p.release();
+ }
+
+ return r;
+}
+
+} // namespace detail
+} // namespace boost
+
+#endif // #ifndef BOOST_DETAIL_LIGHTWEIGHT_THREAD_HPP_INCLUDED

Modified: trunk/libs/smart_ptr/test/shared_ptr_mt_test.cpp
==============================================================================
--- trunk/libs/smart_ptr/test/shared_ptr_mt_test.cpp (original)
+++ trunk/libs/smart_ptr/test/shared_ptr_mt_test.cpp 2008-04-20 11:37:08 EDT (Sun, 20 Apr 2008)
@@ -7,167 +7,76 @@
 #pragma warning(disable: 4514) // unreferenced inline removed
 #endif
 
-//
 // shared_ptr_mt_test.cpp - tests shared_ptr with multiple threads
 //
 // Copyright (c) 2002 Peter Dimov and Multi Media Ltd.
+// Copyright (c) 2008 Peter Dimov
 //
-// Distributed under the Boost Software License, Version 1.0. (See
-// accompanying file LICENSE_1_0.txt or copy at
-// http://www.boost.org/LICENSE_1_0.txt)
-//
+// Distributed under the Boost Software License, Version 1.0.
+// See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt
 
 #include <boost/shared_ptr.hpp>
 #include <boost/bind.hpp>
 
 #include <vector>
-#include <memory>
-#include <stdexcept>
 
 #include <cstdio>
 #include <ctime>
 
-// 'portable' thread framework
-
-class abstract_thread
-{
-public:
-
- virtual ~abstract_thread() {}
- virtual void run() = 0;
-};
-
-#if !defined(BOOST_HAS_PTHREADS) && defined(BOOST_HAS_WINTHREADS)
-
-char const * title = "Using Windows threads";
-
-#include <windows.h>
-#include <process.h>
+#include <boost/detail/lightweight_thread.hpp>
 
-typedef HANDLE pthread_t;
+//
 
-unsigned __stdcall common_thread_routine(void * pv)
-{
- abstract_thread * pt = static_cast<abstract_thread *>(pv);
- pt->run();
- delete pt;
- return 0;
-}
+int const n = 1024 * 1024;
 
-int pthread_create(pthread_t * thread, void const *, unsigned (__stdcall * start_routine) (void*), void* arg)
+void test( boost::shared_ptr<int> const & pi )
 {
- HANDLE h = (HANDLE)_beginthreadex(0, 0, start_routine, arg, 0, 0);
+ std::vector< boost::shared_ptr<int> > v;
 
- if(h != 0)
+ for( int i = 0; i < n; ++i )
     {
- *thread = h;
- return 0;
- }
- else
- {
- return 1; // return errno;
+ v.push_back( pi );
     }
 }
 
-int pthread_join(pthread_t thread, void ** /*value_ptr*/)
-{
- ::WaitForSingleObject(thread, INFINITE);
- ::CloseHandle(thread);
- return 0;
-}
+int const m = 16; // threads
 
-#else
+#if defined( BOOST_HAS_PTHREADS )
 
-char const * title = "Using POSIX threads";
+char const * thmodel = "POSIX";
 
-#include <pthread.h>
+#else
 
-extern "C" void * common_thread_routine(void * pv)
-{
- abstract_thread * pt = static_cast<abstract_thread *>(pv);
- pt->run();
- delete pt;
- return 0;
-}
+char const * thmodel = "Windows";
 
 #endif
 
-//
-
-template<class F> class thread: public abstract_thread
-{
-public:
-
- explicit thread(F f): f_(f)
- {
- }
-
- void run()
- {
- f_();
- }
-
-private:
-
- F f_;
-};
-
-template<class F> pthread_t createThread(F f)
-{
- std::auto_ptr<abstract_thread> p(new thread<F>(f));
-
- pthread_t r;
-
- if(pthread_create(&r, 0, common_thread_routine, p.get()) == 0)
- {
- p.release();
- return r;
- }
-
- throw std::runtime_error("createThread failed.");
-}
-
-//
-
-int const n = 1024 * 1024;
-
-void test(boost::shared_ptr<int> const & pi)
-{
- std::vector< boost::shared_ptr<int> > v;
-
- for(int i = 0; i < n; ++i)
- {
- v.push_back(pi);
- }
-}
-
-int const m = 16; // threads
-
 int main()
 {
     using namespace std; // printf, clock_t, clock
 
- printf("%s: %d threads, %d iterations: ", title, m, n);
+ printf( "Using %s threads: %d threads, %d iterations: ", thmodel, m, n );
 
- boost::shared_ptr<int> pi(new int(42));
+ boost::shared_ptr<int> pi( new int(42) );
 
     clock_t t = clock();
 
- pthread_t a[m];
+ pthread_t a[ m ];
 
- for(int i = 0; i < m; ++i)
+ for( int i = 0; i < m; ++i )
     {
- a[i] = createThread( boost::bind(test, pi) );
+ boost::detail::lw_thread_create( a[ i ], boost::bind( test, pi ) );
     }
 
- for(int j = 0; j < m; ++j)
+ for( int j = 0; j < m; ++j )
     {
- pthread_join(a[j], 0);
+ pthread_join( a[j], 0 );
     }
 
     t = clock() - t;
 
- printf("\n\n%.3f seconds.\n", static_cast<double>(t) / CLOCKS_PER_SEC);
+ printf( "\n\n%.3f seconds.\n", static_cast<double>(t) / CLOCKS_PER_SEC );
 
     return 0;
 }

Modified: trunk/libs/smart_ptr/test/weak_ptr_mt_test.cpp
==============================================================================
--- trunk/libs/smart_ptr/test/weak_ptr_mt_test.cpp (original)
+++ trunk/libs/smart_ptr/test/weak_ptr_mt_test.cpp 2008-04-20 11:37:08 EDT (Sun, 20 Apr 2008)
@@ -7,128 +7,26 @@
 #pragma warning(disable: 4514) // unreferenced inline removed
 #endif
 
-//
 // weak_ptr_mt_test.cpp
 //
 // Copyright (c) 2002 Peter Dimov and Multi Media Ltd.
-// Copyright 2005 Peter Dimov
-//
-// Distributed under the Boost Software License, Version 1.0. (See
-// accompanying file LICENSE_1_0.txt or copy at
-// http://www.boost.org/LICENSE_1_0.txt)
+// Copyright 2005, 2008 Peter Dimov
 //
+// Distributed under the Boost Software License, Version 1.0.
+// See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt
 
 #include <boost/shared_ptr.hpp>
 #include <boost/weak_ptr.hpp>
 #include <boost/bind.hpp>
 
 #include <vector>
-#include <memory>
-#include <stdexcept>
 
 #include <cstdio>
 #include <ctime>
 #include <cstdlib>
 
-// 'portable' thread framework
-
-class abstract_thread
-{
-public:
-
- virtual ~abstract_thread() {}
- virtual void run() = 0;
-};
-
-#if !defined(BOOST_HAS_PTHREADS) && defined(BOOST_HAS_WINTHREADS)
-
-char const * title = "Using Windows threads";
-
-#include <windows.h>
-#include <process.h>
-
-typedef HANDLE pthread_t;
-
-unsigned __stdcall common_thread_routine(void * pv)
-{
- abstract_thread * pt = static_cast<abstract_thread *>(pv);
- pt->run();
- delete pt;
- return 0;
-}
-
-int pthread_create(pthread_t * thread, void const *, unsigned (__stdcall * start_routine) (void*), void* arg)
-{
- HANDLE h = (HANDLE)_beginthreadex(0, 0, start_routine, arg, 0, 0);
-
- if(h != 0)
- {
- *thread = h;
- return 0;
- }
- else
- {
- return 1; // return errno;
- }
-}
-
-int pthread_join(pthread_t thread, void ** /*value_ptr*/)
-{
- ::WaitForSingleObject(thread, INFINITE);
- ::CloseHandle(thread);
- return 0;
-}
-
-#else
-
-char const * title = "Using POSIX threads";
-
-#include <pthread.h>
-
-extern "C" void * common_thread_routine(void * pv)
-{
- abstract_thread * pt = static_cast<abstract_thread *>(pv);
- pt->run();
- delete pt;
- return 0;
-}
-
-#endif
-
-//
-
-template<class F> class thread: public abstract_thread
-{
-public:
-
- explicit thread(F f): f_(f)
- {
- }
-
- void run()
- {
- f_();
- }
-
-private:
-
- F f_;
-};
-
-template<class F> pthread_t createThread(F f)
-{
- std::auto_ptr<abstract_thread> p(new thread<F>(f));
-
- pthread_t r;
-
- if(pthread_create(&r, 0, common_thread_routine, p.get()) == 0)
- {
- p.release();
- return r;
- }
-
- throw std::runtime_error("createThread failed.");
-}
+#include <boost/detail/lightweight_thread.hpp>
 
 //
 
@@ -177,11 +75,21 @@
     printf( "\n%d locks, %d forced rebinds, %d normal rebinds.", s, f, r );
 }
 
+#if defined( BOOST_HAS_PTHREADS )
+
+char const * thmodel = "POSIX";
+
+#else
+
+char const * thmodel = "Windows";
+
+#endif
+
 int main()
 {
     using namespace std; // printf, clock_t, clock
 
- printf("%s: %d threads, %d * %d iterations: ", title, m, n, k );
+ printf("Using %s threads: %d threads, %d * %d iterations: ", thmodel, m, n, k );
 
     std::vector< boost::shared_ptr<int> > v( k );
 
@@ -192,16 +100,16 @@
 
     clock_t t = clock();
 
- pthread_t a[m];
+ pthread_t a[ m ];
 
- for(int i = 0; i < m; ++i)
+ for( int i = 0; i < m; ++i )
     {
- a[i] = createThread( boost::bind( test, v ) );
+ boost::detail::lw_thread_create( a[ i ], boost::bind( test, v ) );
     }
 
     v.resize( 0 ); // kill original copies
 
- for(int j = 0; j < m; ++j)
+ for( int j = 0; j < m; ++j )
     {
         pthread_join( a[j], 0 );
     }


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk