From e2df781e2c667a91ac85ed1c59b23db21d109e8d Mon Sep 17 00:00:00 2001 From: bangerth Date: Fri, 9 Jan 2009 19:42:07 +0000 Subject: [PATCH] Oops, checked in on the wrong branch. Undo previous commit. git-svn-id: https://svn.dealii.org/trunk@18160 0785d39b-7218-0410-832d-ea1e28bc413d --- deal.II/base/include/base/thread_management.h | 301 +++++++----------- 1 file changed, 122 insertions(+), 179 deletions(-) diff --git a/deal.II/base/include/base/thread_management.h b/deal.II/base/include/base/thread_management.h index 662c061293..f3a2044edf 100644 --- a/deal.II/base/include/base/thread_management.h +++ b/deal.II/base/include/base/thread_management.h @@ -1455,7 +1455,7 @@ namespace Threads boost::shared_ptr > thread_descriptor; #if !defined(DEAL_II_NAMESP_TEMPL_FRIEND_BUG2) && !defined(DEAL_II_NAMESP_TEMPL_FRIEND_BUG) - template friend struct internal::ThreadStarter; + template friend struct internal::fun_wrapper; #endif }; @@ -1475,9 +1475,29 @@ namespace Threads * @author Wolfgang Bangerth, 2003 */ template - struct ThreadStarter + struct fun_wrapper { - public: + /** + * Constructor. Store the + * necessary information + * about the function to be + * called and with which + * arguments. + * + * Pass down the address of + * this class's thread entry + * point function. This way, + * we can ensure that object + * and thread entry point + * function always are in + * synch with respect to + * their knowledge of the + * types involved. + */ + fun_wrapper (const boost::function &function) + : function (function) {} + + /** * Start a new thread, wait * until it has copied the @@ -1488,75 +1508,54 @@ namespace Threads * In the non-multithreaded case, * simply call the function. */ - static - Thread start_thread (const boost::function &function) + Thread fire_up () { - ThreadStarter wrapper (function); - wrapper.thread_descriptor = - boost::shared_ptr > - (new internal::thread_description()); + thread_descriptor = + DescriptionPointer(new internal::thread_description()); #if (DEAL_II_USE_MT == 1) - ThreadMutex::ScopedLock lock (wrapper.mutex); - wrapper.thread_descriptor->create (&ThreadStarter::entry_point, - (void *)&wrapper); - - // wait for the newly created - // thread to indicate that it has - // copied the function - // descriptor. note that the - // POSIX description of - // pthread_cond_wait says that - // the function can return - // spuriously and may have to be - // called again; we guard against - // this using the - // data_has_been_copied variable - // that indicates whether the - // condition has actually been - // met - do - { - wrapper.condition.wait (wrapper.mutex); - } - while (wrapper.data_has_been_copied == false); + ThreadMutex::ScopedLock lock (mutex); + thread_descriptor->create (&entry_point, (void *)this); + condition.wait (mutex); #else - call (function, wrapper.thread_descriptor->ret_val); + call (function, thread_descriptor->ret_val); #endif - return wrapper.thread_descriptor; + return thread_descriptor; } private: /** - * Constructor. Store the - * necessary information - * about the function to be - * called and with which - * arguments. - * - * Pass down the address of - * this class's thread entry - * point function. This way, - * we can ensure that object - * and thread entry point - * function always are in - * synch with respect to - * their knowledge of the - * types involved. + * Default constructor. Made + * private and not + * implemented to prevent + * calling. */ - ThreadStarter (const boost::function &function) - : - function (function), - data_has_been_copied (false) - {} + fun_wrapper (); + + /** + * Copy constructor. Made + * private and not + * implemented to prevent + * calling. + */ + fun_wrapper (const fun_wrapper &); + + /** + * Typedef for shared + * pointers to the objects + * describing threads on the + * OS level. + */ + typedef + boost::shared_ptr > + DescriptionPointer; /** * Shared pointer to the * unique object describing a * thread on the OS level. */ - boost::shared_ptr > - thread_descriptor; + DescriptionPointer thread_descriptor; /** * Mutex and condition @@ -1579,22 +1578,14 @@ namespace Threads */ const boost::function &function; - /** - * A variable that indicates whether - * the called thread has copied the - * function descriptor to its own - * stack. - */ - mutable bool data_has_been_copied; - /** * Entry point for the new * thread. */ static void * entry_point (void *arg) { - const ThreadStarter *wrapper - = reinterpret_cast*> (arg); + const fun_wrapper *wrapper + = reinterpret_cast*> (arg); // copy information from // the stack of the @@ -1608,50 +1599,11 @@ namespace Threads // we have copied all the // information that is // needed - // - // note that we indicate success - // of the operation not only - // through the condition variable - // but also through - // data_has_been_copied because - // pthread_cond_wait can return - // spuriously and we need to - // check there whether the return - // is spurious or not { - wrapper->data_has_been_copied = true; ThreadMutex::ScopedLock lock (wrapper->mutex); wrapper->condition.signal (); } - // create a new scheduler object - // so that we can start tasks on - // the new thread. the scheduler - // will go out of scope at the - // end of the function, which - // also coincides with the end of - // the thread - // - // one may think that the - // creation of a scheduler is - // expensive, but just creating - // one and then destroying it - // again costs about 92 - // nanoseconds on my laptop - // (early 2009), whereas thread - // creation takes about 12000 - // nanoseconds, more than 100 - // times longer. there is - // therefore no need to only - // create the scheduler when this - // is actually necessary because - // we are spawning tasks on this - // particular thread; rather, we - // make our life simpler by - // always having a scheduler - // around - tbb::task_scheduler_init scheduler; - // call the // function. since an // exception that is @@ -1681,6 +1633,15 @@ namespace Threads return 0; } + + + /** + * Make the base class a + * friend, so that it can + * access the thread entry + * point function. + */ + template friend class wrapper_base; }; } @@ -1757,7 +1718,7 @@ namespace Threads class fun_encapsulator; -// ----------- encapsulators for function objects +// ----------- encapsulators for member functions not taking any parameters /** * @internal @@ -1780,7 +1741,7 @@ namespace Threads Thread operator() () { - return ThreadStarter::start_thread (function); + return fun_wrapper (function).fire_up (); } private: @@ -1808,10 +1769,8 @@ namespace Threads Thread operator() (typename boost::tuples::element<0,ArgList>::type arg1) { - return - ThreadStarter::start_thread - (boost::bind (function, - internal::maybe_make_boost_ref::type>::act(arg1))); + return fun_wrapper (boost::bind (function, + internal::maybe_make_boost_ref::type>::act(arg1))).fire_up (); } private: @@ -1840,11 +1799,9 @@ namespace Threads operator() (typename boost::tuples::element<0,ArgList>::type arg1, typename boost::tuples::element<1,ArgList>::type arg2) { - return - ThreadStarter::start_thread - (boost::bind (function, - internal::maybe_make_boost_ref::type>::act(arg1), - internal::maybe_make_boost_ref::type>::act(arg2))); + return fun_wrapper (boost::bind (function, + internal::maybe_make_boost_ref::type>::act(arg1), + internal::maybe_make_boost_ref::type>::act(arg2))).fire_up (); } private: @@ -1874,12 +1831,10 @@ namespace Threads typename boost::tuples::element<1,ArgList>::type arg2, typename boost::tuples::element<2,ArgList>::type arg3) { - return - ThreadStarter::start_thread - (boost::bind (function, - internal::maybe_make_boost_ref::type>::act(arg1), - internal::maybe_make_boost_ref::type>::act(arg2), - internal::maybe_make_boost_ref::type>::act(arg3))); + return fun_wrapper (boost::bind (function, + internal::maybe_make_boost_ref::type>::act(arg1), + internal::maybe_make_boost_ref::type>::act(arg2), + internal::maybe_make_boost_ref::type>::act(arg3))).fire_up (); } private: @@ -1910,13 +1865,11 @@ namespace Threads typename boost::tuples::element<2,ArgList>::type arg3, typename boost::tuples::element<3,ArgList>::type arg4) { - return - ThreadStarter::start_thread - (boost::bind (function, - internal::maybe_make_boost_ref::type>::act(arg1), - internal::maybe_make_boost_ref::type>::act(arg2), - internal::maybe_make_boost_ref::type>::act(arg3), - internal::maybe_make_boost_ref::type>::act(arg4))); + return fun_wrapper (boost::bind (function, + internal::maybe_make_boost_ref::type>::act(arg1), + internal::maybe_make_boost_ref::type>::act(arg2), + internal::maybe_make_boost_ref::type>::act(arg3), + internal::maybe_make_boost_ref::type>::act(arg4))).fire_up (); } private: @@ -1948,14 +1901,12 @@ namespace Threads typename boost::tuples::element<3,ArgList>::type arg4, typename boost::tuples::element<4,ArgList>::type arg5) { - return - ThreadStarter::start_thread - (boost::bind (function, - internal::maybe_make_boost_ref::type>::act(arg1), - internal::maybe_make_boost_ref::type>::act(arg2), - internal::maybe_make_boost_ref::type>::act(arg3), - internal::maybe_make_boost_ref::type>::act(arg4), - internal::maybe_make_boost_ref::type>::act(arg5))); + return fun_wrapper (boost::bind (function, + internal::maybe_make_boost_ref::type>::act(arg1), + internal::maybe_make_boost_ref::type>::act(arg2), + internal::maybe_make_boost_ref::type>::act(arg3), + internal::maybe_make_boost_ref::type>::act(arg4), + internal::maybe_make_boost_ref::type>::act(arg5))).fire_up (); } private: @@ -1988,15 +1939,13 @@ namespace Threads typename boost::tuples::element<4,ArgList>::type arg5, typename boost::tuples::element<5,ArgList>::type arg6) { - return - ThreadStarter::start_thread - (boost::bind (function, - internal::maybe_make_boost_ref::type>::act(arg1), - internal::maybe_make_boost_ref::type>::act(arg2), - internal::maybe_make_boost_ref::type>::act(arg3), - internal::maybe_make_boost_ref::type>::act(arg4), - internal::maybe_make_boost_ref::type>::act(arg5), - internal::maybe_make_boost_ref::type>::act(arg6))); + return fun_wrapper (boost::bind (function, + internal::maybe_make_boost_ref::type>::act(arg1), + internal::maybe_make_boost_ref::type>::act(arg2), + internal::maybe_make_boost_ref::type>::act(arg3), + internal::maybe_make_boost_ref::type>::act(arg4), + internal::maybe_make_boost_ref::type>::act(arg5), + internal::maybe_make_boost_ref::type>::act(arg6))).fire_up (); } private: @@ -2030,16 +1979,14 @@ namespace Threads typename boost::tuples::element<5,ArgList>::type arg6, typename boost::tuples::element<6,ArgList>::type arg7) { - return - ThreadStarter::start_thread - (boost::bind (function, - internal::maybe_make_boost_ref::type>::act(arg1), - internal::maybe_make_boost_ref::type>::act(arg2), - internal::maybe_make_boost_ref::type>::act(arg3), - internal::maybe_make_boost_ref::type>::act(arg4), - internal::maybe_make_boost_ref::type>::act(arg5), - internal::maybe_make_boost_ref::type>::act(arg6), - internal::maybe_make_boost_ref::type>::act(arg7))); + return fun_wrapper (boost::bind (function, + internal::maybe_make_boost_ref::type>::act(arg1), + internal::maybe_make_boost_ref::type>::act(arg2), + internal::maybe_make_boost_ref::type>::act(arg3), + internal::maybe_make_boost_ref::type>::act(arg4), + internal::maybe_make_boost_ref::type>::act(arg5), + internal::maybe_make_boost_ref::type>::act(arg6), + internal::maybe_make_boost_ref::type>::act(arg7))).fire_up (); } private: @@ -2074,17 +2021,15 @@ namespace Threads typename boost::tuples::element<6,ArgList>::type arg7, typename boost::tuples::element<7,ArgList>::type arg8) { - return - ThreadStarter::start_thread - (boost::bind (function, - internal::maybe_make_boost_ref::type>::act(arg1), - internal::maybe_make_boost_ref::type>::act(arg2), - internal::maybe_make_boost_ref::type>::act(arg3), - internal::maybe_make_boost_ref::type>::act(arg4), - internal::maybe_make_boost_ref::type>::act(arg5), - internal::maybe_make_boost_ref::type>::act(arg6), - internal::maybe_make_boost_ref::type>::act(arg7), - internal::maybe_make_boost_ref::type>::act(arg8))); + return fun_wrapper (boost::bind (function, + internal::maybe_make_boost_ref::type>::act(arg1), + internal::maybe_make_boost_ref::type>::act(arg2), + internal::maybe_make_boost_ref::type>::act(arg3), + internal::maybe_make_boost_ref::type>::act(arg4), + internal::maybe_make_boost_ref::type>::act(arg5), + internal::maybe_make_boost_ref::type>::act(arg6), + internal::maybe_make_boost_ref::type>::act(arg7), + internal::maybe_make_boost_ref::type>::act(arg8))).fire_up (); } private: @@ -2120,18 +2065,16 @@ namespace Threads typename boost::tuples::element<7,ArgList>::type arg8, typename boost::tuples::element<8,ArgList>::type arg9) { - return - ThreadStarter::start_thread - (boost::bind (function, - internal::maybe_make_boost_ref::type>::act(arg1), - internal::maybe_make_boost_ref::type>::act(arg2), - internal::maybe_make_boost_ref::type>::act(arg3), - internal::maybe_make_boost_ref::type>::act(arg4), - internal::maybe_make_boost_ref::type>::act(arg5), - internal::maybe_make_boost_ref::type>::act(arg6), - internal::maybe_make_boost_ref::type>::act(arg7), - internal::maybe_make_boost_ref::type>::act(arg8), - internal::maybe_make_boost_ref::type>::act(arg9))); + return fun_wrapper (boost::bind (function, + internal::maybe_make_boost_ref::type>::act(arg1), + internal::maybe_make_boost_ref::type>::act(arg2), + internal::maybe_make_boost_ref::type>::act(arg3), + internal::maybe_make_boost_ref::type>::act(arg4), + internal::maybe_make_boost_ref::type>::act(arg5), + internal::maybe_make_boost_ref::type>::act(arg6), + internal::maybe_make_boost_ref::type>::act(arg7), + internal::maybe_make_boost_ref::type>::act(arg8), + internal::maybe_make_boost_ref::type>::act(arg9))).fire_up (); } private: -- 2.39.5