]> https://gitweb.dealii.org/ - dealii-svn.git/commitdiff
Use boost threads instead of doing everything ourselves by hand calling POSIX and...
authorbangerth <bangerth@0785d39b-7218-0410-832d-ea1e28bc413d>
Wed, 14 Jan 2009 14:29:46 +0000 (14:29 +0000)
committerbangerth <bangerth@0785d39b-7218-0410-832d-ea1e28bc413d>
Wed, 14 Jan 2009 14:29:46 +0000 (14:29 +0000)
git-svn-id: https://svn.dealii.org/trunk@18218 0785d39b-7218-0410-832d-ea1e28bc413d

125 files changed:
deal.II/base/include/base/std_cxx0x/thread.h [new file with mode: 0644]
deal.II/base/include/base/thread_management.h
deal.II/base/source/boost_threads.cc [new file with mode: 0644]
deal.II/base/source/thread_management.cc
deal.II/contrib/boost/include/boost/thread/barrier.hpp [new file with mode: 0644]
deal.II/contrib/boost/include/boost/thread/condition.hpp [new file with mode: 0644]
deal.II/contrib/boost/include/boost/thread/condition_variable.hpp [new file with mode: 0644]
deal.II/contrib/boost/include/boost/thread/detail/config.hpp [new file with mode: 0644]
deal.II/contrib/boost/include/boost/thread/detail/force_cast.hpp [new file with mode: 0644]
deal.II/contrib/boost/include/boost/thread/detail/move.hpp [new file with mode: 0644]
deal.II/contrib/boost/include/boost/thread/detail/platform.hpp [new file with mode: 0644]
deal.II/contrib/boost/include/boost/thread/detail/singleton.hpp [new file with mode: 0644]
deal.II/contrib/boost/include/boost/thread/detail/thread.hpp [new file with mode: 0644]
deal.II/contrib/boost/include/boost/thread/detail/thread_heap_alloc.hpp [new file with mode: 0644]
deal.II/contrib/boost/include/boost/thread/detail/tss_hooks.hpp [new file with mode: 0644]
deal.II/contrib/boost/include/boost/thread/exceptions.hpp [new file with mode: 0644]
deal.II/contrib/boost/include/boost/thread/locks.hpp [new file with mode: 0644]
deal.II/contrib/boost/include/boost/thread/mutex.hpp [new file with mode: 0644]
deal.II/contrib/boost/include/boost/thread/once.hpp [new file with mode: 0644]
deal.II/contrib/boost/include/boost/thread/pthread/condition_variable.hpp [new file with mode: 0644]
deal.II/contrib/boost/include/boost/thread/pthread/condition_variable_fwd.hpp [new file with mode: 0644]
deal.II/contrib/boost/include/boost/thread/pthread/mutex.hpp [new file with mode: 0644]
deal.II/contrib/boost/include/boost/thread/pthread/once.hpp [new file with mode: 0644]
deal.II/contrib/boost/include/boost/thread/pthread/pthread_mutex_scoped_lock.hpp [new file with mode: 0644]
deal.II/contrib/boost/include/boost/thread/pthread/recursive_mutex.hpp [new file with mode: 0644]
deal.II/contrib/boost/include/boost/thread/pthread/shared_mutex.hpp [new file with mode: 0644]
deal.II/contrib/boost/include/boost/thread/pthread/thread_data.hpp [new file with mode: 0644]
deal.II/contrib/boost/include/boost/thread/pthread/thread_heap_alloc.hpp [new file with mode: 0644]
deal.II/contrib/boost/include/boost/thread/pthread/timespec.hpp [new file with mode: 0644]
deal.II/contrib/boost/include/boost/thread/recursive_mutex.hpp [new file with mode: 0644]
deal.II/contrib/boost/include/boost/thread/shared_mutex.hpp [new file with mode: 0644]
deal.II/contrib/boost/include/boost/thread/thread.hpp [new file with mode: 0644]
deal.II/contrib/boost/include/boost/thread/thread_time.hpp [new file with mode: 0644]
deal.II/contrib/boost/include/boost/thread/tss.hpp [new file with mode: 0644]
deal.II/contrib/boost/include/boost/thread/win32/basic_recursive_mutex.hpp [new file with mode: 0644]
deal.II/contrib/boost/include/boost/thread/win32/basic_timed_mutex.hpp [new file with mode: 0644]
deal.II/contrib/boost/include/boost/thread/win32/condition_variable.hpp [new file with mode: 0644]
deal.II/contrib/boost/include/boost/thread/win32/interlocked_read.hpp [new file with mode: 0644]
deal.II/contrib/boost/include/boost/thread/win32/mutex.hpp [new file with mode: 0644]
deal.II/contrib/boost/include/boost/thread/win32/once.hpp [new file with mode: 0644]
deal.II/contrib/boost/include/boost/thread/win32/recursive_mutex.hpp [new file with mode: 0644]
deal.II/contrib/boost/include/boost/thread/win32/shared_mutex.hpp [new file with mode: 0644]
deal.II/contrib/boost/include/boost/thread/win32/thread_data.hpp [new file with mode: 0644]
deal.II/contrib/boost/include/boost/thread/win32/thread_heap_alloc.hpp [new file with mode: 0644]
deal.II/contrib/boost/include/boost/thread/win32/thread_primitives.hpp [new file with mode: 0644]
deal.II/contrib/boost/include/boost/thread/xtime.hpp [new file with mode: 0644]
deal.II/contrib/boost/libs/thread/build/Jamfile.v2 [new file with mode: 0644]
deal.II/contrib/boost/libs/thread/doc/Jamfile.v2 [new file with mode: 0644]
deal.II/contrib/boost/libs/thread/doc/acknowledgements.qbk [new file with mode: 0644]
deal.II/contrib/boost/libs/thread/doc/barrier.qbk [new file with mode: 0644]
deal.II/contrib/boost/libs/thread/doc/changes.qbk [new file with mode: 0644]
deal.II/contrib/boost/libs/thread/doc/condition_variables.qbk [new file with mode: 0644]
deal.II/contrib/boost/libs/thread/doc/index.html [new file with mode: 0644]
deal.II/contrib/boost/libs/thread/doc/mutex_concepts.qbk [new file with mode: 0644]
deal.II/contrib/boost/libs/thread/doc/mutexes.qbk [new file with mode: 0644]
deal.II/contrib/boost/libs/thread/doc/once.qbk [new file with mode: 0644]
deal.II/contrib/boost/libs/thread/doc/overview.qbk [new file with mode: 0644]
deal.II/contrib/boost/libs/thread/doc/shared_mutex_ref.qbk [new file with mode: 0644]
deal.II/contrib/boost/libs/thread/doc/thread.qbk [new file with mode: 0644]
deal.II/contrib/boost/libs/thread/doc/thread_ref.qbk [new file with mode: 0644]
deal.II/contrib/boost/libs/thread/doc/time.qbk [new file with mode: 0644]
deal.II/contrib/boost/libs/thread/doc/tss.qbk [new file with mode: 0644]
deal.II/contrib/boost/libs/thread/example/Jamfile.v2 [new file with mode: 0644]
deal.II/contrib/boost/libs/thread/example/condition.cpp [new file with mode: 0644]
deal.II/contrib/boost/libs/thread/example/monitor.cpp [new file with mode: 0644]
deal.II/contrib/boost/libs/thread/example/mutex.cpp [new file with mode: 0644]
deal.II/contrib/boost/libs/thread/example/once.cpp [new file with mode: 0644]
deal.II/contrib/boost/libs/thread/example/recursive_mutex.cpp [new file with mode: 0644]
deal.II/contrib/boost/libs/thread/example/starvephil.cpp [new file with mode: 0644]
deal.II/contrib/boost/libs/thread/example/tennis.cpp [new file with mode: 0644]
deal.II/contrib/boost/libs/thread/example/thread.cpp [new file with mode: 0644]
deal.II/contrib/boost/libs/thread/example/thread_group.cpp [new file with mode: 0644]
deal.II/contrib/boost/libs/thread/example/tss.cpp [new file with mode: 0644]
deal.II/contrib/boost/libs/thread/example/xtime.cpp [new file with mode: 0644]
deal.II/contrib/boost/libs/thread/index.html [new file with mode: 0644]
deal.II/contrib/boost/libs/thread/src/pthread/exceptions.cpp [new file with mode: 0644]
deal.II/contrib/boost/libs/thread/src/pthread/once.cpp [new file with mode: 0644]
deal.II/contrib/boost/libs/thread/src/pthread/thread.cpp [new file with mode: 0644]
deal.II/contrib/boost/libs/thread/src/pthread/timeconv.inl [new file with mode: 0644]
deal.II/contrib/boost/libs/thread/src/tss_null.cpp [new file with mode: 0644]
deal.II/contrib/boost/libs/thread/src/win32/exceptions.cpp [new file with mode: 0644]
deal.II/contrib/boost/libs/thread/src/win32/thread.cpp [new file with mode: 0644]
deal.II/contrib/boost/libs/thread/src/win32/timeconv.inl [new file with mode: 0644]
deal.II/contrib/boost/libs/thread/src/win32/tss_dll.cpp [new file with mode: 0644]
deal.II/contrib/boost/libs/thread/src/win32/tss_pe.cpp [new file with mode: 0644]
deal.II/contrib/boost/libs/thread/test/Carbon.r [new file with mode: 0644]
deal.II/contrib/boost/libs/thread/test/Jamfile.v2 [new file with mode: 0644]
deal.II/contrib/boost/libs/thread/test/condition_test_common.hpp [new file with mode: 0644]
deal.II/contrib/boost/libs/thread/test/no_implicit_assign_from_lvalue_thread.cpp [new file with mode: 0644]
deal.II/contrib/boost/libs/thread/test/no_implicit_move_from_lvalue_thread.cpp [new file with mode: 0644]
deal.II/contrib/boost/libs/thread/test/shared_mutex_locking_thread.hpp [new file with mode: 0644]
deal.II/contrib/boost/libs/thread/test/test.mcp [new file with mode: 0644]
deal.II/contrib/boost/libs/thread/test/test_barrier.cpp [new file with mode: 0644]
deal.II/contrib/boost/libs/thread/test/test_condition.cpp [new file with mode: 0644]
deal.II/contrib/boost/libs/thread/test/test_condition_notify_all.cpp [new file with mode: 0644]
deal.II/contrib/boost/libs/thread/test/test_condition_notify_one.cpp [new file with mode: 0644]
deal.II/contrib/boost/libs/thread/test/test_condition_timed_wait_times_out.cpp [new file with mode: 0644]
deal.II/contrib/boost/libs/thread/test/test_generic_locks.cpp [new file with mode: 0644]
deal.II/contrib/boost/libs/thread/test/test_hardware_concurrency.cpp [new file with mode: 0644]
deal.II/contrib/boost/libs/thread/test/test_lock_concept.cpp [new file with mode: 0644]
deal.II/contrib/boost/libs/thread/test/test_move_function.cpp [new file with mode: 0644]
deal.II/contrib/boost/libs/thread/test/test_mutex.cpp [new file with mode: 0644]
deal.II/contrib/boost/libs/thread/test/test_once.cpp [new file with mode: 0644]
deal.II/contrib/boost/libs/thread/test/test_shared_mutex.cpp [new file with mode: 0644]
deal.II/contrib/boost/libs/thread/test/test_shared_mutex_part_2.cpp [new file with mode: 0644]
deal.II/contrib/boost/libs/thread/test/test_shared_mutex_timed_locks.cpp [new file with mode: 0644]
deal.II/contrib/boost/libs/thread/test/test_thread.cpp [new file with mode: 0644]
deal.II/contrib/boost/libs/thread/test/test_thread_id.cpp [new file with mode: 0644]
deal.II/contrib/boost/libs/thread/test/test_thread_launching.cpp [new file with mode: 0644]
deal.II/contrib/boost/libs/thread/test/test_thread_mf.cpp [new file with mode: 0644]
deal.II/contrib/boost/libs/thread/test/test_thread_move.cpp [new file with mode: 0644]
deal.II/contrib/boost/libs/thread/test/test_tss.cpp [new file with mode: 0644]
deal.II/contrib/boost/libs/thread/test/test_xtime.cpp [new file with mode: 0644]
deal.II/contrib/boost/libs/thread/test/util.inl [new file with mode: 0644]
deal.II/contrib/boost/libs/thread/tutorial/bounded_buffer.cpp [new file with mode: 0644]
deal.II/contrib/boost/libs/thread/tutorial/counter.cpp [new file with mode: 0644]
deal.II/contrib/boost/libs/thread/tutorial/factorial.cpp [new file with mode: 0644]
deal.II/contrib/boost/libs/thread/tutorial/factorial2.cpp [new file with mode: 0644]
deal.II/contrib/boost/libs/thread/tutorial/factorial3.cpp [new file with mode: 0644]
deal.II/contrib/boost/libs/thread/tutorial/helloworld.cpp [new file with mode: 0644]
deal.II/contrib/boost/libs/thread/tutorial/helloworld2.cpp [new file with mode: 0644]
deal.II/contrib/boost/libs/thread/tutorial/helloworld3.cpp [new file with mode: 0644]
deal.II/contrib/boost/libs/thread/tutorial/helloworld4.cpp [new file with mode: 0644]
deal.II/contrib/boost/libs/thread/tutorial/once.cpp [new file with mode: 0644]
deal.II/contrib/boost/libs/thread/tutorial/tss.cpp [new file with mode: 0644]

diff --git a/deal.II/base/include/base/std_cxx0x/thread.h b/deal.II/base/include/base/std_cxx0x/thread.h
new file mode 100644 (file)
index 0000000..48328e8
--- /dev/null
@@ -0,0 +1,36 @@
+//---------------------------------------------------------------------------
+//    $Id: std_cxx0x_tuple.h 16094 2008-05-14 19:18:25Z bangerth $
+//    Version: $Name$
+//
+//    Copyright (C) 2009 by the deal.II authors
+//
+//    This file is subject to QPL and may not be  distributed
+//    without copyright and license information. Please refer
+//    to the file deal.II/doc/license.html for the  text  and
+//    further information on this license.
+//
+//---------------------------------------------------------------------------
+#ifndef __deal2__std_cxx0x_thread_h
+#define __deal2__std_cxx0x_thread_h
+
+
+#include <base/config.h>
+
+#ifdef DEAL_II_CAN_USE_CXX0X
+
+#  include <thread>
+
+#else
+
+#  include <boost/thread.hpp>
+
+DEAL_II_NAMESPACE_OPEN
+namespace std_cxx0x
+{
+  using boost::thread;
+}
+DEAL_II_NAMESPACE_CLOSE
+
+#endif
+
+#endif
index 0a912d50e1b63672d80c6983ae28b2726a7d55f6..2c0ddb3249fd4a4a3a18bebd92437552ca864fe3 100644 (file)
 #include <base/std_cxx0x/shared_ptr.h>
 #include <base/std_cxx0x/bind.h>
 
+#if (DEAL_II_USE_MT == 1)
+#  include <base/std_cxx0x/thread.h>
+#endif
+
 #include <iterator>
 #include <vector>
 #include <list>
@@ -1187,143 +1191,111 @@ namespace Threads
   namespace internal 
   {
 #if (DEAL_II_USE_MT == 1)
-#  if defined(DEAL_II_USE_MT_POSIX)
 
-                                     /**
-                                     * @internal
-                                      * Base class describing a
-                                      * thread. This is the basic
-                                      * class abstracting the
-                                      * operating system's POSIX
-                                      * implementation into a C++
-                                      * class. It provides a mechanism
-                                      * to start a new thread, as well
-                                      * as for joining it.
-                                      *
-                                      * @author Wolfgang Bangerth, 2003
-                                      */
-    struct thread_description_base
+                                    /**
+                                     * A class that represents threads. For
+                                     * each thread, we create exactly one of
+                                     * these objects -- exactly one because
+                                     * it carries the returned value of the
+                                     * function called on the thread.
+                                     *
+                                     * While we have only one of these
+                                     * objects per thread, several
+                                     * Threads::Thread objects may refer to
+                                     * this descriptor.
+                                     */
+    template <typename RT>
+    struct ThreadDescriptor 
     {
-      private:
-                                         /**
-                                          * Variable holding the data
-                                          * the operating system needs
-                                          * to work with a thread.
-                                          */
-        pthread_t             thread;
-
-                                         /**
-                                          * Store whether the
-                                          * <tt>join()</tt> member function
-                                          * as already been called. If
-                                          * <tt>true</tt>, then <tt>join</tt>
-                                          * will return immediately,
-                                          * otherwise it needs to go
-                                          * through a call to the
-                                          * operating system.
-                                          *
-                                          * This class is generated
-                                          * exactly once per thread,
-                                          * but is kept in the
-                                          * background: user's should
-                                          * not directly access this
-                                          * class. Access to it is
-                                          * performed through counted
-                                          * pointers, both from
-                                          * <tt>Thread<></tt> objects as
-                                          * well as from the thread
-                                          * entry point function on
-                                          * the new thread. It is only
-                                          * deleted when all users
-                                          * have freed it, which means
-                                          * that also the new thread
-                                          * has ended.
-                                          */
-        mutable volatile bool was_joined;
-
-                                         /**
-                                          * Mutex used to synchronise
-                                          * calls to the <tt>join()</tt>
-                                          * function.
-                                          */
-        mutable ThreadMutex   join_mutex;
-
-      public:
+                                        /**
+                                         * An object that represents the
+                                         * thread started.
+                                         */
+       std_cxx0x::thread thread;
 
-                                         /**
-                                          * Constructor.
-                                          */
-        thread_description_base ();
-
-                                         /**
-                                          * Destructor.
-                                          */
-        virtual ~thread_description_base ();
-
-                                         /**
-                                          * Create a new thread with
-                                          * the given thread entry
-                                          * point and arguments. Store
-                                          * the result of the
-                                          * operation in the
-                                          * <tt>thread</tt> member variable
-                                          * for further use.
-                                          */
-        void create (void * (*p) (void *), void *d);
-
-                                         /**
-                                          * Join a thread, i.e. wait
-                                          * for it to finish. This
-                                          * function can safely be
-                                          * called from different
-                                          * threads at the same time,
-                                          * and can also be called
-                                          * more than once.
-                                          */
-        void join () const;
+                                        /**
+                                         * An object that will hold the value
+                                         * returned by the function called on
+                                         * the thread.
+                                         */
+        return_value<RT> ret_val;
 
                                         /**
-                                         * Exception
+                                         * Constructor. Start the thread and
+                                         * let it put its return value into
+                                         * the ret_val object.
                                          */
-       DeclException1 (ExcThreadCreationError,
-                       int,
-                       << "pthread_create return code is " << arg1);
-    };
+       ThreadDescriptor (const std_cxx0x::function<RT ()> &function)
+                       :
+                       thread (thread_entry_point, function, &ret_val)
+         {}
 
-#  else       // some other threading model
-#    error Not Implemented
-#  endif     // defined(DEAL_II_USE_MT_POSIX)
 
-#else        // no threading enabled
+                                        /**
+                                         * Wait for the thread to end.
+                                         */
+       void join ()
+         {
+           thread.join ();
+         }
+       
+      private:
 
-    struct thread_description_base
-    {
-       static void join () {}
+                                        /**
+                                         * The function that runs on the
+                                         * thread.
+                                         */
+       static
+       void thread_entry_point (const std_cxx0x::function<RT ()> function,
+                                return_value<RT> *ret_val)
+         {
+           call (function, *ret_val);
+         }
     };
-    
-#endif
 
-                                     /**
-                                     * @internal
-                                      * Class derived from
-                                      * thread_description_base()
-                                      * that also provides the
-                                      * possibility to store a return
-                                      * value.
-                                      *
-                                      * @author Wolfgang Bangerth, 2003
-                                      */
+#else
+                                    /**
+                                     * A class that represents threads. For
+                                     * each thread, we create exactly one of
+                                     * these objects -- exactly one because
+                                     * it carries the returned value of the
+                                     * function called on the thread.
+                                     *
+                                     * While we have only one of these
+                                     * objects per thread, several
+                                     * Threads::Thread objects may refer to
+                                     * this descriptor.
+                                     */
     template <typename RT>
-    struct thread_description : public thread_description_base
+    struct ThreadDescriptor 
     {
+                                        /**
+                                         * An object that will hold the value
+                                         * returned by the function called on
+                                         * the thread.
+                                         */
         return_value<RT> ret_val;
-    };
-    
-                                     // forward declare another class
-    template <typename> struct ThreadStarter;
-  }
 
+                                        /**
+                                         * Constructor. Start the thread and
+                                         * let it put its return value into
+                                         * the ret_val object.
+                                         */
+       ThreadDescriptor (const std_cxx0x::function<RT ()> &function)
+         {
+           call (function, ret_val);
+         }
 
+                                        /**
+                                         * Wait for the thread to end.
+                                         */
+       void join ()
+         {}
+    };
+  
+#endif
+  }
+  
 
                                    /**
                                     * User visible class describing a
@@ -1342,39 +1314,22 @@ namespace Threads
                                     * return value, you can omit the
                                     * template argument.
                                     * 
-                                    * @author Wolfgang Bangerth, 2003
+                                    * @author Wolfgang Bangerth, 2003, 2009
+                                   * @ingroup threads
                                     */
   template <typename RT = void>
   class Thread
   {
+    public:
                                        /**
                                         * Construct a thread object
-                                        * with a pointer to an
-                                        * internal thread object. This
-                                        * is the constructor used to
-                                        * the <tt>spawn</tt> family of
-                                        * functions.
-                                        *
-                                        * We would like to make this
-                                        * constructor private and only
-                                        * grant the
-                                        * <tt>fun_wrapper::fire_up</tt>
-                                        * function friendship, but
-                                        * granting friendship to
-                                        * functions in other
-                                        * namespaces doesn't work with
-                                        * some compilers, so only do
-                                        * so if the configure script
-                                        * decided that this is safe.
+                                        * with a function object.
                                         */
-#if defined(DEAL_II_NAMESP_TEMPL_FRIEND_BUG2) || defined(DEAL_II_NAMESP_TEMPL_FRIEND_BUG)
-    public:
-#endif
-      Thread (const std_cxx0x::shared_ptr<internal::thread_description<RT> > &td)
-                      : thread_descriptor (td) {}
+      Thread (const std_cxx0x::function<RT ()> &function)
+                     :
+                     thread_descriptor (new internal::ThreadDescriptor<RT>(function))
+       {}
 
-    public:
-      
                                        /**
                                         * Default constructor. You
                                         * can't do much with a thread
@@ -1382,7 +1337,7 @@ namespace Threads
                                         * except for assigning it a
                                         * thread object that holds
                                         * data created by the
-                                        * <tt>spawn</tt> functions.
+                                        * <tt>new_thread</tt> functions.
                                         */
       Thread () {}
 
@@ -1451,210 +1406,10 @@ namespace Threads
                                         * as long as there is at least
                                         * one subscriber to it.
                                         */
-      std_cxx0x::shared_ptr<internal::thread_description<RT> > thread_descriptor;
-
-#if !defined(DEAL_II_NAMESP_TEMPL_FRIEND_BUG2) && !defined(DEAL_II_NAMESP_TEMPL_FRIEND_BUG)
-      template <typename> friend struct internal::ThreadStarter;
-#endif
+      std_cxx0x::shared_ptr<internal::ThreadDescriptor<RT> > thread_descriptor;
   };
 
-
-
-  namespace internal
-  {
-                                     /**
-                                     * @internal
-                                      * Wrap the arguments to a
-                                      * non-member or static member
-                                      * function and provide an entry
-                                      * point for a new thread that
-                                      * unwraps this data and calls
-                                      * the function with them.
-                                      *
-                                      * @author Wolfgang Bangerth, 2003
-                                      */
-    template <typename RT>
-    struct ThreadStarter
-    {
-      public:
-                                         /**
-                                          * Start a new thread, wait
-                                          * until it has copied the
-                                          * data out of this object,
-                                          * and return the thread
-                                          * descriptor.
-                                         *
-                                         * In the non-multithreaded case,
-                                         * simply call the function.
-                                          */
-       static
-       Thread<RT> start_thread (const std_cxx0x::function<RT ()> &function)
-         {
-           ThreadStarter<RT> wrapper (function);
-           wrapper.thread_descriptor =
-             std_cxx0x::shared_ptr<internal::thread_description<RT> >
-             (new internal::thread_description<RT>());
-           
-#if (DEAL_II_USE_MT == 1)
-           ThreadMutex::ScopedLock lock (wrapper.mutex);
-           wrapper.thread_descriptor->create (&ThreadStarter<RT>::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);
-#else
-           call (function, wrapper.thread_descriptor->ret_val);
-#endif
-           return wrapper.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.
-                                          */
-        ThreadStarter (const std_cxx0x::function<RT ()> &function)
-                        :
-                       function (function),
-                       data_has_been_copied (false)
-         {}
-
-                                         /**
-                                          * Shared pointer to the
-                                          * unique object describing a
-                                          * thread on the OS level.
-                                          */
-        std_cxx0x::shared_ptr<internal::thread_description<RT> >
-       thread_descriptor;
-
-                                         /**
-                                          * Mutex and condition
-                                          * variable used to
-                                          * synchronise calling and
-                                          * called thread.
-                                          */
-        mutable ThreadMutex     mutex;    
-        mutable ThreadCondition condition;
-
-                                         /**
-                                          * Pointer to the function to
-                                          * be called on the new
-                                          * thread.
-                                         *
-                                         * Note that it is enough to store a
-                                         * reference to the function object
-                                         * because of the way the creation of
-                                         * threads is staged.
-                                          */
-       const std_cxx0x::function<RT ()> &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<RT> *wrapper
-              = reinterpret_cast<const ThreadStarter<RT>*> (arg);
-
-                                             // copy information from
-                                             // the stack of the
-                                             // calling thread
-            std_cxx0x::function<RT ()> function = wrapper->function;
-
-            std_cxx0x::shared_ptr<internal::thread_description<RT> >
-              thread_descriptor  = wrapper->thread_descriptor;
-          
-                                             // signal the fact that
-                                             // 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 ();
-            }
-
-                                             // call the
-                                             // function. since an
-                                             // exception that is
-                                             // thrown from one of the
-                                             // called functions will
-                                             // not propagate to the
-                                             // main thread, it will
-                                             // kill the program if
-                                             // not treated here
-                                             // before we return to
-                                             // the operating system's
-                                             // thread library
-            internal::register_thread ();
-            try 
-              {
-                internal::call (function, thread_descriptor->ret_val);
-              }
-            catch (const std::exception &exc)
-              {
-                internal::handle_std_exception (exc);
-              }
-            catch (...)
-              {
-                internal::handle_unknown_exception ();
-              }
-            internal::deregister_thread ();
-          
-            return 0;
-          }
-    };  
-  }
-
+  
   namespace internal
   {
                                     /**
@@ -1751,7 +1506,7 @@ namespace Threads
         Thread<RT>
         operator() ()
          {
-           return ThreadStarter<RT>::start_thread (function);
+           return Thread<RT> (function);
          }
     
       private:
@@ -1780,7 +1535,7 @@ namespace Threads
         operator() (typename std_cxx0x::tuple_element<0,ArgList>::type arg1)
          {
            return
-             ThreadStarter<RT>::start_thread
+             Thread<RT>
              (std_cxx0x::bind (function,
                            internal::maybe_make_ref<typename std_cxx0x::tuple_element<0,ArgList>::type>::act(arg1)));
          }
@@ -1812,7 +1567,7 @@ namespace Threads
                    typename std_cxx0x::tuple_element<1,ArgList>::type arg2)
          {
            return
-             ThreadStarter<RT>::start_thread
+             Thread<RT>
              (std_cxx0x::bind (function,
                            internal::maybe_make_ref<typename std_cxx0x::tuple_element<0,ArgList>::type>::act(arg1),
                            internal::maybe_make_ref<typename std_cxx0x::tuple_element<1,ArgList>::type>::act(arg2)));
@@ -1846,7 +1601,7 @@ namespace Threads
                    typename std_cxx0x::tuple_element<2,ArgList>::type arg3)
          {
            return
-             ThreadStarter<RT>::start_thread
+             Thread<RT>
              (std_cxx0x::bind (function,
                            internal::maybe_make_ref<typename std_cxx0x::tuple_element<0,ArgList>::type>::act(arg1),
                            internal::maybe_make_ref<typename std_cxx0x::tuple_element<1,ArgList>::type>::act(arg2),
@@ -1882,7 +1637,7 @@ namespace Threads
                    typename std_cxx0x::tuple_element<3,ArgList>::type arg4)
          {
            return
-             ThreadStarter<RT>::start_thread
+             Thread<RT>
              (std_cxx0x::bind (function,
                            internal::maybe_make_ref<typename std_cxx0x::tuple_element<0,ArgList>::type>::act(arg1),
                            internal::maybe_make_ref<typename std_cxx0x::tuple_element<1,ArgList>::type>::act(arg2),
@@ -1920,7 +1675,7 @@ namespace Threads
                    typename std_cxx0x::tuple_element<4,ArgList>::type arg5)
          {
            return
-             ThreadStarter<RT>::start_thread
+             Thread<RT>
              (std_cxx0x::bind (function,
                            internal::maybe_make_ref<typename std_cxx0x::tuple_element<0,ArgList>::type>::act(arg1),
                            internal::maybe_make_ref<typename std_cxx0x::tuple_element<1,ArgList>::type>::act(arg2),
@@ -1960,7 +1715,7 @@ namespace Threads
                    typename std_cxx0x::tuple_element<5,ArgList>::type arg6)
          {
            return
-             ThreadStarter<RT>::start_thread
+             Thread<RT>
              (std_cxx0x::bind (function,
                            internal::maybe_make_ref<typename std_cxx0x::tuple_element<0,ArgList>::type>::act(arg1),
                            internal::maybe_make_ref<typename std_cxx0x::tuple_element<1,ArgList>::type>::act(arg2),
@@ -2002,7 +1757,7 @@ namespace Threads
                    typename std_cxx0x::tuple_element<6,ArgList>::type arg7)
          {
            return
-             ThreadStarter<RT>::start_thread
+             Thread<RT>
              (std_cxx0x::bind (function,
                            internal::maybe_make_ref<typename std_cxx0x::tuple_element<0,ArgList>::type>::act(arg1),
                            internal::maybe_make_ref<typename std_cxx0x::tuple_element<1,ArgList>::type>::act(arg2),
@@ -2046,7 +1801,7 @@ namespace Threads
                    typename std_cxx0x::tuple_element<7,ArgList>::type arg8)
          {
            return
-             ThreadStarter<RT>::start_thread
+             Thread<RT>
              (std_cxx0x::bind (function,
                            internal::maybe_make_ref<typename std_cxx0x::tuple_element<0,ArgList>::type>::act(arg1),
                            internal::maybe_make_ref<typename std_cxx0x::tuple_element<1,ArgList>::type>::act(arg2),
@@ -2092,7 +1847,7 @@ namespace Threads
                    typename std_cxx0x::tuple_element<8,ArgList>::type arg9)
          {
            return
-             ThreadStarter<RT>::start_thread
+             Thread<RT>
              (std_cxx0x::bind (function,
                            internal::maybe_make_ref<typename std_cxx0x::tuple_element<0,ArgList>::type>::act(arg1),
                            internal::maybe_make_ref<typename std_cxx0x::tuple_element<1,ArgList>::type>::act(arg2),
diff --git a/deal.II/base/source/boost_threads.cc b/deal.II/base/source/boost_threads.cc
new file mode 100644 (file)
index 0000000..6632f20
--- /dev/null
@@ -0,0 +1,24 @@
+//---------------------------------------------------------------------------
+//    $Id: thread_management.cc 18205 2009-01-13 13:53:08Z bangerth $
+//    Version: $Name$
+//
+//    Copyright (C) 2009 by the deal.II authors
+//
+//    This file is subject to QPL and may not be  distributed
+//    without copyright and license information. Please refer
+//    to the file deal.II/doc/license.html for the  text  and
+//    further information on this license.
+//
+//---------------------------------------------------------------------------
+
+
+// include all the files that form BOOST's thread implementation so that we
+// don't have to build BOOST itself only to get at this small part of it. it
+// also ensures that we use the correct compiler and flags
+
+#define BOOST_THREAD_POSIX
+#define BOOST_THREAD_BUILD_LIB 1
+
+#include <../libs/thread/src/pthread/once.cpp>
+#include <../libs/thread/src/pthread/exceptions.cpp>
+#include <../libs/thread/src/pthread/thread.cpp>
index ae6af3c6dc4ffadd30c4cba61a2e689f0ef5a349..8166a37d664651edee4ce14f80b6b566743a779d 100644 (file)
@@ -275,169 +275,7 @@ namespace Threads
          return_values[i].second = end;
       };
     return return_values;
-  } 
-
-
-#if (DEAL_II_USE_MT == 1) && defined(DEAL_II_USE_MT_POSIX)
-
-  namespace internal
-  {
-    thread_description_base::thread_description_base ()
-                   :
-                   was_joined (false)
-    {}
-
-
-    
-    thread_description_base::~thread_description_base ()
-    {
-                                       // if we are here, then the
-                                       // last listener is just about
-                                       // to cease to exists. there
-                                       // are two possibilities (since
-                                       // there are two types of
-                                       // possible listeners, and
-                                       // exactly one listener is
-                                       // around):
-                                       //
-                                       // 1. there are no Thread<>
-                                       // objects around any more, but
-                                       // we are at the end of the
-                                       // entry_point function of the
-                                       // new thread; the thread is
-                                       // still running, though, and
-                                       // we are called from this new
-                                       // thread.
-                                       //
-                                       // if this is the case,
-                                       // apparently none of the
-                                       // orginal listeners has called
-                                       // join(), otherwise the thread
-                                       // would not be running any
-                                       // more. since there are no
-                                       // listeners any more, nobody
-                                       // will ever call join() on
-                                       // this thread any
-                                       // more. however, to avoid a
-                                       // resource leak, somebody has
-                                       // to do something like that --
-                                       // on the other hand, we can't
-                                       // since calling pthread_join()
-                                       // on ourself will create a
-                                       // deadlock, of course. so
-                                       // detach the thread.
-                                       //
-                                       // note that in this case,
-                                       // since nobody has ever called
-                                       // join(), was_joined must be
-                                       // false
-                                       //
-                                       // 2. the thread has already
-                                       // ended. in this case, the
-                                       // last Thread<> object
-                                       // refering to it just went out
-                                       // of scope. If this is the
-                                       // case, to prevent a memory
-                                       // leak, we have to call join
-                                       // on the thread, if this has
-                                       // not yet happened, i.e. if
-                                       // was_joined is false.
-                                       //
-                                       // if we are in case 2, then
-                                       // the destructor is called
-                                       // from another than the
-                                       // presently running thread
-                                       //
-                                       //
-                                       // now: how do we find out
-                                       // which case we're in? we
-                                       // could either call
-                                       // pthread_join and see whether
-                                       // we get an error back, or if
-                                       // we get back an error on
-                                       // pthread_detach. from the man
-                                       // pages, the second way seems
-                                       // a little bit safer, so go it:
-      if (was_joined == false)
-        {
-                                           // assume case 1:
-          int error = pthread_detach (thread);
-          if (error == 0)
-            return;
-
-                                           // ouch, could not
-                                           // detach. see if thread
-                                           // could not be found any
-                                           // more:
-          if (error == ESRCH)
-                                             // ok, this is the
-                                             // case. then we are in
-                                             // branch 2, and need to
-                                             // join the thread
-            join ();
-          else
-                                             // something went
-                                             // terribly wrong
-            AssertThrow (false, ExcInternalError());
-        }
-    }
-
-    
-    void
-    thread_description_base::create (void * (*p) (void *), void *d)
-    {
-                                       // start new thread. retry until
-                                       // we either succeed or get an
-                                       // error other than EAGAIN
-      int error = 0;
-      do
-        {
-          error = pthread_create (&thread, 0, p, d);
-        }
-      while (error == EAGAIN);
-
-      AssertThrow (error == 0,
-                  ExcThreadCreationError(error));
-    }
-      
-    
-
-    void
-    thread_description_base::join () const
-    {
-                                       // use Schmidt's double
-                                       // checking pattern: if thread
-                                       // was already joined, then
-                                       // return immediately
-      if (was_joined)
-        return;
-
-                                       // otherwise make sure that
-                                       // only one thread can enter
-                                       // the following section at a
-                                       // time
-      ThreadMutex::ScopedLock lock(join_mutex);
-                                       // while getting the lock,
-                                       // another thread may have set
-                                       // was_joined to true, so check
-                                       // again (this is the double
-                                       // checking pattern) and only
-                                       // if we are really sure that
-                                       // this has not happened, call
-                                       // pthread_join
-      if (!was_joined)
-        {
-          const int error = pthread_join (thread, 0);
-          AssertThrow (error == 0, ExcInternalError());
-        }
-
-                                       // set the flag
-      was_joined = true;
-    }
-    
-  } // end namespace internal
-
-#endif  // (DEAL_II_USE_MT == 1) && defined(DEAL_II_USE_MT_POSIX)
+  }
   
 }   // end namespace Thread
 
diff --git a/deal.II/contrib/boost/include/boost/thread/barrier.hpp b/deal.II/contrib/boost/include/boost/thread/barrier.hpp
new file mode 100644 (file)
index 0000000..546f5e9
--- /dev/null
@@ -0,0 +1,63 @@
+// Copyright (C) 2002-2003
+// David Moore, William E. Kempf
+// Copyright (C) 2007-8 Anthony Williams
+//
+//  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)
+
+#ifndef BOOST_BARRIER_JDM030602_HPP
+#define BOOST_BARRIER_JDM030602_HPP
+
+#include <boost/thread/detail/config.hpp>
+
+#include <boost/thread/mutex.hpp>
+#include <boost/thread/condition_variable.hpp>
+#include <string>
+#include <stdexcept>
+
+#include <boost/config/abi_prefix.hpp>
+
+namespace boost
+{
+
+    class barrier
+    {
+    public:
+        barrier(unsigned int count)
+            : m_threshold(count), m_count(count), m_generation(0)
+        {
+            if (count == 0)
+                throw std::invalid_argument("count cannot be zero.");
+        }
+    
+        bool wait()
+        {
+            boost::mutex::scoped_lock lock(m_mutex);
+            unsigned int gen = m_generation;
+        
+            if (--m_count == 0)
+            {
+                m_generation++;
+                m_count = m_threshold;
+                m_cond.notify_all();
+                return true;
+            }
+
+            while (gen == m_generation)
+                m_cond.wait(lock);
+            return false;
+        }
+
+    private:
+        mutex m_mutex;
+        condition_variable m_cond;
+        unsigned int m_threshold;
+        unsigned int m_count;
+        unsigned int m_generation;
+    };
+
+}   // namespace boost
+
+#include <boost/config/abi_suffix.hpp>
+
+#endif
diff --git a/deal.II/contrib/boost/include/boost/thread/condition.hpp b/deal.II/contrib/boost/include/boost/thread/condition.hpp
new file mode 100644 (file)
index 0000000..35b879f
--- /dev/null
@@ -0,0 +1,16 @@
+#ifndef BOOST_THREAD_CONDITION_HPP
+#define BOOST_THREAD_CONDITION_HPP
+//  (C) Copyright 2007 Anthony Williams 
+//
+//  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/thread/condition_variable.hpp>
+
+namespace boost
+{
+    typedef condition_variable_any condition;
+}
+
+#endif
diff --git a/deal.II/contrib/boost/include/boost/thread/condition_variable.hpp b/deal.II/contrib/boost/include/boost/thread/condition_variable.hpp
new file mode 100644 (file)
index 0000000..8f8e9f2
--- /dev/null
@@ -0,0 +1,21 @@
+#ifndef BOOST_THREAD_CONDITION_VARIABLE_HPP
+#define BOOST_THREAD_CONDITION_VARIABLE_HPP
+
+//  condition_variable.hpp
+//
+//  (C) Copyright 2007 Anthony Williams 
+//
+//  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/thread/detail/platform.hpp>
+#if defined(BOOST_THREAD_PLATFORM_WIN32)
+#include <boost/thread/win32/condition_variable.hpp>
+#elif defined(BOOST_THREAD_PLATFORM_PTHREAD)
+#include <boost/thread/pthread/condition_variable.hpp>
+#else
+#error "Boost threads unavailable on this platform"
+#endif
+
+#endif
diff --git a/deal.II/contrib/boost/include/boost/thread/detail/config.hpp b/deal.II/contrib/boost/include/boost/thread/detail/config.hpp
new file mode 100644 (file)
index 0000000..7661507
--- /dev/null
@@ -0,0 +1,94 @@
+// Copyright (C) 2001-2003
+// William E. Kempf
+//
+//  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)
+
+#ifndef BOOST_THREAD_CONFIG_WEK01032003_HPP
+#define BOOST_THREAD_CONFIG_WEK01032003_HPP
+
+#include <boost/config.hpp>
+#include <boost/detail/workaround.hpp>
+
+#if BOOST_WORKAROUND(__BORLANDC__, < 0x600)
+#  pragma warn -8008 // Condition always true/false
+#  pragma warn -8080 // Identifier declared but never used
+#  pragma warn -8057 // Parameter never used
+#  pragma warn -8066 // Unreachable code
+#endif
+
+#include "platform.hpp"
+
+// compatibility with the rest of Boost's auto-linking code:
+#if defined(BOOST_THREAD_DYN_DLL) || defined(BOOST_ALL_DYN_LINK)
+# undef  BOOST_THREAD_USE_LIB
+# define BOOST_THREAD_USE_DLL
+#endif
+
+#if defined(BOOST_THREAD_BUILD_DLL)   //Build dll
+#elif defined(BOOST_THREAD_BUILD_LIB) //Build lib
+#elif defined(BOOST_THREAD_USE_DLL)   //Use dll
+#elif defined(BOOST_THREAD_USE_LIB)   //Use lib
+#else //Use default
+#   if defined(BOOST_THREAD_PLATFORM_WIN32)
+#       if defined(BOOST_MSVC) || defined(BOOST_INTEL_WIN)
+            //For compilers supporting auto-tss cleanup
+            //with Boost.Threads lib, use Boost.Threads lib
+#           define BOOST_THREAD_USE_LIB
+#       else
+            //For compilers not yet supporting auto-tss cleanup
+            //with Boost.Threads lib, use Boost.Threads dll
+#           define BOOST_THREAD_USE_DLL
+#       endif
+#   else
+#       define BOOST_THREAD_USE_LIB
+#   endif
+#endif
+
+#if defined(BOOST_HAS_DECLSPEC)
+#   if defined(BOOST_THREAD_BUILD_DLL) //Build dll
+#       define BOOST_THREAD_DECL __declspec(dllexport)
+#   elif defined(BOOST_THREAD_USE_DLL) //Use dll
+#       define BOOST_THREAD_DECL __declspec(dllimport)
+#   else
+#       define BOOST_THREAD_DECL
+#   endif
+#else
+#   define BOOST_THREAD_DECL
+#endif // BOOST_HAS_DECLSPEC
+
+//
+// Automatically link to the correct build variant where possible.
+//
+#if !defined(BOOST_ALL_NO_LIB) && !defined(BOOST_THREAD_NO_LIB) && !defined(BOOST_THREAD_BUILD_DLL) && !defined(BOOST_THREAD_BUILD_LIB)
+//
+// Tell the autolink to link dynamically, this will get undef'ed by auto_link.hpp
+// once it's done with it: 
+//
+#if defined(BOOST_THREAD_USE_DLL)
+#   define BOOST_DYN_LINK
+#endif
+//
+// Set the name of our library, this will get undef'ed by auto_link.hpp
+// once it's done with it:
+//
+#if defined(BOOST_THREAD_LIB_NAME)
+#    define BOOST_LIB_NAME BOOST_THREAD_LIB_NAME
+#else
+#    define BOOST_LIB_NAME boost_thread
+#endif
+//
+// If we're importing code from a dll, then tell auto_link.hpp about it:
+//
+// And include the header that does the work:
+//
+#include <boost/config/auto_link.hpp>
+#endif  // auto-linking disabled
+
+#endif // BOOST_THREAD_CONFIG_WEK1032003_HPP
+
+// Change Log:
+//   22 Jan 05 Roland Schwarz (speedsnail)
+//      Usage of BOOST_HAS_DECLSPEC macro.
+//      Default again is static lib usage.
+//      BOOST_DYN_LINK only defined when autolink included.
diff --git a/deal.II/contrib/boost/include/boost/thread/detail/force_cast.hpp b/deal.II/contrib/boost/include/boost/thread/detail/force_cast.hpp
new file mode 100644 (file)
index 0000000..d5d15ad
--- /dev/null
@@ -0,0 +1,39 @@
+// Copyright (C) 2001-2003
+// Mac Murrett
+//
+// 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)
+//
+// See http://www.boost.org for most recent version including documentation.
+
+#ifndef BOOST_FORCE_CAST_MJM012402_HPP
+#define BOOST_FORCE_CAST_MJM012402_HPP
+
+#include <boost/thread/detail/config.hpp>
+
+namespace boost {
+namespace detail {
+namespace thread {
+
+// force_cast will convert anything to anything.
+
+// general case
+template<class Return_Type, class Argument_Type>
+inline Return_Type &force_cast(Argument_Type &rSrc)
+{
+    return(*reinterpret_cast<Return_Type *>(&rSrc));
+}
+
+// specialization for const
+template<class Return_Type, class Argument_Type>
+inline const Return_Type &force_cast(const Argument_Type &rSrc)
+{
+    return(*reinterpret_cast<const Return_Type *>(&rSrc));
+}
+
+} // namespace thread
+} // namespace detail
+} // namespace boost
+
+#endif // BOOST_FORCE_CAST_MJM012402_HPP
diff --git a/deal.II/contrib/boost/include/boost/thread/detail/move.hpp b/deal.II/contrib/boost/include/boost/thread/detail/move.hpp
new file mode 100644 (file)
index 0000000..044ecda
--- /dev/null
@@ -0,0 +1,60 @@
+// 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)
+// (C) Copyright 2007-8 Anthony Williams
+
+#ifndef BOOST_THREAD_MOVE_HPP
+#define BOOST_THREAD_MOVE_HPP
+
+#ifndef BOOST_NO_SFINAE
+#include <boost/utility/enable_if.hpp>
+#include <boost/type_traits/is_convertible.hpp>
+#endif
+
+#include <boost/config/abi_prefix.hpp>
+
+namespace boost
+{
+    namespace detail
+    {
+        template<typename T>
+        struct thread_move_t
+        {
+            T& t;
+            explicit thread_move_t(T& t_):
+                t(t_)
+            {}
+
+            T& operator*() const
+            {
+                return t;
+            }
+
+            T* operator->() const
+            {
+                return &t;
+            }
+        private:
+            void operator=(thread_move_t&);
+        };
+    }
+
+#ifndef BOOST_NO_SFINAE
+    template<typename T>
+    typename enable_if<boost::is_convertible<T&,detail::thread_move_t<T> >, T >::type move(T& t)
+    {
+        return T(detail::thread_move_t<T>(t));
+    }
+#endif
+    
+    template<typename T>
+    detail::thread_move_t<T> move(detail::thread_move_t<T> t)
+    {
+        return t;
+    }
+    
+}
+
+#include <boost/config/abi_suffix.hpp>
+
+#endif
diff --git a/deal.II/contrib/boost/include/boost/thread/detail/platform.hpp b/deal.II/contrib/boost/include/boost/thread/detail/platform.hpp
new file mode 100644 (file)
index 0000000..4a37cf3
--- /dev/null
@@ -0,0 +1,71 @@
+// Copyright 2006 Roland Schwarz.
+// (C) Copyright 2007 Anthony Williams
+// 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)
+//
+// This work is a reimplementation along the design and ideas
+// of William E. Kempf.
+
+#ifndef BOOST_THREAD_RS06040501_HPP
+#define BOOST_THREAD_RS06040501_HPP
+
+// fetch compiler and platform configuration
+#include <boost/config.hpp>
+
+// insist on threading support being available:
+#include <boost/config/requires_threads.hpp>
+
+// choose platform
+#if defined(linux) || defined(__linux) || defined(__linux__)
+#  define BOOST_THREAD_LINUX
+#elif defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__DragonFly__)
+#  define BOOST_THREAD_BSD
+#elif defined(sun) || defined(__sun)
+#  define BOOST_THREAD_SOLARIS
+#elif defined(__sgi)
+#  define BOOST_THREAD_IRIX
+#elif defined(__hpux)
+#  define BOOST_THREAD_HPUX
+#elif defined(__CYGWIN__)
+#  define BOOST_THREAD_CYGWIN
+#elif defined(_WIN32) || defined(__WIN32__) || defined(WIN32)
+#  define BOOST_THREAD_WIN32
+#elif defined(__BEOS__)
+#  define BOOST_THREAD_BEOS
+#elif defined(macintosh) || defined(__APPLE__) || defined(__APPLE_CC__)
+#  define BOOST_THREAD_MACOS
+#elif defined(__IBMCPP__) || defined(_AIX)
+#  define BOOST_THREAD_AIX
+#elif defined(__amigaos__)
+#  define BOOST_THREAD_AMIGAOS
+#elif defined(__QNXNTO__)
+#  define BOOST_THREAD_QNXNTO
+#elif defined(unix) || defined(__unix) || defined(_XOPEN_SOURCE) || defined(_POSIX_SOURCE)
+#       if defined(BOOST_HAS_PTHREADS) && !defined(BOOST_THREAD_POSIX)
+#               define BOOST_THREAD_POSIX
+#       endif
+#endif
+
+// For every supported platform add a new entry into the dispatch table below.
+// BOOST_THREAD_POSIX is tested first, so on platforms where posix and native
+// threading is available, the user may choose, by defining BOOST_THREAD_POSIX
+// in her source. If a platform is known to support pthreads and no native
+// port of boost_thread is available just specify "pthread" in the
+// dispatcher table. If there is no entry for a platform but pthreads is
+// available on the platform, pthread is choosen as default. If nothing is
+// available the preprocessor will fail with a diagnostic message.
+#if defined(BOOST_THREAD_POSIX)
+#  define BOOST_THREAD_PLATFORM_PTHREAD
+#else
+#  if defined(BOOST_THREAD_WIN32)
+#       define BOOST_THREAD_PLATFORM_WIN32
+#  elif defined(BOOST_HAS_PTHREADS)
+#       define BOOST_THREAD_PLATFORM_PTHREAD
+#  else
+#       error "Sorry, no boost threads are available for this platform."
+#  endif
+#endif
+
+#endif // BOOST_THREAD_RS06040501_HPP
diff --git a/deal.II/contrib/boost/include/boost/thread/detail/singleton.hpp b/deal.II/contrib/boost/include/boost/thread/detail/singleton.hpp
new file mode 100644 (file)
index 0000000..a20a429
--- /dev/null
@@ -0,0 +1,59 @@
+// Copyright (C) 2001-2003
+// Mac Murrett
+//
+// 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)
+//
+// See http://www.boost.org for most recent version including documentation.
+
+#ifndef BOOST_SINGLETON_MJM012402_HPP
+#define BOOST_SINGLETON_MJM012402_HPP
+
+#include <boost/thread/detail/config.hpp>
+
+namespace boost {
+namespace detail {
+namespace thread {
+
+// class singleton has the same goal as all singletons: create one instance of
+// a class on demand, then dish it out as requested.
+
+template <class T>
+class singleton : private T
+{
+private:
+    singleton();
+    ~singleton();
+
+public:
+    static T &instance();
+};
+
+
+template <class T>
+inline singleton<T>::singleton()
+{
+    /* no-op */
+}
+
+template <class T>
+inline singleton<T>::~singleton()
+{
+    /* no-op */
+}
+
+template <class T>
+/*static*/ T &singleton<T>::instance()
+{
+    // function-local static to force this to work correctly at static
+    // initialization time.
+    static singleton<T> s_oT;
+    return(s_oT);
+}
+
+} // namespace thread
+} // namespace detail
+} // namespace boost
+
+#endif // BOOST_SINGLETON_MJM012402_HPP
diff --git a/deal.II/contrib/boost/include/boost/thread/detail/thread.hpp b/deal.II/contrib/boost/include/boost/thread/detail/thread.hpp
new file mode 100644 (file)
index 0000000..fbb895d
--- /dev/null
@@ -0,0 +1,575 @@
+#ifndef BOOST_THREAD_THREAD_COMMON_HPP
+#define BOOST_THREAD_THREAD_COMMON_HPP
+// 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)
+// (C) Copyright 2007-8 Anthony Williams
+#include <boost/thread/exceptions.hpp>
+#include <ostream>
+#include <boost/thread/detail/move.hpp>
+#include <boost/thread/mutex.hpp>
+#include <boost/thread/xtime.hpp>
+#include <boost/thread/detail/thread_heap_alloc.hpp>
+#include <boost/utility.hpp>
+#include <boost/assert.hpp>
+#include <list>
+#include <algorithm>
+#include <boost/ref.hpp>
+#include <boost/cstdint.hpp>
+#include <boost/bind.hpp>
+#include <stdlib.h>
+#include <memory>
+#include <boost/utility/enable_if.hpp>
+#include <boost/type_traits/remove_reference.hpp>
+
+#include <boost/config/abi_prefix.hpp>
+
+#ifdef BOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable:4251)
+#endif
+
+namespace boost
+{
+    namespace detail
+    {
+        template<typename F>
+        class thread_data:
+            public detail::thread_data_base
+        {
+        public:
+#ifdef BOOST_HAS_RVALUE_REFS
+            thread_data(F&& f_):
+                f(static_cast<F&&>(f_))
+            {}
+#else
+            thread_data(F f_):
+                f(f_)
+            {}
+            thread_data(detail::thread_move_t<F> f_):
+                f(f_)
+            {}
+#endif            
+            void run()
+            {
+                f();
+            }
+        private:
+            F f;
+
+            void operator=(thread_data&);
+            thread_data(thread_data&);
+        };
+
+        template<typename F>
+        class thread_data<boost::reference_wrapper<F> >:
+            public detail::thread_data_base
+        {
+        private:
+            F& f;
+
+            void operator=(thread_data&);
+            thread_data(thread_data&);
+        public:
+            thread_data(boost::reference_wrapper<F> f_):
+                f(f_)
+            {}
+            
+            void run()
+            {
+                f();
+            }
+        };
+
+        template<typename F>
+        class thread_data<const boost::reference_wrapper<F> >:
+            public detail::thread_data_base
+        {
+        private:
+            F& f;
+            void operator=(thread_data&);
+            thread_data(thread_data&);
+        public:
+            thread_data(const boost::reference_wrapper<F> f_):
+                f(f_)
+            {}
+            
+            void run()
+            {
+                f();
+            }
+        };
+    }
+    
+    class BOOST_THREAD_DECL thread
+    {
+    private:
+        thread(thread&);
+        thread& operator=(thread&);
+
+        void release_handle();
+        
+        mutable boost::mutex thread_info_mutex;
+        detail::thread_data_ptr thread_info;
+
+        void start_thread();
+        
+        explicit thread(detail::thread_data_ptr data);
+
+        detail::thread_data_ptr get_thread_info() const;
+
+#ifdef BOOST_HAS_RVALUE_REFS
+        template<typename F>
+        static inline detail::thread_data_ptr make_thread_info(F&& f)
+        {
+            return detail::thread_data_ptr(detail::heap_new<detail::thread_data<typename boost::remove_reference<F>::type> >(static_cast<F&&>(f)));
+        }
+        static inline detail::thread_data_ptr make_thread_info(void (*f)())
+        {
+            return detail::thread_data_ptr(detail::heap_new<detail::thread_data<void(*)()> >(f));
+        }
+#else
+        template<typename F>
+        static inline detail::thread_data_ptr make_thread_info(F f)
+        {
+            return detail::thread_data_ptr(detail::heap_new<detail::thread_data<F> >(f));
+        }
+        template<typename F>
+        static inline detail::thread_data_ptr make_thread_info(boost::detail::thread_move_t<F> f)
+        {
+            return detail::thread_data_ptr(detail::heap_new<detail::thread_data<F> >(f));
+        }
+
+        struct dummy;
+#endif
+    public:
+        thread();
+        ~thread();
+
+#ifdef BOOST_HAS_RVALUE_REFS
+        template <class F>
+        thread(F&& f):
+            thread_info(make_thread_info(static_cast<F&&>(f)))
+        {
+            start_thread();
+        }
+
+        thread(thread&& other)
+        {
+            thread_info.swap(other.thread_info);
+        }
+        
+        thread& operator=(thread&& other)
+        {
+            thread_info=other.thread_info;
+            other.thread_info.reset();
+            return *this;
+        }
+
+        thread&& move()
+        {
+            return static_cast<thread&&>(*this);
+        }
+        
+#else
+#ifdef BOOST_NO_SFINAE
+        template <class F>
+        explicit thread(F f):
+            thread_info(make_thread_info(f))
+        {
+            start_thread();
+        }
+#else
+        template <class F>
+        explicit thread(F f,typename disable_if<boost::is_convertible<F&,detail::thread_move_t<F> >, dummy* >::type=0):
+            thread_info(make_thread_info(f))
+        {
+            start_thread();
+        }
+#endif
+        
+        template <class F>
+        explicit thread(detail::thread_move_t<F> f):
+            thread_info(make_thread_info(f))
+        {
+            start_thread();
+        }
+
+        thread(detail::thread_move_t<thread> x)
+        {
+            thread_info=x->thread_info;
+            x->thread_info.reset();
+        }
+        
+        thread& operator=(detail::thread_move_t<thread> x)
+        {
+            thread new_thread(x);
+            swap(new_thread);
+            return *this;
+        }
+        
+        operator detail::thread_move_t<thread>()
+        {
+            return move();
+        }
+        
+        detail::thread_move_t<thread> move()
+        {
+            detail::thread_move_t<thread> x(*this);
+            return x;
+        }
+
+#endif
+
+        template <class F,class A1>
+        thread(F f,A1 a1):
+            thread_info(make_thread_info(boost::bind(boost::type<void>(),f,a1)))
+        {
+            start_thread();
+        }
+        template <class F,class A1,class A2>
+        thread(F f,A1 a1,A2 a2):
+            thread_info(make_thread_info(boost::bind(boost::type<void>(),f,a1,a2)))
+        {
+            start_thread();
+        }
+
+        template <class F,class A1,class A2,class A3>
+        thread(F f,A1 a1,A2 a2,A3 a3):
+            thread_info(make_thread_info(boost::bind(boost::type<void>(),f,a1,a2,a3)))
+        {
+            start_thread();
+        }
+
+        template <class F,class A1,class A2,class A3,class A4>
+        thread(F f,A1 a1,A2 a2,A3 a3,A4 a4):
+            thread_info(make_thread_info(boost::bind(boost::type<void>(),f,a1,a2,a3,a4)))
+        {
+            start_thread();
+        }
+
+        template <class F,class A1,class A2,class A3,class A4,class A5>
+        thread(F f,A1 a1,A2 a2,A3 a3,A4 a4,A5 a5):
+            thread_info(make_thread_info(boost::bind(boost::type<void>(),f,a1,a2,a3,a4,a5)))
+        {
+            start_thread();
+        }
+
+        template <class F,class A1,class A2,class A3,class A4,class A5,class A6>
+        thread(F f,A1 a1,A2 a2,A3 a3,A4 a4,A5 a5,A6 a6):
+            thread_info(make_thread_info(boost::bind(boost::type<void>(),f,a1,a2,a3,a4,a5,a6)))
+        {
+            start_thread();
+        }
+
+        template <class F,class A1,class A2,class A3,class A4,class A5,class A6,class A7>
+        thread(F f,A1 a1,A2 a2,A3 a3,A4 a4,A5 a5,A6 a6,A7 a7):
+            thread_info(make_thread_info(boost::bind(boost::type<void>(),f,a1,a2,a3,a4,a5,a6,a7)))
+        {
+            start_thread();
+        }
+
+        template <class F,class A1,class A2,class A3,class A4,class A5,class A6,class A7,class A8>
+        thread(F f,A1 a1,A2 a2,A3 a3,A4 a4,A5 a5,A6 a6,A7 a7,A8 a8):
+            thread_info(make_thread_info(boost::bind(boost::type<void>(),f,a1,a2,a3,a4,a5,a6,a7,a8)))
+        {
+            start_thread();
+        }
+
+        template <class F,class A1,class A2,class A3,class A4,class A5,class A6,class A7,class A8,class A9>
+        thread(F f,A1 a1,A2 a2,A3 a3,A4 a4,A5 a5,A6 a6,A7 a7,A8 a8,A9 a9):
+            thread_info(make_thread_info(boost::bind(boost::type<void>(),f,a1,a2,a3,a4,a5,a6,a7,a8,a9)))
+        {
+            start_thread();
+        }
+
+        void swap(thread& x)
+        {
+            thread_info.swap(x.thread_info);
+        }
+
+        class id;
+        id get_id() const;
+
+
+        bool joinable() const;
+        void join();
+        bool timed_join(const system_time& wait_until);
+
+        template<typename TimeDuration>
+        inline bool timed_join(TimeDuration const& rel_time)
+        {
+            return timed_join(get_system_time()+rel_time);
+        }
+        void detach();
+
+        static unsigned hardware_concurrency();
+
+        typedef detail::thread_data_base::native_handle_type native_handle_type;
+        native_handle_type native_handle();
+
+        // backwards compatibility
+        bool operator==(const thread& other) const;
+        bool operator!=(const thread& other) const;
+
+        static inline void yield()
+        {
+            this_thread::yield();
+        }
+        
+        static inline void sleep(const system_time& xt)
+        {
+            this_thread::sleep(xt);
+        }
+
+        // extensions
+        void interrupt();
+        bool interruption_requested() const;
+    };
+
+    inline void swap(thread& lhs,thread& rhs)
+    {
+        return lhs.swap(rhs);
+    }
+    
+#ifdef BOOST_HAS_RVALUE_REFS
+    inline thread&& move(thread&& t)
+    {
+        return t;
+    }
+#else
+    inline thread move(detail::thread_move_t<thread> t)
+    {
+        return thread(t);
+    }
+#endif
+
+    namespace this_thread
+    {
+        class BOOST_THREAD_DECL disable_interruption
+        {
+            disable_interruption(const disable_interruption&);
+            disable_interruption& operator=(const disable_interruption&);
+            
+            bool interruption_was_enabled;
+            friend class restore_interruption;
+        public:
+            disable_interruption();
+            ~disable_interruption();
+        };
+
+        class BOOST_THREAD_DECL restore_interruption
+        {
+            restore_interruption(const restore_interruption&);
+            restore_interruption& operator=(const restore_interruption&);
+        public:
+            explicit restore_interruption(disable_interruption& d);
+            ~restore_interruption();
+        };
+
+        thread::id BOOST_THREAD_DECL get_id();
+
+        void BOOST_THREAD_DECL interruption_point();
+        bool BOOST_THREAD_DECL interruption_enabled();
+        bool BOOST_THREAD_DECL interruption_requested();
+
+        inline void sleep(xtime const& abs_time)
+        {
+            sleep(system_time(abs_time));
+        }
+    }
+
+    class thread::id
+    {
+    private:
+        detail::thread_data_ptr thread_data;
+            
+        id(detail::thread_data_ptr thread_data_):
+            thread_data(thread_data_)
+        {}
+        friend class thread;
+        friend id this_thread::get_id();
+    public:
+        id():
+            thread_data()
+        {}
+            
+        bool operator==(const id& y) const
+        {
+            return thread_data==y.thread_data;
+        }
+        
+        bool operator!=(const id& y) const
+        {
+            return thread_data!=y.thread_data;
+        }
+        
+        bool operator<(const id& y) const
+        {
+            return thread_data<y.thread_data;
+        }
+        
+        bool operator>(const id& y) const
+        {
+            return y.thread_data<thread_data;
+        }
+        
+        bool operator<=(const id& y) const
+        {
+            return !(y.thread_data<thread_data);
+        }
+        
+        bool operator>=(const id& y) const
+        {
+            return !(thread_data<y.thread_data);
+        }
+
+        template<class charT, class traits>
+        friend std::basic_ostream<charT, traits>& 
+        operator<<(std::basic_ostream<charT, traits>& os, const id& x)
+        {
+            if(x.thread_data)
+            {
+                return os<<x.thread_data;
+            }
+            else
+            {
+                return os<<"{Not-any-thread}";
+            }
+        }
+    };
+
+    inline bool thread::operator==(const thread& other) const
+    {
+        return get_id()==other.get_id();
+    }
+    
+    inline bool thread::operator!=(const thread& other) const
+    {
+        return get_id()!=other.get_id();
+    }
+        
+    namespace detail
+    {
+        struct thread_exit_function_base
+        {
+            virtual ~thread_exit_function_base()
+            {}
+            virtual void operator()() const=0;
+        };
+        
+        template<typename F>
+        struct thread_exit_function:
+            thread_exit_function_base
+        {
+            F f;
+            
+            thread_exit_function(F f_):
+                f(f_)
+            {}
+            
+            void operator()() const
+            {
+                f();
+            }
+        };
+        
+        void add_thread_exit_function(thread_exit_function_base*);
+    }
+    
+    namespace this_thread
+    {
+        template<typename F>
+        void at_thread_exit(F f)
+        {
+            detail::thread_exit_function_base* const thread_exit_func=detail::heap_new<detail::thread_exit_function<F> >(f);
+            detail::add_thread_exit_function(thread_exit_func);
+        }
+    }
+
+    class thread_group:
+        private noncopyable
+    {
+    public:
+        ~thread_group()
+        {
+            for(std::list<thread*>::iterator it=threads.begin(),end=threads.end();
+                it!=end;
+                ++it)
+            {
+                delete *it;
+            }
+        }
+
+        template<typename F>
+        thread* create_thread(F threadfunc)
+        {
+            boost::lock_guard<mutex> guard(m);
+            std::auto_ptr<thread> new_thread(new thread(threadfunc));
+            threads.push_back(new_thread.get());
+            return new_thread.release();
+        }
+        
+        void add_thread(thread* thrd)
+        {
+            if(thrd)
+            {
+                boost::lock_guard<mutex> guard(m);
+                threads.push_back(thrd);
+            }
+        }
+            
+        void remove_thread(thread* thrd)
+        {
+            boost::lock_guard<mutex> guard(m);
+            std::list<thread*>::iterator const it=std::find(threads.begin(),threads.end(),thrd);
+            if(it!=threads.end())
+            {
+                threads.erase(it);
+            }
+        }
+        
+        void join_all()
+        {
+            boost::lock_guard<mutex> guard(m);
+            
+            for(std::list<thread*>::iterator it=threads.begin(),end=threads.end();
+                it!=end;
+                ++it)
+            {
+                (*it)->join();
+            }
+        }
+        
+        void interrupt_all()
+        {
+            boost::lock_guard<mutex> guard(m);
+            
+            for(std::list<thread*>::iterator it=threads.begin(),end=threads.end();
+                it!=end;
+                ++it)
+            {
+                (*it)->interrupt();
+            }
+        }
+        
+        size_t size() const
+        {
+            boost::lock_guard<mutex> guard(m);
+            return threads.size();
+        }
+        
+    private:
+        std::list<thread*> threads;
+        mutable mutex m;
+    };
+}
+
+#ifdef BOOST_MSVC
+#pragma warning(pop)
+#endif
+
+#include <boost/config/abi_suffix.hpp>
+
+#endif
diff --git a/deal.II/contrib/boost/include/boost/thread/detail/thread_heap_alloc.hpp b/deal.II/contrib/boost/include/boost/thread/detail/thread_heap_alloc.hpp
new file mode 100644 (file)
index 0000000..2f9bfd5
--- /dev/null
@@ -0,0 +1,23 @@
+#ifndef BOOST_THREAD_THREAD_HEAP_ALLOC_HPP
+#define BOOST_THREAD_THREAD_HEAP_ALLOC_HPP
+
+//  thread_heap_alloc.hpp
+//
+//  (C) Copyright 2008 Anthony Williams 
+//
+//  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/thread/detail/platform.hpp>
+
+#if defined(BOOST_THREAD_PLATFORM_WIN32)
+#include <boost/thread/win32/thread_heap_alloc.hpp>
+#elif defined(BOOST_THREAD_PLATFORM_PTHREAD)
+#include <boost/thread/pthread/thread_heap_alloc.hpp>
+#else
+#error "Boost threads unavailable on this platform"
+#endif
+
+
+#endif
diff --git a/deal.II/contrib/boost/include/boost/thread/detail/tss_hooks.hpp b/deal.II/contrib/boost/include/boost/thread/detail/tss_hooks.hpp
new file mode 100644 (file)
index 0000000..c496844
--- /dev/null
@@ -0,0 +1,82 @@
+// (C) Copyright Michael Glassford 2004.
+// Use, modification and distribution are subject to 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)
+
+#if !defined(BOOST_TLS_HOOKS_HPP)
+#define BOOST_TLS_HOOKS_HPP
+
+#include <boost/thread/detail/config.hpp>
+
+#include <boost/config/abi_prefix.hpp>
+
+#if defined(BOOST_HAS_WINTHREADS)
+
+    typedef void (__cdecl *thread_exit_handler)(void);
+
+    extern "C" BOOST_THREAD_DECL int at_thread_exit(
+        thread_exit_handler exit_handler
+        );
+        //Add a function to the list of functions that will
+            //be called when a thread is about to exit.
+        //Currently only implemented for Win32, but should
+            //later be implemented for all platforms.
+        //Used by Win32 implementation of Boost.Threads
+            //tss to perform cleanup.
+        //Like the C runtime library atexit() function,
+            //which it mimics, at_thread_exit() returns
+            //zero if successful and a nonzero
+            //value if an error occurs.
+
+#endif //defined(BOOST_HAS_WINTHREADS)
+
+#if defined(BOOST_HAS_WINTHREADS)
+
+    extern "C" BOOST_THREAD_DECL void on_process_enter(void);
+        //Function to be called when the exe or dll
+            //that uses Boost.Threads first starts
+            //or is first loaded.
+        //Should be called only before the first call to
+            //on_thread_enter().
+        //Called automatically by Boost.Threads when
+            //a method for doing so has been discovered.
+        //May be omitted; may be called multiple times.
+
+    extern "C" BOOST_THREAD_DECL void on_process_exit(void);
+        //Function to be called when the exe or dll
+            //that uses Boost.Threads first starts
+            //or is first loaded.
+        //Should be called only after the last call to
+            //on_exit_thread().
+        //Called automatically by Boost.Threads when
+            //a method for doing so has been discovered.
+        //Must not be omitted; may be called multiple times.
+
+    extern "C" BOOST_THREAD_DECL void on_thread_enter(void);
+        //Function to be called just after a thread starts
+            //in an exe or dll that uses Boost.Threads.
+        //Must be called in the context of the thread
+            //that is starting.
+        //Called automatically by Boost.Threads when
+            //a method for doing so has been discovered.
+        //May be omitted; may be called multiple times.
+
+    extern "C" BOOST_THREAD_DECL void __cdecl on_thread_exit(void);
+        //Function to be called just be fore a thread ends
+            //in an exe or dll that uses Boost.Threads.
+        //Must be called in the context of the thread
+            //that is ending.
+        //Called automatically by Boost.Threads when
+            //a method for doing so has been discovered.
+        //Must not be omitted; may be called multiple times.
+    
+    extern "C" void tss_cleanup_implemented(void);
+        //Dummy function used both to detect whether tss cleanup
+            //cleanup has been implemented and to force
+            //it to be linked into the Boost.Threads library.
+
+#endif //defined(BOOST_HAS_WINTHREADS)
+
+#include <boost/config/abi_suffix.hpp>
+
+#endif //!defined(BOOST_TLS_HOOKS_HPP)
diff --git a/deal.II/contrib/boost/include/boost/thread/exceptions.hpp b/deal.II/contrib/boost/include/boost/thread/exceptions.hpp
new file mode 100644 (file)
index 0000000..49e244f
--- /dev/null
@@ -0,0 +1,114 @@
+// Copyright (C) 2001-2003
+// William E. Kempf
+// Copyright (C) 2007-8 Anthony Williams
+//
+//  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)
+
+#ifndef BOOST_THREAD_EXCEPTIONS_PDM070801_H
+#define BOOST_THREAD_EXCEPTIONS_PDM070801_H
+
+#include <boost/thread/detail/config.hpp>
+
+//  pdm: Sorry, but this class is used all over the place & I end up
+//       with recursive headers if I don't separate it
+//  wek: Not sure why recursive headers would cause compilation problems
+//       given the include guards, but regardless it makes sense to
+//       seperate this out any way.
+
+#include <string>
+#include <stdexcept>
+
+#include <boost/config/abi_prefix.hpp>
+
+namespace boost
+{
+
+    class BOOST_THREAD_DECL thread_interrupted
+    {};
+
+class BOOST_THREAD_DECL thread_exception : public std::exception
+{
+protected:
+    thread_exception();
+    thread_exception(int sys_err_code);
+
+public:
+    ~thread_exception() throw();
+
+    int native_error() const;
+
+private:
+    int m_sys_err;
+};
+
+    class condition_error:
+        public std::exception
+    {
+    public:
+        const char* what() const throw()
+        {
+            return "Condition error";
+        }
+    };
+    
+
+class BOOST_THREAD_DECL lock_error : public thread_exception
+{
+public:
+    lock_error();
+    lock_error(int sys_err_code);
+    ~lock_error() throw();
+
+    virtual const char* what() const throw();
+};
+
+class BOOST_THREAD_DECL thread_resource_error : public thread_exception
+{
+public:
+    thread_resource_error();
+    thread_resource_error(int sys_err_code);
+    ~thread_resource_error() throw();
+
+    virtual const char* what() const throw();
+};
+
+class BOOST_THREAD_DECL unsupported_thread_option : public thread_exception
+{
+public:
+    unsupported_thread_option();
+    unsupported_thread_option(int sys_err_code);
+    ~unsupported_thread_option() throw();
+
+    virtual const char* what() const throw();
+};
+
+class BOOST_THREAD_DECL invalid_thread_argument : public thread_exception
+{
+public:
+    invalid_thread_argument();
+    invalid_thread_argument(int sys_err_code);
+    ~invalid_thread_argument() throw();
+
+    virtual const char* what() const throw();
+};
+
+class BOOST_THREAD_DECL thread_permission_error : public thread_exception
+{
+public:
+    thread_permission_error();
+    thread_permission_error(int sys_err_code);
+    ~thread_permission_error() throw();
+
+    virtual const char* what() const throw();
+};
+
+} // namespace boost
+
+#include <boost/config/abi_suffix.hpp>
+
+#endif // BOOST_THREAD_CONFIG_PDM070801_H
+
+// Change log:
+//    3 Jan 03  WEKEMPF Modified for DLL implementation.
+
diff --git a/deal.II/contrib/boost/include/boost/thread/locks.hpp b/deal.II/contrib/boost/include/boost/thread/locks.hpp
new file mode 100644 (file)
index 0000000..abbfd75
--- /dev/null
@@ -0,0 +1,1430 @@
+// 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)
+// (C) Copyright 2007 Anthony Williams
+#ifndef BOOST_THREAD_LOCKS_HPP
+#define BOOST_THREAD_LOCKS_HPP
+#include <boost/thread/detail/config.hpp>
+#include <boost/thread/exceptions.hpp>
+#include <boost/thread/detail/move.hpp>
+#include <algorithm>
+#include <iterator>
+#include <boost/thread/thread_time.hpp>
+#include <boost/detail/workaround.hpp>
+
+#include <boost/config/abi_prefix.hpp>
+
+namespace boost
+{
+    struct xtime;
+
+#if defined(BOOST_NO_SFINAE) ||                           \
+    BOOST_WORKAROUND(__IBMCPP__, BOOST_TESTED_AT(600)) || \
+    BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x590))
+#define BOOST_THREAD_NO_AUTO_DETECT_MUTEX_TYPES
+#endif
+
+#ifndef BOOST_THREAD_NO_AUTO_DETECT_MUTEX_TYPES
+    namespace detail
+    {
+        template<typename T>
+        struct has_member_lock
+        {
+            typedef char true_type;
+            struct false_type
+            {
+                true_type dummy[2];
+            };
+            
+            template<typename U>
+            static true_type has_member(U*,void (U::*dummy)()=&U::lock);
+            static false_type has_member(void*);
+            
+            BOOST_STATIC_CONSTANT(bool, value=sizeof(has_member_lock<T>::has_member((T*)NULL))==sizeof(true_type));
+        };
+
+        template<typename T>
+        struct has_member_unlock
+        {
+            typedef char true_type;
+            struct false_type
+            {
+                true_type dummy[2];
+            };
+            
+            template<typename U>
+            static true_type has_member(U*,void (U::*dummy)()=&U::unlock);
+            static false_type has_member(void*);
+            
+            BOOST_STATIC_CONSTANT(bool, value=sizeof(has_member_unlock<T>::has_member((T*)NULL))==sizeof(true_type));
+        };
+        
+        template<typename T>
+        struct has_member_try_lock
+        {
+            typedef char true_type;
+            struct false_type
+            {
+                true_type dummy[2];
+            };
+            
+            template<typename U>
+            static true_type has_member(U*,bool (U::*dummy)()=&U::try_lock);
+            static false_type has_member(void*);
+            
+            BOOST_STATIC_CONSTANT(bool, value=sizeof(has_member_try_lock<T>::has_member((T*)NULL))==sizeof(true_type));
+        };
+
+    }
+    
+
+    template<typename T>
+    struct is_mutex_type
+    {
+        BOOST_STATIC_CONSTANT(bool, value = detail::has_member_lock<T>::value &&
+                              detail::has_member_unlock<T>::value &&
+                              detail::has_member_try_lock<T>::value);
+        
+    };
+#else
+    template<typename T>
+    struct is_mutex_type
+    {
+        BOOST_STATIC_CONSTANT(bool, value = false);
+    };
+#endif    
+
+    struct defer_lock_t
+    {};
+    struct try_to_lock_t
+    {};
+    struct adopt_lock_t
+    {};
+    
+    const defer_lock_t defer_lock={};
+    const try_to_lock_t try_to_lock={};
+    const adopt_lock_t adopt_lock={};
+
+    template<typename Mutex>
+    class shared_lock;
+
+    template<typename Mutex>
+    class upgrade_lock;
+
+    template<typename Mutex>
+    class unique_lock;
+
+    namespace detail
+    {
+        template<typename Mutex>
+        class try_lock_wrapper;
+    }
+    
+#ifdef BOOST_THREAD_NO_AUTO_DETECT_MUTEX_TYPES
+    template<typename T>
+    struct is_mutex_type<unique_lock<T> >
+    {
+        BOOST_STATIC_CONSTANT(bool, value = true);
+    };
+
+    template<typename T>
+    struct is_mutex_type<shared_lock<T> >
+    {
+        BOOST_STATIC_CONSTANT(bool, value = true);
+    };
+
+    template<typename T>
+    struct is_mutex_type<upgrade_lock<T> >
+    {
+        BOOST_STATIC_CONSTANT(bool, value = true);
+    };
+    
+    template<typename T>
+    struct is_mutex_type<detail::try_lock_wrapper<T> >
+    {
+        BOOST_STATIC_CONSTANT(bool, value = true);
+    };
+
+    class mutex;
+    class timed_mutex;
+    class recursive_mutex;
+    class recursive_timed_mutex;
+    class shared_mutex;
+    
+    template<>
+    struct is_mutex_type<mutex>
+    {
+        BOOST_STATIC_CONSTANT(bool, value = true);
+    };
+    template<>
+    struct is_mutex_type<timed_mutex>
+    {
+        BOOST_STATIC_CONSTANT(bool, value = true);
+    };
+    template<>
+    struct is_mutex_type<recursive_mutex>
+    {
+        BOOST_STATIC_CONSTANT(bool, value = true);
+    };
+    template<>
+    struct is_mutex_type<recursive_timed_mutex>
+    {
+        BOOST_STATIC_CONSTANT(bool, value = true);
+    };
+    template<>
+    struct is_mutex_type<shared_mutex>
+    {
+        BOOST_STATIC_CONSTANT(bool, value = true);
+    };
+
+#endif
+
+    template<typename Mutex>
+    class lock_guard
+    {
+    private:
+        Mutex& m;
+
+        explicit lock_guard(lock_guard&);
+        lock_guard& operator=(lock_guard&);
+    public:
+        explicit lock_guard(Mutex& m_):
+            m(m_)
+        {
+            m.lock();
+        }
+        lock_guard(Mutex& m_,adopt_lock_t):
+            m(m_)
+        {}
+        ~lock_guard()
+        {
+            m.unlock();
+        }
+    };
+
+
+    template<typename Mutex>
+    class unique_lock
+    {
+    private:
+        Mutex* m;
+        bool is_locked;
+        unique_lock(unique_lock&);
+        explicit unique_lock(upgrade_lock<Mutex>&);
+        unique_lock& operator=(unique_lock&);
+        unique_lock& operator=(upgrade_lock<Mutex>& other);
+    public:
+        unique_lock():
+            m(0),is_locked(false)
+        {}
+        
+        explicit unique_lock(Mutex& m_):
+            m(&m_),is_locked(false)
+        {
+            lock();
+        }
+        unique_lock(Mutex& m_,adopt_lock_t):
+            m(&m_),is_locked(true)
+        {}
+        unique_lock(Mutex& m_,defer_lock_t):
+            m(&m_),is_locked(false)
+        {}
+        unique_lock(Mutex& m_,try_to_lock_t):
+            m(&m_),is_locked(false)
+        {
+            try_lock();
+        }
+        template<typename TimeDuration>
+        unique_lock(Mutex& m_,TimeDuration const& target_time):
+            m(&m_),is_locked(false)
+        {
+            timed_lock(target_time);
+        }
+        unique_lock(Mutex& m_,system_time const& target_time):
+            m(&m_),is_locked(false)
+        {
+            timed_lock(target_time);
+        }
+#ifdef BOOST_HAS_RVALUE_REFS
+        unique_lock(unique_lock&& other):
+            m(other.m),is_locked(other.is_locked)
+        {
+            other.is_locked=false;
+            other.m=0;
+        }
+        explicit unique_lock(upgrade_lock<Mutex>&& other);
+
+        unique_lock<Mutex>&& move()
+        {
+            return static_cast<unique_lock<Mutex>&&>(*this);
+        }
+
+
+        unique_lock& operator=(unique_lock<Mutex>&& other)
+        {
+            unique_lock temp(other);
+            swap(temp);
+            return *this;
+        }
+
+        unique_lock& operator=(upgrade_lock<Mutex>&& other)
+        {
+            unique_lock temp(other);
+            swap(temp);
+            return *this;
+        }
+        void swap(unique_lock&& other)
+        {
+            std::swap(m,other.m);
+            std::swap(is_locked,other.is_locked);
+        }
+#else
+        unique_lock(detail::thread_move_t<unique_lock<Mutex> > other):
+            m(other->m),is_locked(other->is_locked)
+        {
+            other->is_locked=false;
+            other->m=0;
+        }
+        unique_lock(detail::thread_move_t<upgrade_lock<Mutex> > other);
+
+        operator detail::thread_move_t<unique_lock<Mutex> >()
+        {
+            return move();
+        }
+
+        detail::thread_move_t<unique_lock<Mutex> > move()
+        {
+            return detail::thread_move_t<unique_lock<Mutex> >(*this);
+        }
+
+        unique_lock& operator=(detail::thread_move_t<unique_lock<Mutex> > other)
+        {
+            unique_lock temp(other);
+            swap(temp);
+            return *this;
+        }
+
+        unique_lock& operator=(detail::thread_move_t<upgrade_lock<Mutex> > other)
+        {
+            unique_lock temp(other);
+            swap(temp);
+            return *this;
+        }
+        void swap(unique_lock& other)
+        {
+            std::swap(m,other.m);
+            std::swap(is_locked,other.is_locked);
+        }
+        void swap(detail::thread_move_t<unique_lock<Mutex> > other)
+        {
+            std::swap(m,other->m);
+            std::swap(is_locked,other->is_locked);
+        }
+#endif
+        
+        ~unique_lock()
+        {
+            if(owns_lock())
+            {
+                m->unlock();
+            }
+        }
+        void lock()
+        {
+            if(owns_lock())
+            {
+                throw boost::lock_error();
+            }
+            m->lock();
+            is_locked=true;
+        }
+        bool try_lock()
+        {
+            if(owns_lock())
+            {
+                throw boost::lock_error();
+            }
+            is_locked=m->try_lock();
+            return is_locked;
+        }
+        template<typename TimeDuration>
+        bool timed_lock(TimeDuration const& relative_time)
+        {
+            is_locked=m->timed_lock(relative_time);
+            return is_locked;
+        }
+        
+        bool timed_lock(::boost::system_time const& absolute_time)
+        {
+            is_locked=m->timed_lock(absolute_time);
+            return is_locked;
+        }
+        bool timed_lock(::boost::xtime const& absolute_time)
+        {
+            is_locked=m->timed_lock(absolute_time);
+            return is_locked;
+        }
+        void unlock()
+        {
+            if(!owns_lock())
+            {
+                throw boost::lock_error();
+            }
+            m->unlock();
+            is_locked=false;
+        }
+            
+        typedef void (unique_lock::*bool_type)();
+        operator bool_type() const
+        {
+            return is_locked?&unique_lock::lock:0;
+        }
+        bool operator!() const
+        {
+            return !owns_lock();
+        }
+        bool owns_lock() const
+        {
+            return is_locked;
+        }
+
+        Mutex* mutex() const
+        {
+            return m;
+        }
+
+        Mutex* release()
+        {
+            Mutex* const res=m;
+            m=0;
+            is_locked=false;
+            return res;
+        }
+
+        friend class shared_lock<Mutex>;
+        friend class upgrade_lock<Mutex>;
+    };
+
+#ifdef BOOST_HAS_RVALUE_REFS
+    template<typename Mutex>
+    void swap(unique_lock<Mutex>&& lhs,unique_lock<Mutex>&& rhs)
+    {
+        lhs.swap(rhs);
+    }
+#else
+    template<typename Mutex>
+    void swap(unique_lock<Mutex>& lhs,unique_lock<Mutex>& rhs)
+    {
+        lhs.swap(rhs);
+    }
+#endif
+
+#ifdef BOOST_HAS_RVALUE_REFS
+    template<typename Mutex>
+    inline unique_lock<Mutex>&& move(unique_lock<Mutex>&& ul)
+    {
+        return ul;
+    }
+#endif
+
+    template<typename Mutex>
+    class shared_lock
+    {
+    protected:
+        Mutex* m;
+        bool is_locked;
+    private:
+        explicit shared_lock(shared_lock&);
+        shared_lock& operator=(shared_lock&);
+    public:
+        shared_lock():
+            m(0),is_locked(false)
+        {}
+        
+        explicit shared_lock(Mutex& m_):
+            m(&m_),is_locked(false)
+        {
+            lock();
+        }
+        shared_lock(Mutex& m_,adopt_lock_t):
+            m(&m_),is_locked(true)
+        {}
+        shared_lock(Mutex& m_,defer_lock_t):
+            m(&m_),is_locked(false)
+        {}
+        shared_lock(Mutex& m_,try_to_lock_t):
+            m(&m_),is_locked(false)
+        {
+            try_lock();
+        }
+        shared_lock(Mutex& m_,system_time const& target_time):
+            m(&m_),is_locked(false)
+        {
+            timed_lock(target_time);
+        }
+
+        shared_lock(detail::thread_move_t<shared_lock<Mutex> > other):
+            m(other->m),is_locked(other->is_locked)
+        {
+            other->is_locked=false;
+            other->m=0;
+        }
+
+        shared_lock(detail::thread_move_t<unique_lock<Mutex> > other):
+            m(other->m),is_locked(other->is_locked)
+        {
+            if(is_locked)
+            {
+                m->unlock_and_lock_shared();
+            }
+            other->is_locked=false;
+            other->m=0;
+        }
+
+        shared_lock(detail::thread_move_t<upgrade_lock<Mutex> > other):
+            m(other->m),is_locked(other->is_locked)
+        {
+            if(is_locked)
+            {
+                m->unlock_upgrade_and_lock_shared();
+            }
+            other->is_locked=false;
+            other->m=0;
+        }
+
+        operator detail::thread_move_t<shared_lock<Mutex> >()
+        {
+            return move();
+        }
+
+        detail::thread_move_t<shared_lock<Mutex> > move()
+        {
+            return detail::thread_move_t<shared_lock<Mutex> >(*this);
+        }
+
+
+        shared_lock& operator=(detail::thread_move_t<shared_lock<Mutex> > other)
+        {
+            shared_lock temp(other);
+            swap(temp);
+            return *this;
+        }
+
+        shared_lock& operator=(detail::thread_move_t<unique_lock<Mutex> > other)
+        {
+            shared_lock temp(other);
+            swap(temp);
+            return *this;
+        }
+
+        shared_lock& operator=(detail::thread_move_t<upgrade_lock<Mutex> > other)
+        {
+            shared_lock temp(other);
+            swap(temp);
+            return *this;
+        }
+
+#ifdef BOOST_HAS_RVALUE_REFS
+        void swap(shared_lock&& other)
+        {
+            std::swap(m,other.m);
+            std::swap(is_locked,other.is_locked);
+        }
+#else
+        void swap(shared_lock& other)
+        {
+            std::swap(m,other.m);
+            std::swap(is_locked,other.is_locked);
+        }
+        void swap(boost::detail::thread_move_t<shared_lock<Mutex> > other)
+        {
+            std::swap(m,other->m);
+            std::swap(is_locked,other->is_locked);
+        }
+#endif
+
+        Mutex* mutex() const
+        {
+            return m;
+        }
+        
+        ~shared_lock()
+        {
+            if(owns_lock())
+            {
+                m->unlock_shared();
+            }
+        }
+        void lock()
+        {
+            if(owns_lock())
+            {
+                throw boost::lock_error();
+            }
+            m->lock_shared();
+            is_locked=true;
+        }
+        bool try_lock()
+        {
+            if(owns_lock())
+            {
+                throw boost::lock_error();
+            }
+            is_locked=m->try_lock_shared();
+            return is_locked;
+        }
+        bool timed_lock(boost::system_time const& target_time)
+        {
+            if(owns_lock())
+            {
+                throw boost::lock_error();
+            }
+            is_locked=m->timed_lock_shared(target_time);
+            return is_locked;
+        }
+        template<typename Duration>
+        bool timed_lock(Duration const& target_time)
+        {
+            if(owns_lock())
+            {
+                throw boost::lock_error();
+            }
+            is_locked=m->timed_lock_shared(target_time);
+            return is_locked;
+        }
+        void unlock()
+        {
+            if(!owns_lock())
+            {
+                throw boost::lock_error();
+            }
+            m->unlock_shared();
+            is_locked=false;
+        }
+            
+        typedef void (shared_lock<Mutex>::*bool_type)();
+        operator bool_type() const
+        {
+            return is_locked?&shared_lock::lock:0;
+        }
+        bool operator!() const
+        {
+            return !owns_lock();
+        }
+        bool owns_lock() const
+        {
+            return is_locked;
+        }
+
+    };
+
+#ifdef BOOST_HAS_RVALUE_REFS
+    template<typename Mutex>
+    void swap(shared_lock<Mutex>&& lhs,shared_lock<Mutex>&& rhs)
+    {
+        lhs.swap(rhs);
+    }
+#else
+    template<typename Mutex>
+    void swap(shared_lock<Mutex>& lhs,shared_lock<Mutex>& rhs)
+    {
+        lhs.swap(rhs);
+    }
+#endif
+
+    template<typename Mutex>
+    class upgrade_lock
+    {
+    protected:
+        Mutex* m;
+        bool is_locked;
+    private:
+        explicit upgrade_lock(upgrade_lock&);
+        upgrade_lock& operator=(upgrade_lock&);
+    public:
+        upgrade_lock():
+            m(0),is_locked(false)
+        {}
+        
+        explicit upgrade_lock(Mutex& m_):
+            m(&m_),is_locked(false)
+        {
+            lock();
+        }
+        upgrade_lock(Mutex& m_,adopt_lock_t):
+            m(&m_),is_locked(true)
+        {}
+        upgrade_lock(Mutex& m_,defer_lock_t):
+            m(&m_),is_locked(false)
+        {}
+        upgrade_lock(Mutex& m_,try_to_lock_t):
+            m(&m_),is_locked(false)
+        {
+            try_lock();
+        }
+        upgrade_lock(detail::thread_move_t<upgrade_lock<Mutex> > other):
+            m(other->m),is_locked(other->is_locked)
+        {
+            other->is_locked=false;
+            other->m=0;
+        }
+
+        upgrade_lock(detail::thread_move_t<unique_lock<Mutex> > other):
+            m(other->m),is_locked(other->is_locked)
+        {
+            if(is_locked)
+            {
+                m->unlock_and_lock_upgrade();
+            }
+            other->is_locked=false;
+            other->m=0;
+        }
+
+        operator detail::thread_move_t<upgrade_lock<Mutex> >()
+        {
+            return move();
+        }
+
+        detail::thread_move_t<upgrade_lock<Mutex> > move()
+        {
+            return detail::thread_move_t<upgrade_lock<Mutex> >(*this);
+        }
+
+
+        upgrade_lock& operator=(detail::thread_move_t<upgrade_lock<Mutex> > other)
+        {
+            upgrade_lock temp(other);
+            swap(temp);
+            return *this;
+        }
+
+        upgrade_lock& operator=(detail::thread_move_t<unique_lock<Mutex> > other)
+        {
+            upgrade_lock temp(other);
+            swap(temp);
+            return *this;
+        }
+
+        void swap(upgrade_lock& other)
+        {
+            std::swap(m,other.m);
+            std::swap(is_locked,other.is_locked);
+        }
+        
+        ~upgrade_lock()
+        {
+            if(owns_lock())
+            {
+                m->unlock_upgrade();
+            }
+        }
+        void lock()
+        {
+            if(owns_lock())
+            {
+                throw boost::lock_error();
+            }
+            m->lock_upgrade();
+            is_locked=true;
+        }
+        bool try_lock()
+        {
+            if(owns_lock())
+            {
+                throw boost::lock_error();
+            }
+            is_locked=m->try_lock_upgrade();
+            return is_locked;
+        }
+        void unlock()
+        {
+            if(!owns_lock())
+            {
+                throw boost::lock_error();
+            }
+            m->unlock_upgrade();
+            is_locked=false;
+        }
+            
+        typedef void (upgrade_lock::*bool_type)();
+        operator bool_type() const
+        {
+            return is_locked?&upgrade_lock::lock:0;
+        }
+        bool operator!() const
+        {
+            return !owns_lock();
+        }
+        bool owns_lock() const
+        {
+            return is_locked;
+        }
+        friend class shared_lock<Mutex>;
+        friend class unique_lock<Mutex>;
+    };
+
+
+#ifdef BOOST_HAS_RVALUE_REFS
+    template<typename Mutex>
+    unique_lock<Mutex>::unique_lock(upgrade_lock<Mutex>&& other):
+        m(other.m),is_locked(other.is_locked)
+    {
+        other.is_locked=false;
+        if(is_locked)
+        {
+            m.unlock_upgrade_and_lock();
+        }
+    }
+#else
+    template<typename Mutex>
+    unique_lock<Mutex>::unique_lock(detail::thread_move_t<upgrade_lock<Mutex> > other):
+        m(other->m),is_locked(other->is_locked)
+    {
+        other->is_locked=false;
+        if(is_locked)
+        {
+            m->unlock_upgrade_and_lock();
+        }
+    }
+#endif
+    template <class Mutex>
+    class upgrade_to_unique_lock
+    {
+    private:
+        upgrade_lock<Mutex>* source;
+        unique_lock<Mutex> exclusive;
+
+        explicit upgrade_to_unique_lock(upgrade_to_unique_lock&);
+        upgrade_to_unique_lock& operator=(upgrade_to_unique_lock&);
+    public:
+        explicit upgrade_to_unique_lock(upgrade_lock<Mutex>& m_):
+            source(&m_),exclusive(move(*source))
+        {}
+        ~upgrade_to_unique_lock()
+        {
+            if(source)
+            {
+                *source=move(exclusive);
+            }
+        }
+
+        upgrade_to_unique_lock(detail::thread_move_t<upgrade_to_unique_lock<Mutex> > other):
+            source(other->source),exclusive(move(other->exclusive))
+        {
+            other->source=0;
+        }
+        
+        upgrade_to_unique_lock& operator=(detail::thread_move_t<upgrade_to_unique_lock<Mutex> > other)
+        {
+            upgrade_to_unique_lock temp(other);
+            swap(temp);
+            return *this;
+        }
+        void swap(upgrade_to_unique_lock& other)
+        {
+            std::swap(source,other.source);
+            exclusive.swap(other.exclusive);
+        }
+        typedef void (upgrade_to_unique_lock::*bool_type)(upgrade_to_unique_lock&);
+        operator bool_type() const
+        {
+            return exclusive.owns_lock()?&upgrade_to_unique_lock::swap:0;
+        }
+        bool operator!() const
+        {
+            return !owns_lock();
+        }
+        bool owns_lock() const
+        {
+            return exclusive.owns_lock();
+        }
+    };
+
+    namespace detail
+    {
+        template<typename Mutex>
+        class try_lock_wrapper:
+            private unique_lock<Mutex>
+        {
+            typedef unique_lock<Mutex> base;
+        public:
+            try_lock_wrapper()
+            {}
+            
+            explicit try_lock_wrapper(Mutex& m):
+                base(m,try_to_lock)
+            {}
+
+            try_lock_wrapper(Mutex& m_,adopt_lock_t):
+                base(m_,adopt_lock)
+            {}
+            try_lock_wrapper(Mutex& m_,defer_lock_t):
+                base(m_,defer_lock)
+            {}
+            try_lock_wrapper(Mutex& m_,try_to_lock_t):
+                base(m_,try_to_lock)
+            {}
+            try_lock_wrapper(detail::thread_move_t<try_lock_wrapper<Mutex> > other):
+                base(detail::thread_move_t<base>(*other))
+            {}
+
+            operator detail::thread_move_t<try_lock_wrapper<Mutex> >()
+            {
+                return move();
+            }
+
+            detail::thread_move_t<try_lock_wrapper<Mutex> > move()
+            {
+                return detail::thread_move_t<try_lock_wrapper<Mutex> >(*this);
+            }
+
+            try_lock_wrapper& operator=(detail::thread_move_t<try_lock_wrapper<Mutex> > other)
+            {
+                try_lock_wrapper temp(other);
+                swap(temp);
+                return *this;
+            }
+
+#ifdef BOOST_HAS_RVALUE_REFS
+            void swap(try_lock_wrapper&& other)
+            {
+                base::swap(other);
+            }
+#else
+            void swap(try_lock_wrapper& other)
+            {
+                base::swap(other);
+            }
+            void swap(detail::thread_move_t<try_lock_wrapper<Mutex> > other)
+            {
+                base::swap(*other);
+            }
+#endif
+
+            void lock()
+            {
+                base::lock();
+            }
+            bool try_lock()
+            {
+                return base::try_lock();
+            }
+            void unlock()
+            {
+                base::unlock();
+            }
+            bool owns_lock() const
+            {
+                return base::owns_lock();
+            }
+            Mutex* mutex() const
+            {
+                return base::mutex();
+            }
+            Mutex* release()
+            {
+                return base::release();
+            }
+            bool operator!() const
+            {
+                return !this->owns_lock();
+            }
+
+            typedef typename base::bool_type bool_type;
+            operator bool_type() const
+            {
+                return base::operator bool_type();
+            }
+        };
+
+#ifdef BOOST_HAS_RVALUE_REFS
+        template<typename Mutex>
+        void swap(try_lock_wrapper<Mutex>&& lhs,try_lock_wrapper<Mutex>&& rhs)
+        {
+            lhs.swap(rhs);
+        }
+#else
+        template<typename Mutex>
+        void swap(try_lock_wrapper<Mutex>& lhs,try_lock_wrapper<Mutex>& rhs)
+        {
+            lhs.swap(rhs);
+        }
+#endif
+        
+        template<typename MutexType1,typename MutexType2>
+        unsigned try_lock_internal(MutexType1& m1,MutexType2& m2)
+        {
+            boost::unique_lock<MutexType1> l1(m1,boost::try_to_lock);
+            if(!l1)
+            {
+                return 1;
+            }
+            if(!m2.try_lock())
+            {
+                return 2;
+            }
+            l1.release();
+            return 0;
+        }
+
+        template<typename MutexType1,typename MutexType2,typename MutexType3>
+        unsigned try_lock_internal(MutexType1& m1,MutexType2& m2,MutexType3& m3)
+        {
+            boost::unique_lock<MutexType1> l1(m1,boost::try_to_lock);
+            if(!l1)
+            {
+                return 1;
+            }
+            if(unsigned const failed_lock=try_lock_internal(m2,m3))
+            {
+                return failed_lock+1;
+            }
+            l1.release();
+            return 0;
+        }
+
+
+        template<typename MutexType1,typename MutexType2,typename MutexType3,
+                 typename MutexType4>
+        unsigned try_lock_internal(MutexType1& m1,MutexType2& m2,MutexType3& m3,
+                                   MutexType4& m4)
+        {
+            boost::unique_lock<MutexType1> l1(m1,boost::try_to_lock);
+            if(!l1)
+            {
+                return 1;
+            }
+            if(unsigned const failed_lock=try_lock_internal(m2,m3,m4))
+            {
+                return failed_lock+1;
+            }
+            l1.release();
+            return 0;
+        }
+
+        template<typename MutexType1,typename MutexType2,typename MutexType3,
+                 typename MutexType4,typename MutexType5>
+        unsigned try_lock_internal(MutexType1& m1,MutexType2& m2,MutexType3& m3,
+                                   MutexType4& m4,MutexType5& m5)
+        {
+            boost::unique_lock<MutexType1> l1(m1,boost::try_to_lock);
+            if(!l1)
+            {
+                return 1;
+            }
+            if(unsigned const failed_lock=try_lock_internal(m2,m3,m4,m5))
+            {
+                return failed_lock+1;
+            }
+            l1.release();
+            return 0;
+        }
+
+
+        template<typename MutexType1,typename MutexType2>
+        unsigned lock_helper(MutexType1& m1,MutexType2& m2)
+        {
+            boost::unique_lock<MutexType1> l1(m1);
+            if(!m2.try_lock())
+            {
+                return 1;
+            }
+            l1.release();
+            return 0;
+        }
+
+        template<typename MutexType1,typename MutexType2,typename MutexType3>
+        unsigned lock_helper(MutexType1& m1,MutexType2& m2,MutexType3& m3)
+        {
+            boost::unique_lock<MutexType1> l1(m1);
+            if(unsigned const failed_lock=try_lock_internal(m2,m3))
+            {
+                return failed_lock;
+            }
+            l1.release();
+            return 0;
+        }
+
+        template<typename MutexType1,typename MutexType2,typename MutexType3,
+                 typename MutexType4>
+        unsigned lock_helper(MutexType1& m1,MutexType2& m2,MutexType3& m3,
+                             MutexType4& m4)
+        {
+            boost::unique_lock<MutexType1> l1(m1);
+            if(unsigned const failed_lock=try_lock_internal(m2,m3,m4))
+            {
+                return failed_lock;
+            }
+            l1.release();
+            return 0;
+        }
+
+        template<typename MutexType1,typename MutexType2,typename MutexType3,
+                 typename MutexType4,typename MutexType5>
+        unsigned lock_helper(MutexType1& m1,MutexType2& m2,MutexType3& m3,
+                             MutexType4& m4,MutexType5& m5)
+        {
+            boost::unique_lock<MutexType1> l1(m1);
+            if(unsigned const failed_lock=try_lock_internal(m2,m3,m4,m5))
+            {
+                return failed_lock;
+            }
+            l1.release();
+            return 0;
+        }
+    }
+
+    namespace detail
+    {
+        template<bool x>
+        struct is_mutex_type_wrapper
+        {};
+        
+        template<typename MutexType1,typename MutexType2>
+        void lock_impl(MutexType1& m1,MutexType2& m2,is_mutex_type_wrapper<true>)
+        {
+            unsigned const lock_count=2;
+            unsigned lock_first=0;
+            while(true)
+            {
+                switch(lock_first)
+                {
+                case 0:
+                    lock_first=detail::lock_helper(m1,m2);
+                    if(!lock_first)
+                        return;
+                    break;
+                case 1:
+                    lock_first=detail::lock_helper(m2,m1);
+                    if(!lock_first)
+                        return;
+                    lock_first=(lock_first+1)%lock_count;
+                    break;
+                }
+            }
+        }
+
+        template<typename Iterator>
+        void lock_impl(Iterator begin,Iterator end,is_mutex_type_wrapper<false>);
+    }
+    
+
+    template<typename MutexType1,typename MutexType2>
+    void lock(MutexType1& m1,MutexType2& m2)
+    {
+        detail::lock_impl(m1,m2,detail::is_mutex_type_wrapper<is_mutex_type<MutexType1>::value>());
+    }
+
+    template<typename MutexType1,typename MutexType2>
+    void lock(const MutexType1& m1,MutexType2& m2)
+    {
+        detail::lock_impl(m1,m2,detail::is_mutex_type_wrapper<is_mutex_type<MutexType1>::value>());
+    }
+
+    template<typename MutexType1,typename MutexType2>
+    void lock(MutexType1& m1,const MutexType2& m2)
+    {
+        detail::lock_impl(m1,m2,detail::is_mutex_type_wrapper<is_mutex_type<MutexType1>::value>());
+    }
+
+    template<typename MutexType1,typename MutexType2>
+    void lock(const MutexType1& m1,const MutexType2& m2)
+    {
+        detail::lock_impl(m1,m2,detail::is_mutex_type_wrapper<is_mutex_type<MutexType1>::value>());
+    }
+
+    template<typename MutexType1,typename MutexType2,typename MutexType3>
+    void lock(MutexType1& m1,MutexType2& m2,MutexType3& m3)
+    {
+        unsigned const lock_count=3;
+        unsigned lock_first=0;
+        while(true)
+        {
+            switch(lock_first)
+            {
+            case 0:
+                lock_first=detail::lock_helper(m1,m2,m3);
+                if(!lock_first)
+                    return;
+                break;
+            case 1:
+                lock_first=detail::lock_helper(m2,m3,m1);
+                if(!lock_first)
+                    return;
+                lock_first=(lock_first+1)%lock_count;
+                break;
+            case 2:
+                lock_first=detail::lock_helper(m3,m1,m2);
+                if(!lock_first)
+                    return;
+                lock_first=(lock_first+2)%lock_count;
+                break;
+            }
+        }
+    }
+
+    template<typename MutexType1,typename MutexType2,typename MutexType3,
+             typename MutexType4>
+    void lock(MutexType1& m1,MutexType2& m2,MutexType3& m3,
+              MutexType4& m4)
+    {
+        unsigned const lock_count=4;
+        unsigned lock_first=0;
+        while(true)
+        {
+            switch(lock_first)
+            {
+            case 0:
+                lock_first=detail::lock_helper(m1,m2,m3,m4);
+                if(!lock_first)
+                    return;
+                break;
+            case 1:
+                lock_first=detail::lock_helper(m2,m3,m4,m1);
+                if(!lock_first)
+                    return;
+                lock_first=(lock_first+1)%lock_count;
+                break;
+            case 2:
+                lock_first=detail::lock_helper(m3,m4,m1,m2);
+                if(!lock_first)
+                    return;
+                lock_first=(lock_first+2)%lock_count;
+                break;
+            case 3:
+                lock_first=detail::lock_helper(m4,m1,m2,m3);
+                if(!lock_first)
+                    return;
+                lock_first=(lock_first+3)%lock_count;
+                break;
+            }
+        }
+    }
+
+    template<typename MutexType1,typename MutexType2,typename MutexType3,
+             typename MutexType4,typename MutexType5>
+    void lock(MutexType1& m1,MutexType2& m2,MutexType3& m3,
+              MutexType4& m4,MutexType5& m5)
+    {
+        unsigned const lock_count=5;
+        unsigned lock_first=0;
+        while(true)
+        {
+            switch(lock_first)
+            {
+            case 0:
+                lock_first=detail::lock_helper(m1,m2,m3,m4,m5);
+                if(!lock_first)
+                    return;
+                break;
+            case 1:
+                lock_first=detail::lock_helper(m2,m3,m4,m5,m1);
+                if(!lock_first)
+                    return;
+                lock_first=(lock_first+1)%lock_count;
+                break;
+            case 2:
+                lock_first=detail::lock_helper(m3,m4,m5,m1,m2);
+                if(!lock_first)
+                    return;
+                lock_first=(lock_first+2)%lock_count;
+                break;
+            case 3:
+                lock_first=detail::lock_helper(m4,m5,m1,m2,m3);
+                if(!lock_first)
+                    return;
+                lock_first=(lock_first+3)%lock_count;
+                break;
+            case 4:
+                lock_first=detail::lock_helper(m5,m1,m2,m3,m4);
+                if(!lock_first)
+                    return;
+                lock_first=(lock_first+4)%lock_count;
+                break;
+            }
+        }
+    }
+
+    namespace detail
+    {
+        template<typename Mutex,bool x=is_mutex_type<Mutex>::value>
+        struct try_lock_impl_return
+        {
+            typedef int type;
+        };
+        
+        template<typename Iterator>
+        struct try_lock_impl_return<Iterator,false>
+        {
+            typedef Iterator type;
+        };
+
+        template<typename MutexType1,typename MutexType2>
+        int try_lock_impl(MutexType1& m1,MutexType2& m2,is_mutex_type_wrapper<true>)
+        {
+            return ((int)detail::try_lock_internal(m1,m2))-1;
+        }
+
+        template<typename Iterator>
+        Iterator try_lock_impl(Iterator begin,Iterator end,is_mutex_type_wrapper<false>);
+    }
+    
+    template<typename MutexType1,typename MutexType2>
+    typename detail::try_lock_impl_return<MutexType1>::type try_lock(MutexType1& m1,MutexType2& m2)
+    {
+        return detail::try_lock_impl(m1,m2,detail::is_mutex_type_wrapper<is_mutex_type<MutexType1>::value>());
+    }
+
+    template<typename MutexType1,typename MutexType2>
+    typename detail::try_lock_impl_return<MutexType1>::type try_lock(const MutexType1& m1,MutexType2& m2)
+    {
+        return detail::try_lock_impl(m1,m2,detail::is_mutex_type_wrapper<is_mutex_type<MutexType1>::value>());
+    }
+
+    template<typename MutexType1,typename MutexType2>
+    typename detail::try_lock_impl_return<MutexType1>::type try_lock(MutexType1& m1,const MutexType2& m2)
+    {
+        return detail::try_lock_impl(m1,m2,detail::is_mutex_type_wrapper<is_mutex_type<MutexType1>::value>());
+    }
+
+    template<typename MutexType1,typename MutexType2>
+    typename detail::try_lock_impl_return<MutexType1>::type try_lock(const MutexType1& m1,const MutexType2& m2)
+    {
+        return detail::try_lock_impl(m1,m2,detail::is_mutex_type_wrapper<is_mutex_type<MutexType1>::value>());
+    }
+
+    template<typename MutexType1,typename MutexType2,typename MutexType3>
+    int try_lock(MutexType1& m1,MutexType2& m2,MutexType3& m3)
+    {
+        return ((int)detail::try_lock_internal(m1,m2,m3))-1;
+    }
+
+    template<typename MutexType1,typename MutexType2,typename MutexType3,typename MutexType4>
+    int try_lock(MutexType1& m1,MutexType2& m2,MutexType3& m3,MutexType4& m4)
+    {
+        return ((int)detail::try_lock_internal(m1,m2,m3,m4))-1;
+    }
+
+    template<typename MutexType1,typename MutexType2,typename MutexType3,typename MutexType4,typename MutexType5>
+    int try_lock(MutexType1& m1,MutexType2& m2,MutexType3& m3,MutexType4& m4,MutexType5& m5)
+    {
+        return ((int)detail::try_lock_internal(m1,m2,m3,m4,m5))-1;
+    }
+    
+
+    namespace detail
+    {
+        template<typename Iterator>
+        struct range_lock_guard
+        {
+            Iterator begin;
+            Iterator end;
+            
+            range_lock_guard(Iterator begin_,Iterator end_):
+                begin(begin_),end(end_)
+            {
+                lock(begin,end);
+            }
+            
+            void release()
+            {
+                begin=end;
+            }
+
+            ~range_lock_guard()
+            {
+                for(;begin!=end;++begin)
+                {
+                    begin->unlock();
+                }
+            }
+        };
+
+        template<typename Iterator>
+        Iterator try_lock_impl(Iterator begin,Iterator end,is_mutex_type_wrapper<false>)
+
+        {
+            if(begin==end)
+            {
+                return end;
+            }
+            typedef typename std::iterator_traits<Iterator>::value_type lock_type;
+            unique_lock<lock_type> guard(*begin,try_to_lock);
+            
+            if(!guard.owns_lock())
+            {
+                return begin;
+            }
+            Iterator const failed=try_lock(++begin,end);
+            if(failed==end)
+            {
+                guard.release();
+            }
+            
+            return failed;
+        }
+    }
+    
+
+    namespace detail
+    {
+        template<typename Iterator>
+        void lock_impl(Iterator begin,Iterator end,is_mutex_type_wrapper<false>)
+        {
+            typedef typename std::iterator_traits<Iterator>::value_type lock_type;
+        
+            if(begin==end)
+            {
+                return;
+            }
+            bool start_with_begin=true;
+            Iterator second=begin;
+            ++second;
+            Iterator next=second;
+        
+            for(;;)
+            {
+                unique_lock<lock_type> begin_lock(*begin,defer_lock);
+                if(start_with_begin)
+                {
+                    begin_lock.lock();
+                    Iterator const failed_lock=try_lock(next,end);
+                    if(failed_lock==end)
+                    {
+                        begin_lock.release();
+                        return;
+                    }
+                    start_with_begin=false;
+                    next=failed_lock;
+                }
+                else
+                {
+                    detail::range_lock_guard<Iterator> guard(next,end);
+                    if(begin_lock.try_lock())
+                    {
+                        Iterator const failed_lock=try_lock(second,next);
+                        if(failed_lock==next)
+                        {
+                            begin_lock.release();
+                            guard.release();
+                            return;
+                        }
+                        start_with_begin=false;
+                        next=failed_lock;
+                    }
+                    else
+                    {
+                        start_with_begin=true;
+                        next=second;
+                    }
+                }
+            }
+        }
+        
+    }
+    
+}
+
+#include <boost/config/abi_suffix.hpp>
+
+#endif
diff --git a/deal.II/contrib/boost/include/boost/thread/mutex.hpp b/deal.II/contrib/boost/include/boost/thread/mutex.hpp
new file mode 100644 (file)
index 0000000..4669886
--- /dev/null
@@ -0,0 +1,21 @@
+#ifndef BOOST_THREAD_MUTEX_HPP
+#define BOOST_THREAD_MUTEX_HPP
+
+//  mutex.hpp
+//
+//  (C) Copyright 2007 Anthony Williams 
+//
+//  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/thread/detail/platform.hpp>
+#if defined(BOOST_THREAD_PLATFORM_WIN32)
+#include <boost/thread/win32/mutex.hpp>
+#elif defined(BOOST_THREAD_PLATFORM_PTHREAD)
+#include <boost/thread/pthread/mutex.hpp>
+#else
+#error "Boost threads unavailable on this platform"
+#endif
+
+#endif
diff --git a/deal.II/contrib/boost/include/boost/thread/once.hpp b/deal.II/contrib/boost/include/boost/thread/once.hpp
new file mode 100644 (file)
index 0000000..975304e
--- /dev/null
@@ -0,0 +1,33 @@
+#ifndef BOOST_THREAD_ONCE_HPP
+#define BOOST_THREAD_ONCE_HPP
+
+//  once.hpp
+//
+//  (C) Copyright 2006-7 Anthony Williams 
+//
+//  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/thread/detail/platform.hpp>
+#if defined(BOOST_THREAD_PLATFORM_WIN32)
+#include <boost/thread/win32/once.hpp>
+#elif defined(BOOST_THREAD_PLATFORM_PTHREAD)
+#include <boost/thread/pthread/once.hpp>
+#else
+#error "Boost threads unavailable on this platform"
+#endif
+
+#include <boost/config/abi_prefix.hpp>
+
+namespace boost
+{
+    inline void call_once(void (*func)(),once_flag& flag)
+    {
+        call_once(flag,func);
+    }
+}
+
+#include <boost/config/abi_suffix.hpp>
+
+#endif
diff --git a/deal.II/contrib/boost/include/boost/thread/pthread/condition_variable.hpp b/deal.II/contrib/boost/include/boost/thread/pthread/condition_variable.hpp
new file mode 100644 (file)
index 0000000..8ec6ae7
--- /dev/null
@@ -0,0 +1,176 @@
+#ifndef BOOST_THREAD_CONDITION_VARIABLE_PTHREAD_HPP
+#define BOOST_THREAD_CONDITION_VARIABLE_PTHREAD_HPP
+// 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)
+// (C) Copyright 2007-8 Anthony Williams
+
+#include "timespec.hpp"
+#include "pthread_mutex_scoped_lock.hpp"
+#include "thread_data.hpp"
+#include "condition_variable_fwd.hpp"
+
+#include <boost/config/abi_prefix.hpp>
+
+namespace boost
+{
+    inline void condition_variable::wait(unique_lock<mutex>& m)
+    {
+        detail::interruption_checker check_for_interruption(&cond);
+        BOOST_VERIFY(!pthread_cond_wait(&cond,m.mutex()->native_handle()));
+    }
+
+    inline bool condition_variable::timed_wait(unique_lock<mutex>& m,boost::system_time const& wait_until)
+    {
+        detail::interruption_checker check_for_interruption(&cond);
+        struct timespec const timeout=detail::get_timespec(wait_until);
+        int const cond_res=pthread_cond_timedwait(&cond,m.mutex()->native_handle(),&timeout);
+        if(cond_res==ETIMEDOUT)
+        {
+            return false;
+        }
+        BOOST_ASSERT(!cond_res);
+        return true;
+    }
+
+    inline void condition_variable::notify_one()
+    {
+        BOOST_VERIFY(!pthread_cond_signal(&cond));
+    }
+        
+    inline void condition_variable::notify_all()
+    {
+        BOOST_VERIFY(!pthread_cond_broadcast(&cond));
+    }
+    
+    class condition_variable_any
+    {
+        pthread_mutex_t internal_mutex;
+        pthread_cond_t cond;
+
+        condition_variable_any(condition_variable&);
+        condition_variable_any& operator=(condition_variable&);
+
+    public:
+        condition_variable_any()
+        {
+            int const res=pthread_mutex_init(&internal_mutex,NULL);
+            if(res)
+            {
+                throw thread_resource_error();
+            }
+            int const res2=pthread_cond_init(&cond,NULL);
+            if(res2)
+            {
+                BOOST_VERIFY(!pthread_mutex_destroy(&internal_mutex));
+                throw thread_resource_error();
+            }
+        }
+        ~condition_variable_any()
+        {
+            BOOST_VERIFY(!pthread_mutex_destroy(&internal_mutex));
+            BOOST_VERIFY(!pthread_cond_destroy(&cond));
+        }
+        
+        template<typename lock_type>
+        void wait(lock_type& m)
+        {
+            int res=0;
+            {
+                detail::interruption_checker check_for_interruption(&cond);
+                {
+                    boost::pthread::pthread_mutex_scoped_lock internal_lock(&internal_mutex);
+                    m.unlock();
+                    res=pthread_cond_wait(&cond,&internal_mutex);
+                }
+                m.lock();
+            }
+            if(res)
+            {
+                throw condition_error();
+            }
+        }
+
+        template<typename lock_type,typename predicate_type>
+        void wait(lock_type& m,predicate_type pred)
+        {
+            while(!pred()) wait(m);
+        }
+        
+        template<typename lock_type>
+        bool timed_wait(lock_type& m,boost::system_time const& wait_until)
+        {
+            struct timespec const timeout=detail::get_timespec(wait_until);
+            int res=0;
+            {
+                detail::interruption_checker check_for_interruption(&cond);
+                {
+                    boost::pthread::pthread_mutex_scoped_lock internal_lock(&internal_mutex);
+                    m.unlock();
+                    res=pthread_cond_timedwait(&cond,&internal_mutex,&timeout);
+                }
+                m.lock();
+            }
+            if(res==ETIMEDOUT)
+            {
+                return false;
+            }
+            if(res)
+            {
+                throw condition_error();
+            }
+            return true;
+        }
+        template<typename lock_type>
+        bool timed_wait(lock_type& m,xtime const& wait_until)
+        {
+            return timed_wait(m,system_time(wait_until));
+        }
+
+        template<typename lock_type,typename duration_type>
+        bool timed_wait(lock_type& m,duration_type const& wait_duration)
+        {
+            return timed_wait(m,get_system_time()+wait_duration);
+        }
+
+        template<typename lock_type,typename predicate_type>
+        bool timed_wait(lock_type& m,boost::system_time const& wait_until,predicate_type pred)
+        {
+            while (!pred())
+            {
+                if(!timed_wait(m, wait_until))
+                    return pred();
+            }
+            return true;
+        }
+
+        template<typename lock_type,typename predicate_type>
+        bool timed_wait(lock_type& m,xtime const& wait_until,predicate_type pred)
+        {
+            return timed_wait(m,system_time(wait_until),pred);
+        }
+
+        template<typename lock_type,typename duration_type,typename predicate_type>
+        bool timed_wait(lock_type& m,duration_type const& wait_duration,predicate_type pred)
+        {
+            return timed_wait(m,get_system_time()+wait_duration,pred);
+        }
+
+        void notify_one()
+        {
+            boost::pthread::pthread_mutex_scoped_lock internal_lock(&internal_mutex);
+            BOOST_VERIFY(!pthread_cond_signal(&cond));
+        }
+        
+        void notify_all()
+        {
+            boost::pthread::pthread_mutex_scoped_lock internal_lock(&internal_mutex);
+            BOOST_VERIFY(!pthread_cond_broadcast(&cond));
+        }
+    };
+
+}
+
+#include <boost/config/abi_suffix.hpp>
+
+#endif
diff --git a/deal.II/contrib/boost/include/boost/thread/pthread/condition_variable_fwd.hpp b/deal.II/contrib/boost/include/boost/thread/pthread/condition_variable_fwd.hpp
new file mode 100644 (file)
index 0000000..4048cdf
--- /dev/null
@@ -0,0 +1,97 @@
+#ifndef BOOST_THREAD_PTHREAD_CONDITION_VARIABLE_FWD_HPP
+#define BOOST_THREAD_PTHREAD_CONDITION_VARIABLE_FWD_HPP
+// 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)
+// (C) Copyright 2007-8 Anthony Williams
+
+#include <boost/assert.hpp>
+#include <pthread.h>
+#include <boost/thread/mutex.hpp>
+#include <boost/thread/locks.hpp>
+#include <boost/thread/thread_time.hpp>
+#include <boost/thread/xtime.hpp>
+
+#include <boost/config/abi_prefix.hpp>
+
+namespace boost
+{
+    class condition_variable
+    {
+    private:
+        pthread_cond_t cond;
+        
+        condition_variable(condition_variable&);
+        condition_variable& operator=(condition_variable&);
+
+    public:
+        condition_variable()
+        {
+            int const res=pthread_cond_init(&cond,NULL);
+            if(res)
+            {
+                throw thread_resource_error();
+            }
+        }
+        ~condition_variable()
+        {
+            BOOST_VERIFY(!pthread_cond_destroy(&cond));
+        }
+
+        void wait(unique_lock<mutex>& m);
+
+        template<typename predicate_type>
+        void wait(unique_lock<mutex>& m,predicate_type pred)
+        {
+            while(!pred()) wait(m);
+        }
+
+        bool timed_wait(unique_lock<mutex>& m,boost::system_time const& wait_until);
+        bool timed_wait(unique_lock<mutex>& m,xtime const& wait_until)
+        {
+            return timed_wait(m,system_time(wait_until));
+        }
+
+        template<typename duration_type>
+        bool timed_wait(unique_lock<mutex>& m,duration_type const& wait_duration)
+        {
+            return timed_wait(m,get_system_time()+wait_duration);
+        }
+
+        template<typename predicate_type>
+        bool timed_wait(unique_lock<mutex>& m,boost::system_time const& wait_until,predicate_type pred)
+        {
+            while (!pred())
+            {
+                if(!timed_wait(m, wait_until))
+                    return pred();
+            }
+            return true;
+        }
+
+        template<typename predicate_type>
+        bool timed_wait(unique_lock<mutex>& m,xtime const& wait_until,predicate_type pred)
+        {
+            return timed_wait(m,system_time(wait_until),pred);
+        }
+
+        template<typename duration_type,typename predicate_type>
+        bool timed_wait(unique_lock<mutex>& m,duration_type const& wait_duration,predicate_type pred)
+        {
+            return timed_wait(m,get_system_time()+wait_duration,pred);
+        }
+
+        typedef pthread_cond_t* native_handle_type;
+        native_handle_type native_handle()
+        {
+            return &cond;
+        }
+
+        void notify_one();
+        void notify_all();
+    };
+}
+
+#include <boost/config/abi_suffix.hpp>
+
+#endif
diff --git a/deal.II/contrib/boost/include/boost/thread/pthread/mutex.hpp b/deal.II/contrib/boost/include/boost/thread/pthread/mutex.hpp
new file mode 100644 (file)
index 0000000..51d62ae
--- /dev/null
@@ -0,0 +1,210 @@
+#ifndef BOOST_THREAD_PTHREAD_MUTEX_HPP
+#define BOOST_THREAD_PTHREAD_MUTEX_HPP
+// (C) Copyright 2007-8 Anthony Williams
+// 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 <pthread.h>
+#include <boost/utility.hpp>
+#include <boost/thread/exceptions.hpp>
+#include <boost/thread/locks.hpp>
+#include <boost/thread/thread_time.hpp>
+#include <boost/thread/xtime.hpp>
+#include <boost/assert.hpp>
+#include <errno.h>
+#include "timespec.hpp"
+#include "pthread_mutex_scoped_lock.hpp"
+
+#ifdef _POSIX_TIMEOUTS
+#if _POSIX_TIMEOUTS >= 0
+#define BOOST_PTHREAD_HAS_TIMEDLOCK
+#endif
+#endif
+
+#include <boost/config/abi_prefix.hpp>
+
+namespace boost
+{
+    class mutex:
+        boost::noncopyable
+    {
+    private:
+        pthread_mutex_t m;
+    public:
+        mutex()
+        {
+            int const res=pthread_mutex_init(&m,NULL);
+            if(res)
+            {
+                throw thread_resource_error();
+            }
+        }
+        ~mutex()
+        {
+            BOOST_VERIFY(!pthread_mutex_destroy(&m));
+        }
+        
+        void lock()
+        {
+            BOOST_VERIFY(!pthread_mutex_lock(&m));
+        }
+
+        void unlock()
+        {
+            BOOST_VERIFY(!pthread_mutex_unlock(&m));
+        }
+        
+        bool try_lock()
+        {
+            int const res=pthread_mutex_trylock(&m);
+            BOOST_ASSERT(!res || res==EBUSY);
+            return !res;
+        }
+
+        typedef pthread_mutex_t* native_handle_type;
+        native_handle_type native_handle()
+        {
+            return &m;
+        }
+
+        typedef unique_lock<mutex> scoped_lock;
+        typedef detail::try_lock_wrapper<mutex> scoped_try_lock;
+    };
+
+    typedef mutex try_mutex;
+
+    class timed_mutex:
+        boost::noncopyable
+    {
+    private:
+        pthread_mutex_t m;
+#ifndef BOOST_PTHREAD_HAS_TIMEDLOCK
+        pthread_cond_t cond;
+        bool is_locked;
+#endif
+    public:
+        timed_mutex()
+        {
+            int const res=pthread_mutex_init(&m,NULL);
+            if(res)
+            {
+                throw thread_resource_error();
+            }
+#ifndef BOOST_PTHREAD_HAS_TIMEDLOCK
+            int const res2=pthread_cond_init(&cond,NULL);
+            if(res2)
+            {
+                BOOST_VERIFY(!pthread_mutex_destroy(&m));
+                throw thread_resource_error();
+            }
+            is_locked=false;
+#endif
+        }
+        ~timed_mutex()
+        {
+            BOOST_VERIFY(!pthread_mutex_destroy(&m));
+#ifndef BOOST_PTHREAD_HAS_TIMEDLOCK
+            BOOST_VERIFY(!pthread_cond_destroy(&cond));
+#endif
+        }
+
+        template<typename TimeDuration>
+        bool timed_lock(TimeDuration const & relative_time)
+        {
+            return timed_lock(get_system_time()+relative_time);
+        }
+        bool timed_lock(boost::xtime const & absolute_time)
+        {
+            return timed_lock(system_time(absolute_time));
+        }
+
+#ifdef BOOST_PTHREAD_HAS_TIMEDLOCK
+        void lock()
+        {
+            BOOST_VERIFY(!pthread_mutex_lock(&m));
+        }
+
+        void unlock()
+        {
+            BOOST_VERIFY(!pthread_mutex_unlock(&m));
+        }
+        
+        bool try_lock()
+        {
+            int const res=pthread_mutex_trylock(&m);
+            BOOST_ASSERT(!res || res==EBUSY);
+            return !res;
+        }
+        bool timed_lock(system_time const & abs_time)
+        {
+            struct timespec const timeout=detail::get_timespec(abs_time);
+            int const res=pthread_mutex_timedlock(&m,&timeout);
+            BOOST_ASSERT(!res || res==ETIMEDOUT);
+            return !res;
+        }
+
+        typedef pthread_mutex_t* native_handle_type;
+        native_handle_type native_handle()
+        {
+            return &m;
+        }
+
+#else
+        void lock()
+        {
+            boost::pthread::pthread_mutex_scoped_lock const local_lock(&m);
+            while(is_locked)
+            {
+                BOOST_VERIFY(!pthread_cond_wait(&cond,&m));
+            }
+            is_locked=true;
+        }
+
+        void unlock()
+        {
+            boost::pthread::pthread_mutex_scoped_lock const local_lock(&m);
+            is_locked=false;
+            BOOST_VERIFY(!pthread_cond_signal(&cond));
+        }
+        
+        bool try_lock()
+        {
+            boost::pthread::pthread_mutex_scoped_lock const local_lock(&m);
+            if(is_locked)
+            {
+                return false;
+            }
+            is_locked=true;
+            return true;
+        }
+
+        bool timed_lock(system_time const & abs_time)
+        {
+            struct timespec const timeout=detail::get_timespec(abs_time);
+            boost::pthread::pthread_mutex_scoped_lock const local_lock(&m);
+            while(is_locked)
+            {
+                int const cond_res=pthread_cond_timedwait(&cond,&m,&timeout);
+                if(cond_res==ETIMEDOUT)
+                {
+                    return false;
+                }
+                BOOST_ASSERT(!cond_res);
+            }
+            is_locked=true;
+            return true;
+        }
+#endif
+
+        typedef unique_lock<timed_mutex> scoped_timed_lock;
+        typedef detail::try_lock_wrapper<timed_mutex> scoped_try_lock;
+        typedef scoped_timed_lock scoped_lock;
+    };
+
+}
+
+#include <boost/config/abi_suffix.hpp>
+
+
+#endif
diff --git a/deal.II/contrib/boost/include/boost/thread/pthread/once.hpp b/deal.II/contrib/boost/include/boost/thread/pthread/once.hpp
new file mode 100644 (file)
index 0000000..f278a57
--- /dev/null
@@ -0,0 +1,90 @@
+#ifndef BOOST_THREAD_PTHREAD_ONCE_HPP
+#define BOOST_THREAD_PTHREAD_ONCE_HPP
+
+//  once.hpp
+//
+//  (C) Copyright 2007-8 Anthony Williams 
+//
+//  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/thread/detail/config.hpp>
+
+#include <pthread.h>
+#include <boost/assert.hpp>
+#include "pthread_mutex_scoped_lock.hpp"
+#include <boost/thread/pthread/pthread_mutex_scoped_lock.hpp>
+#include <boost/cstdint.hpp>
+
+#include <boost/config/abi_prefix.hpp>
+
+namespace boost
+{
+
+    struct once_flag
+    {
+        boost::uintmax_t epoch;
+    };
+
+    namespace detail
+    {
+        BOOST_THREAD_DECL boost::uintmax_t& get_once_per_thread_epoch();
+        BOOST_THREAD_DECL extern boost::uintmax_t once_global_epoch;
+        BOOST_THREAD_DECL extern pthread_mutex_t once_epoch_mutex;
+        BOOST_THREAD_DECL extern pthread_cond_t once_epoch_cv;
+    }
+    
+#define BOOST_ONCE_INITIAL_FLAG_VALUE 0
+#define BOOST_ONCE_INIT {BOOST_ONCE_INITIAL_FLAG_VALUE}
+
+
+    // Based on Mike Burrows fast_pthread_once algorithm as described in
+    // http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2444.html
+    template<typename Function>
+    void call_once(once_flag& flag,Function f)
+    {
+        static boost::uintmax_t const uninitialized_flag=BOOST_ONCE_INITIAL_FLAG_VALUE;
+        static boost::uintmax_t const being_initialized=uninitialized_flag+1;
+        boost::uintmax_t const epoch=flag.epoch;
+        boost::uintmax_t& this_thread_epoch=detail::get_once_per_thread_epoch();
+        
+        if(epoch<this_thread_epoch)
+        {
+            pthread::pthread_mutex_scoped_lock lk(&detail::once_epoch_mutex);
+
+            while(flag.epoch<=being_initialized)
+            {
+                if(flag.epoch==uninitialized_flag)
+                {
+                    flag.epoch=being_initialized;
+                    try
+                    {
+                        pthread::pthread_mutex_scoped_unlock relocker(&detail::once_epoch_mutex);
+                        f();
+                    }
+                    catch(...)
+                    {
+                        flag.epoch=uninitialized_flag;
+                        BOOST_VERIFY(!pthread_cond_broadcast(&detail::once_epoch_cv));
+                        throw;
+                    }
+                    flag.epoch=--detail::once_global_epoch;
+                    BOOST_VERIFY(!pthread_cond_broadcast(&detail::once_epoch_cv));
+                }
+                else
+                {
+                    while(flag.epoch==being_initialized)
+                    {
+                        BOOST_VERIFY(!pthread_cond_wait(&detail::once_epoch_cv,&detail::once_epoch_mutex));
+                    }
+                }
+            }
+            this_thread_epoch=detail::once_global_epoch;
+        }
+    }
+}
+
+#include <boost/config/abi_suffix.hpp>
+
+#endif
diff --git a/deal.II/contrib/boost/include/boost/thread/pthread/pthread_mutex_scoped_lock.hpp b/deal.II/contrib/boost/include/boost/thread/pthread/pthread_mutex_scoped_lock.hpp
new file mode 100644 (file)
index 0000000..2407f91
--- /dev/null
@@ -0,0 +1,54 @@
+#ifndef BOOST_PTHREAD_MUTEX_SCOPED_LOCK_HPP
+#define BOOST_PTHREAD_MUTEX_SCOPED_LOCK_HPP
+//  (C) Copyright 2007-8 Anthony Williams 
+//
+//  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 <pthread.h>
+#include <boost/assert.hpp>
+
+#include <boost/config/abi_prefix.hpp>
+
+namespace boost
+{
+    namespace pthread
+    {
+        class pthread_mutex_scoped_lock
+        {
+            pthread_mutex_t* m;
+        public:
+            explicit pthread_mutex_scoped_lock(pthread_mutex_t* m_):
+                m(m_)
+            {
+                BOOST_VERIFY(!pthread_mutex_lock(m));
+            }
+            ~pthread_mutex_scoped_lock()
+            {
+                BOOST_VERIFY(!pthread_mutex_unlock(m));
+            }
+            
+        };
+
+        class pthread_mutex_scoped_unlock
+        {
+            pthread_mutex_t* m;
+        public:
+            explicit pthread_mutex_scoped_unlock(pthread_mutex_t* m_):
+                m(m_)
+            {
+                BOOST_VERIFY(!pthread_mutex_unlock(m));
+            }
+            ~pthread_mutex_scoped_unlock()
+            {
+                BOOST_VERIFY(!pthread_mutex_lock(m));
+            }
+            
+        };
+    }
+}
+
+#include <boost/config/abi_suffix.hpp>
+
+#endif
diff --git a/deal.II/contrib/boost/include/boost/thread/pthread/recursive_mutex.hpp b/deal.II/contrib/boost/include/boost/thread/pthread/recursive_mutex.hpp
new file mode 100644 (file)
index 0000000..f3f7bf1
--- /dev/null
@@ -0,0 +1,266 @@
+#ifndef BOOST_THREAD_PTHREAD_RECURSIVE_MUTEX_HPP
+#define BOOST_THREAD_PTHREAD_RECURSIVE_MUTEX_HPP
+// (C) Copyright 2007-8 Anthony Williams
+// 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 <pthread.h>
+#include <boost/utility.hpp>
+#include <boost/thread/exceptions.hpp>
+#include <boost/thread/locks.hpp>
+#include <boost/thread/thread_time.hpp>
+#include <boost/assert.hpp>
+#ifndef _WIN32
+#include <unistd.h>
+#endif
+#include <boost/date_time/posix_time/conversion.hpp>
+#include <errno.h>
+#include "timespec.hpp"
+#include "pthread_mutex_scoped_lock.hpp"
+
+#ifdef _POSIX_TIMEOUTS
+#if _POSIX_TIMEOUTS >= 0
+#define BOOST_PTHREAD_HAS_TIMEDLOCK
+#endif
+#endif
+
+#include <boost/config/abi_prefix.hpp>
+
+namespace boost
+{
+    class recursive_mutex:
+        boost::noncopyable
+    {
+    private:
+        pthread_mutex_t m;
+    public:
+        recursive_mutex()
+        {
+            pthread_mutexattr_t attr;
+            
+            int const init_attr_res=pthread_mutexattr_init(&attr);
+            if(init_attr_res)
+            {
+                throw thread_resource_error();
+            }
+            int const set_attr_res=pthread_mutexattr_settype(&attr,PTHREAD_MUTEX_RECURSIVE);
+            if(set_attr_res)
+            {
+                throw thread_resource_error();
+            }
+            
+            int const res=pthread_mutex_init(&m,&attr);
+            if(res)
+            {
+                throw thread_resource_error();
+            }
+            BOOST_VERIFY(!pthread_mutexattr_destroy(&attr));
+        }
+        ~recursive_mutex()
+        {
+            BOOST_VERIFY(!pthread_mutex_destroy(&m));
+        }
+        
+        void lock()
+        {
+            BOOST_VERIFY(!pthread_mutex_lock(&m));
+        }
+
+        void unlock()
+        {
+            BOOST_VERIFY(!pthread_mutex_unlock(&m));
+        }
+        
+        bool try_lock()
+        {
+            int const res=pthread_mutex_trylock(&m);
+            BOOST_ASSERT(!res || res==EBUSY);
+            return !res;
+        }
+
+        typedef pthread_mutex_t* native_handle_type;
+        native_handle_type native_handle()
+        {
+            return &m;
+        }
+
+        typedef unique_lock<recursive_mutex> scoped_lock;
+        typedef detail::try_lock_wrapper<recursive_mutex> scoped_try_lock;
+    };
+
+    typedef recursive_mutex recursive_try_mutex;
+
+    class recursive_timed_mutex:
+        boost::noncopyable
+    {
+    private:
+        pthread_mutex_t m;
+#ifndef BOOST_PTHREAD_HAS_TIMEDLOCK
+        pthread_cond_t cond;
+        bool is_locked;
+        pthread_t owner;
+        unsigned count;
+#endif
+    public:
+        recursive_timed_mutex()
+        {
+#ifdef BOOST_PTHREAD_HAS_TIMEDLOCK
+            pthread_mutexattr_t attr;
+            
+            int const init_attr_res=pthread_mutexattr_init(&attr);
+            if(init_attr_res)
+            {
+                throw thread_resource_error();
+            }
+            int const set_attr_res=pthread_mutexattr_settype(&attr,PTHREAD_MUTEX_RECURSIVE);
+            if(set_attr_res)
+            {
+                throw thread_resource_error();
+            }
+            
+            int const res=pthread_mutex_init(&m,&attr);
+            if(res)
+            {
+                BOOST_VERIFY(!pthread_mutexattr_destroy(&attr));
+                throw thread_resource_error();
+            }
+            BOOST_VERIFY(!pthread_mutexattr_destroy(&attr));
+#else
+            int const res=pthread_mutex_init(&m,NULL);
+            if(res)
+            {
+                throw thread_resource_error();
+            }
+            int const res2=pthread_cond_init(&cond,NULL);
+            if(res2)
+            {
+                BOOST_VERIFY(!pthread_mutex_destroy(&m));
+                throw thread_resource_error();
+            }
+            is_locked=false;
+            count=0;
+#endif
+        }
+        ~recursive_timed_mutex()
+        {
+            BOOST_VERIFY(!pthread_mutex_destroy(&m));
+#ifndef BOOST_PTHREAD_HAS_TIMEDLOCK
+            BOOST_VERIFY(!pthread_cond_destroy(&cond));
+#endif
+        }
+
+        template<typename TimeDuration>
+        bool timed_lock(TimeDuration const & relative_time)
+        {
+            return timed_lock(get_system_time()+relative_time);
+        }
+
+#ifdef BOOST_PTHREAD_HAS_TIMEDLOCK
+        void lock()
+        {
+            BOOST_VERIFY(!pthread_mutex_lock(&m));
+        }
+
+        void unlock()
+        {
+            BOOST_VERIFY(!pthread_mutex_unlock(&m));
+        }
+        
+        bool try_lock()
+        {
+            int const res=pthread_mutex_trylock(&m);
+            BOOST_ASSERT(!res || res==EBUSY);
+            return !res;
+        }
+        bool timed_lock(system_time const & abs_time)
+        {
+            struct timespec const timeout=detail::get_timespec(abs_time);
+            int const res=pthread_mutex_timedlock(&m,&timeout);
+            BOOST_ASSERT(!res || res==ETIMEDOUT);
+            return !res;
+        }
+
+        typedef pthread_mutex_t* native_handle_type;
+        native_handle_type native_handle()
+        {
+            return &m;
+        }
+
+#else
+        void lock()
+        {
+            boost::pthread::pthread_mutex_scoped_lock const local_lock(&m);
+            if(is_locked && pthread_equal(owner,pthread_self()))
+            {
+                ++count;
+                return;
+            }
+            
+            while(is_locked)
+            {
+                BOOST_VERIFY(!pthread_cond_wait(&cond,&m));
+            }
+            is_locked=true;
+            ++count;
+            owner=pthread_self();
+        }
+
+        void unlock()
+        {
+            boost::pthread::pthread_mutex_scoped_lock const local_lock(&m);
+            if(!--count)
+            {
+                is_locked=false;
+            }
+            BOOST_VERIFY(!pthread_cond_signal(&cond));
+        }
+        
+        bool try_lock()
+        {
+            boost::pthread::pthread_mutex_scoped_lock const local_lock(&m);
+            if(is_locked && !pthread_equal(owner,pthread_self()))
+            {
+                return false;
+            }
+            is_locked=true;
+            ++count;
+            owner=pthread_self();
+            return true;
+        }
+
+        bool timed_lock(system_time const & abs_time)
+        {
+            struct timespec const timeout=detail::get_timespec(abs_time);
+            boost::pthread::pthread_mutex_scoped_lock const local_lock(&m);
+            if(is_locked && pthread_equal(owner,pthread_self()))
+            {
+                ++count;
+                return true;
+            }
+            while(is_locked)
+            {
+                int const cond_res=pthread_cond_timedwait(&cond,&m,&timeout);
+                if(cond_res==ETIMEDOUT)
+                {
+                    return false;
+                }
+                BOOST_ASSERT(!cond_res);
+            }
+            is_locked=true;
+            ++count;
+            owner=pthread_self();
+            return true;
+        }
+#endif
+
+        typedef unique_lock<recursive_timed_mutex> scoped_timed_lock;
+        typedef detail::try_lock_wrapper<recursive_timed_mutex> scoped_try_lock;
+        typedef scoped_timed_lock scoped_lock;
+    };
+
+}
+
+#include <boost/config/abi_suffix.hpp>
+
+#endif
diff --git a/deal.II/contrib/boost/include/boost/thread/pthread/shared_mutex.hpp b/deal.II/contrib/boost/include/boost/thread/pthread/shared_mutex.hpp
new file mode 100644 (file)
index 0000000..3ce4e23
--- /dev/null
@@ -0,0 +1,303 @@
+#ifndef BOOST_THREAD_PTHREAD_SHARED_MUTEX_HPP
+#define BOOST_THREAD_PTHREAD_SHARED_MUTEX_HPP
+
+//  (C) Copyright 2006-8 Anthony Williams
+//
+//  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/assert.hpp>
+#include <boost/static_assert.hpp>
+#include <boost/thread/mutex.hpp>
+#include <boost/thread/thread.hpp>
+#include <boost/thread/condition_variable.hpp>
+
+#include <boost/config/abi_prefix.hpp>
+
+namespace boost
+{
+    class shared_mutex
+    {
+    private:
+        struct state_data
+        {
+            unsigned shared_count;
+            bool exclusive;
+            bool upgrade;
+            bool exclusive_waiting_blocked;
+        };
+        
+
+
+        state_data state;
+        boost::mutex state_change;
+        boost::condition_variable shared_cond;
+        boost::condition_variable exclusive_cond;
+        boost::condition_variable upgrade_cond;
+
+        void release_waiters()
+        {
+            exclusive_cond.notify_one();
+            shared_cond.notify_all();
+        }
+        
+
+    public:
+        shared_mutex()
+        {
+            state_data state_={0,0,0,0};
+            state=state_;
+        }
+
+        ~shared_mutex()
+        {
+        }
+
+        void lock_shared()
+        {
+            boost::this_thread::disable_interruption do_not_disturb;
+            boost::mutex::scoped_lock lk(state_change);
+                
+            while(state.exclusive || state.exclusive_waiting_blocked)
+            {
+                shared_cond.wait(lk);
+            }
+            ++state.shared_count;
+        }
+
+        bool try_lock_shared()
+        {
+            boost::mutex::scoped_lock lk(state_change);
+                
+            if(state.exclusive || state.exclusive_waiting_blocked)
+            {
+                return false;
+            }
+            else
+            {
+                ++state.shared_count;
+                return true;
+            }
+        }
+
+        bool timed_lock_shared(system_time const& timeout)
+        {
+            boost::this_thread::disable_interruption do_not_disturb;
+            boost::mutex::scoped_lock lk(state_change);
+                
+            while(state.exclusive || state.exclusive_waiting_blocked)
+            {
+                if(!shared_cond.timed_wait(lk,timeout))
+                {
+                    return false;
+                }
+            }
+            ++state.shared_count;
+            return true;
+        }
+
+        template<typename TimeDuration>
+        bool timed_lock_shared(TimeDuration const & relative_time)
+        {
+            return timed_lock_shared(get_system_time()+relative_time);
+        }
+
+        void unlock_shared()
+        {
+            boost::mutex::scoped_lock lk(state_change);
+            bool const last_reader=!--state.shared_count;
+                
+            if(last_reader)
+            {
+                if(state.upgrade)
+                {
+                    state.upgrade=false;
+                    state.exclusive=true;
+                    upgrade_cond.notify_one();
+                }
+                else
+                {
+                    state.exclusive_waiting_blocked=false;
+                }
+                release_waiters();
+            }
+        }
+
+        void lock()
+        {
+            boost::this_thread::disable_interruption do_not_disturb;
+            boost::mutex::scoped_lock lk(state_change);
+                
+            while(state.shared_count || state.exclusive)
+            {
+                state.exclusive_waiting_blocked=true;
+                exclusive_cond.wait(lk);
+            }
+            state.exclusive=true;
+        }
+
+        bool timed_lock(system_time const& timeout)
+        {
+            boost::this_thread::disable_interruption do_not_disturb;
+            boost::mutex::scoped_lock lk(state_change);
+
+            while(state.shared_count || state.exclusive)
+            {
+                state.exclusive_waiting_blocked=true;
+                if(!exclusive_cond.timed_wait(lk,timeout))
+                {
+                    if(state.shared_count || state.exclusive)
+                    {
+                        state.exclusive_waiting_blocked=false;
+                        exclusive_cond.notify_one();
+                        return false;
+                    }
+                    break;
+                }
+            }
+            state.exclusive=true;
+            return true;
+        }
+
+        template<typename TimeDuration>
+        bool timed_lock(TimeDuration const & relative_time)
+        {
+            return timed_lock(get_system_time()+relative_time);
+        }
+
+        bool try_lock()
+        {
+            boost::mutex::scoped_lock lk(state_change);
+                
+            if(state.shared_count || state.exclusive)
+            {
+                return false;
+            }
+            else
+            {
+                state.exclusive=true;
+                return true;
+            }
+                
+        }
+
+        void unlock()
+        {
+            boost::mutex::scoped_lock lk(state_change);
+            state.exclusive=false;
+            state.exclusive_waiting_blocked=false;
+            release_waiters();
+        }
+
+        void lock_upgrade()
+        {
+            boost::this_thread::disable_interruption do_not_disturb;
+            boost::mutex::scoped_lock lk(state_change);
+            while(state.exclusive || state.exclusive_waiting_blocked || state.upgrade)
+            {
+                shared_cond.wait(lk);
+            }
+            ++state.shared_count;
+            state.upgrade=true;
+        }
+
+        bool timed_lock_upgrade(system_time const& timeout)
+        {
+            boost::this_thread::disable_interruption do_not_disturb;
+            boost::mutex::scoped_lock lk(state_change);
+            while(state.exclusive || state.exclusive_waiting_blocked || state.upgrade)
+            {
+                if(!shared_cond.timed_wait(lk,timeout))
+                {
+                    if(state.exclusive || state.exclusive_waiting_blocked || state.upgrade)
+                    {
+                        return false;
+                    }
+                    break;
+                }
+            }
+            ++state.shared_count;
+            state.upgrade=true;
+            return true;
+        }
+
+        template<typename TimeDuration>
+        bool timed_lock_upgrade(TimeDuration const & relative_time)
+        {
+            return timed_lock(get_system_time()+relative_time);
+        }
+
+        bool try_lock_upgrade()
+        {
+            boost::mutex::scoped_lock lk(state_change);
+            if(state.exclusive || state.exclusive_waiting_blocked || state.upgrade)
+            {
+                return false;
+            }
+            else
+            {
+                ++state.shared_count;
+                state.upgrade=true;
+                return true;
+            }
+        }
+
+        void unlock_upgrade()
+        {
+            boost::mutex::scoped_lock lk(state_change);
+            state.upgrade=false;
+            bool const last_reader=!--state.shared_count;
+                
+            if(last_reader)
+            {
+                state.exclusive_waiting_blocked=false;
+                release_waiters();
+            }
+        }
+
+        void unlock_upgrade_and_lock()
+        {
+            boost::this_thread::disable_interruption do_not_disturb;
+            boost::mutex::scoped_lock lk(state_change);
+            --state.shared_count;
+            while(state.shared_count)
+            {
+                upgrade_cond.wait(lk);
+            }
+            state.upgrade=false;
+            state.exclusive=true;
+        }
+
+        void unlock_and_lock_upgrade()
+        {
+            boost::mutex::scoped_lock lk(state_change);
+            state.exclusive=false;
+            state.upgrade=true;
+            ++state.shared_count;
+            state.exclusive_waiting_blocked=false;
+            release_waiters();
+        }
+        
+        void unlock_and_lock_shared()
+        {
+            boost::mutex::scoped_lock lk(state_change);
+            state.exclusive=false;
+            ++state.shared_count;
+            state.exclusive_waiting_blocked=false;
+            release_waiters();
+        }
+        
+        void unlock_upgrade_and_lock_shared()
+        {
+            boost::mutex::scoped_lock lk(state_change);
+            state.upgrade=false;
+            state.exclusive_waiting_blocked=false;
+            release_waiters();
+        }
+    };
+}
+
+#include <boost/config/abi_suffix.hpp>
+
+#endif
diff --git a/deal.II/contrib/boost/include/boost/thread/pthread/thread_data.hpp b/deal.II/contrib/boost/include/boost/thread/pthread/thread_data.hpp
new file mode 100644 (file)
index 0000000..244035b
--- /dev/null
@@ -0,0 +1,118 @@
+#ifndef BOOST_THREAD_PTHREAD_THREAD_DATA_HPP
+#define BOOST_THREAD_PTHREAD_THREAD_DATA_HPP
+// 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)
+// (C) Copyright 2007 Anthony Williams
+
+#include <boost/thread/detail/config.hpp>
+#include <boost/thread/exceptions.hpp>
+#include <boost/shared_ptr.hpp>
+#include <boost/enable_shared_from_this.hpp>
+#include <boost/thread/mutex.hpp>
+#include <boost/optional.hpp>
+#include <pthread.h>
+#include "condition_variable_fwd.hpp"
+
+#include <boost/config/abi_prefix.hpp>
+
+namespace boost
+{
+    class thread;
+    
+    namespace detail
+    {
+        struct thread_exit_callback_node;
+        struct tss_data_node;
+
+        struct thread_data_base;
+        typedef boost::shared_ptr<thread_data_base> thread_data_ptr;
+        
+        struct BOOST_THREAD_DECL thread_data_base:
+            enable_shared_from_this<thread_data_base>
+        {
+            thread_data_ptr self;
+            pthread_t thread_handle;
+            boost::mutex data_mutex;
+            boost::condition_variable done_condition;
+            boost::mutex sleep_mutex;
+            boost::condition_variable sleep_condition;
+            bool done;
+            bool join_started;
+            bool joined;
+            boost::detail::thread_exit_callback_node* thread_exit_callbacks;
+            boost::detail::tss_data_node* tss_data;
+            bool interrupt_enabled;
+            bool interrupt_requested;
+            pthread_cond_t* current_cond;
+
+            thread_data_base():
+                done(false),join_started(false),joined(false),
+                thread_exit_callbacks(0),tss_data(0),
+                interrupt_enabled(true),
+                interrupt_requested(false),
+                current_cond(0)
+            {}
+            virtual ~thread_data_base();
+
+            typedef pthread_t native_handle_type;
+
+            virtual void run()=0;
+        };
+
+        BOOST_THREAD_DECL thread_data_base* get_current_thread_data();
+
+        class interruption_checker
+        {
+            thread_data_base* const thread_info;
+
+            void check_for_interruption()
+            {
+                if(thread_info->interrupt_requested)
+                {
+                    thread_info->interrupt_requested=false;
+                    throw thread_interrupted();
+                }
+            }
+            
+            void operator=(interruption_checker&);
+        public:
+            explicit interruption_checker(pthread_cond_t* cond):
+                thread_info(detail::get_current_thread_data())
+            {
+                if(thread_info && thread_info->interrupt_enabled)
+                {
+                    lock_guard<mutex> guard(thread_info->data_mutex);
+                    check_for_interruption();
+                    thread_info->current_cond=cond;
+                }
+            }
+            ~interruption_checker()
+            {
+                if(thread_info && thread_info->interrupt_enabled)
+                {
+                    lock_guard<mutex> guard(thread_info->data_mutex);
+                    thread_info->current_cond=NULL;
+                    check_for_interruption();
+                }
+            }
+        };
+    }
+
+    namespace this_thread
+    {
+        void BOOST_THREAD_DECL yield();
+        
+        void BOOST_THREAD_DECL sleep(system_time const& abs_time);
+        
+        template<typename TimeDuration>
+        inline void sleep(TimeDuration const& rel_time)
+        {
+            this_thread::sleep(get_system_time()+rel_time);
+        }
+    }
+}
+
+#include <boost/config/abi_suffix.hpp>
+
+#endif
diff --git a/deal.II/contrib/boost/include/boost/thread/pthread/thread_heap_alloc.hpp b/deal.II/contrib/boost/include/boost/thread/pthread/thread_heap_alloc.hpp
new file mode 100644 (file)
index 0000000..7cc0aa0
--- /dev/null
@@ -0,0 +1,242 @@
+// 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)
+// (C) Copyright 2008 Anthony Williams
+#ifndef THREAD_HEAP_ALLOC_PTHREAD_HPP
+#define THREAD_HEAP_ALLOC_PTHREAD_HPP
+
+#include <boost/config/abi_prefix.hpp>
+
+namespace boost
+{
+    namespace detail
+    {
+        template<typename T>
+        inline T* heap_new()
+        {
+            return new T();
+        }
+
+#ifdef BOOST_HAS_RVALUE_REFS
+        template<typename T,typename A1>
+        inline T* heap_new(A1&& a1)
+        {
+            return new T(static_cast<A1&&>(a1));
+        }
+        template<typename T,typename A1,typename A2>
+        inline T* heap_new(A1&& a1,A2&& a2)
+        {
+            return new T(static_cast<A1&&>(a1),static_cast<A2&&>(a2));
+        }
+        template<typename T,typename A1,typename A2,typename A3>
+        inline T* heap_new(A1&& a1,A2&& a2,A3&& a3)
+        {
+            return new T(static_cast<A1&&>(a1),static_cast<A2&&>(a2),
+                         static_cast<A3&&>(a3));
+        }
+        template<typename T,typename A1,typename A2,typename A3,typename A4>
+        inline T* heap_new(A1&& a1,A2&& a2,A3&& a3,A4&& a4)
+        {
+            return new T(static_cast<A1&&>(a1),static_cast<A2&&>(a2),
+                         static_cast<A3&&>(a3),static_cast<A4&&>(a4));
+        }
+#else
+        template<typename T,typename A1>
+        inline T* heap_new_impl(A1 a1)
+        {
+            return new T(a1);
+        }
+        template<typename T,typename A1,typename A2>
+        inline T* heap_new_impl(A1 a1,A2 a2)
+        {
+            return new T(a1,a2);
+        }
+        template<typename T,typename A1,typename A2,typename A3>
+        inline T* heap_new_impl(A1 a1,A2 a2,A3 a3)
+        {
+            return new T(a1,a2,a3);
+        }
+        template<typename T,typename A1,typename A2,typename A3,typename A4>
+        inline T* heap_new_impl(A1 a1,A2 a2,A3 a3,A4 a4)
+        {
+            return new T(a1,a2,a3,a4);
+        }
+
+        template<typename T,typename A1>
+        inline T* heap_new(A1 const& a1)
+        {
+            return heap_new_impl<T,A1 const&>(a1);
+        }
+        template<typename T,typename A1>
+        inline T* heap_new(A1& a1)
+        {
+            return heap_new_impl<T,A1&>(a1);
+        }
+        
+        template<typename T,typename A1,typename A2>
+        inline T* heap_new(A1 const& a1,A2 const& a2)
+        {
+            return heap_new_impl<T,A1 const&,A2 const&>(a1,a2);
+        }
+        template<typename T,typename A1,typename A2>
+        inline T* heap_new(A1& a1,A2 const& a2)
+        {
+            return heap_new_impl<T,A1&,A2 const&>(a1,a2);
+        }
+        template<typename T,typename A1,typename A2>
+        inline T* heap_new(A1 const& a1,A2& a2)
+        {
+            return heap_new_impl<T,A1 const&,A2&>(a1,a2);
+        }
+        template<typename T,typename A1,typename A2>
+        inline T* heap_new(A1& a1,A2& a2)
+        {
+            return heap_new_impl<T,A1&,A2&>(a1,a2);
+        }
+
+        template<typename T,typename A1,typename A2,typename A3>
+        inline T* heap_new(A1 const& a1,A2 const& a2,A3 const& a3)
+        {
+            return heap_new_impl<T,A1 const&,A2 const&,A3 const&>(a1,a2,a3);
+        }
+        template<typename T,typename A1,typename A2,typename A3>
+        inline T* heap_new(A1& a1,A2 const& a2,A3 const& a3)
+        {
+            return heap_new_impl<T,A1&,A2 const&,A3 const&>(a1,a2,a3);
+        }
+        template<typename T,typename A1,typename A2,typename A3>
+        inline T* heap_new(A1 const& a1,A2& a2,A3 const& a3)
+        {
+            return heap_new_impl<T,A1 const&,A2&,A3 const&>(a1,a2,a3);
+        }
+        template<typename T,typename A1,typename A2,typename A3>
+        inline T* heap_new(A1& a1,A2& a2,A3 const& a3)
+        {
+            return heap_new_impl<T,A1&,A2&,A3 const&>(a1,a2,a3);
+        }
+
+        template<typename T,typename A1,typename A2,typename A3>
+        inline T* heap_new(A1 const& a1,A2 const& a2,A3& a3)
+        {
+            return heap_new_impl<T,A1 const&,A2 const&,A3&>(a1,a2,a3);
+        }
+        template<typename T,typename A1,typename A2,typename A3>
+        inline T* heap_new(A1& a1,A2 const& a2,A3& a3)
+        {
+            return heap_new_impl<T,A1&,A2 const&,A3&>(a1,a2,a3);
+        }
+        template<typename T,typename A1,typename A2,typename A3>
+        inline T* heap_new(A1 const& a1,A2& a2,A3& a3)
+        {
+            return heap_new_impl<T,A1 const&,A2&,A3&>(a1,a2,a3);
+        }
+        template<typename T,typename A1,typename A2,typename A3>
+        inline T* heap_new(A1& a1,A2& a2,A3& a3)
+        {
+            return heap_new_impl<T,A1&,A2&,A3&>(a1,a2,a3);
+        }
+
+        template<typename T,typename A1,typename A2,typename A3,typename A4>
+        inline T* heap_new(A1 const& a1,A2 const& a2,A3 const& a3,A4 const& a4)
+        {
+            return heap_new_impl<T,A1 const&,A2 const&,A3 const&,A4 const&>(a1,a2,a3,a4);
+        }
+        template<typename T,typename A1,typename A2,typename A3,typename A4>
+        inline T* heap_new(A1& a1,A2 const& a2,A3 const& a3,A4 const& a4)
+        {
+            return heap_new_impl<T,A1&,A2 const&,A3 const&,A4 const&>(a1,a2,a3,a4);
+        }
+        template<typename T,typename A1,typename A2,typename A3,typename A4>
+        inline T* heap_new(A1 const& a1,A2& a2,A3 const& a3,A4 const& a4)
+        {
+            return heap_new_impl<T,A1 const&,A2&,A3 const&,A4 const&>(a1,a2,a3,a4);
+        }
+        template<typename T,typename A1,typename A2,typename A3,typename A4>
+        inline T* heap_new(A1& a1,A2& a2,A3 const& a3,A4 const& a4)
+        {
+            return heap_new_impl<T,A1&,A2&,A3 const&,A4 const&>(a1,a2,a3,a4);
+        }
+
+        template<typename T,typename A1,typename A2,typename A3,typename A4>
+        inline T* heap_new(A1 const& a1,A2 const& a2,A3& a3,A4 const& a4)
+        {
+            return heap_new_impl<T,A1 const&,A2 const&,A3&,A4 const&>(a1,a2,a3,a4);
+        }
+        template<typename T,typename A1,typename A2,typename A3,typename A4>
+        inline T* heap_new(A1& a1,A2 const& a2,A3& a3,A4 const& a4)
+        {
+            return heap_new_impl<T,A1&,A2 const&,A3&,A4 const&>(a1,a2,a3,a4);
+        }
+        template<typename T,typename A1,typename A2,typename A3,typename A4>
+        inline T* heap_new(A1 const& a1,A2& a2,A3& a3,A4 const& a4)
+        {
+            return heap_new_impl<T,A1 const&,A2&,A3&,A4 const&>(a1,a2,a3,a4);
+        }
+        template<typename T,typename A1,typename A2,typename A3,typename A4>
+        inline T* heap_new(A1& a1,A2& a2,A3& a3,A4 const& a4)
+        {
+            return heap_new_impl<T,A1&,A2&,A3&,A4 const&>(a1,a2,a3,a4);
+        }
+        template<typename T,typename A1,typename A2,typename A3,typename A4>
+        inline T* heap_new(A1 const& a1,A2 const& a2,A3 const& a3,A4& a4)
+        {
+            return heap_new_impl<T,A1 const&,A2 const&,A3 const&,A4&>(a1,a2,a3,a4);
+        }
+        template<typename T,typename A1,typename A2,typename A3,typename A4>
+        inline T* heap_new(A1& a1,A2 const& a2,A3 const& a3,A4& a4)
+        {
+            return heap_new_impl<T,A1&,A2 const&,A3 const&,A4&>(a1,a2,a3,a4);
+        }
+        template<typename T,typename A1,typename A2,typename A3,typename A4>
+        inline T* heap_new(A1 const& a1,A2& a2,A3 const& a3,A4& a4)
+        {
+            return heap_new_impl<T,A1 const&,A2&,A3 const&,A4&>(a1,a2,a3,a4);
+        }
+        template<typename T,typename A1,typename A2,typename A3,typename A4>
+        inline T* heap_new(A1& a1,A2& a2,A3 const& a3,A4& a4)
+        {
+            return heap_new_impl<T,A1&,A2&,A3 const&,A4&>(a1,a2,a3,a4);
+        }
+
+        template<typename T,typename A1,typename A2,typename A3,typename A4>
+        inline T* heap_new(A1 const& a1,A2 const& a2,A3& a3,A4& a4)
+        {
+            return heap_new_impl<T,A1 const&,A2 const&,A3&,A4&>(a1,a2,a3,a4);
+        }
+        template<typename T,typename A1,typename A2,typename A3,typename A4>
+        inline T* heap_new(A1& a1,A2 const& a2,A3& a3,A4& a4)
+        {
+            return heap_new_impl<T,A1&,A2 const&,A3&,A4&>(a1,a2,a3,a4);
+        }
+        template<typename T,typename A1,typename A2,typename A3,typename A4>
+        inline T* heap_new(A1 const& a1,A2& a2,A3& a3,A4& a4)
+        {
+            return heap_new_impl<T,A1 const&,A2&,A3&,A4&>(a1,a2,a3,a4);
+        }
+        template<typename T,typename A1,typename A2,typename A3,typename A4>
+        inline T* heap_new(A1& a1,A2& a2,A3& a3,A4& a4)
+        {
+            return heap_new_impl<T,A1&,A2&,A3&,A4&>(a1,a2,a3,a4);
+        }
+        
+#endif        
+        template<typename T>
+        inline void heap_delete(T* data)
+        {
+            delete data;
+        }
+
+        template<typename T>
+        struct do_heap_delete
+        {
+            void operator()(T* data) const
+            {
+                detail::heap_delete(data);
+            }
+        };
+    }
+}
+
+#include <boost/config/abi_suffix.hpp>
+
+#endif
diff --git a/deal.II/contrib/boost/include/boost/thread/pthread/timespec.hpp b/deal.II/contrib/boost/include/boost/thread/pthread/timespec.hpp
new file mode 100644 (file)
index 0000000..d7465c1
--- /dev/null
@@ -0,0 +1,36 @@
+#ifndef BOOST_THREAD_PTHREAD_TIMESPEC_HPP
+#define BOOST_THREAD_PTHREAD_TIMESPEC_HPP
+//  (C) Copyright 2007-8 Anthony Williams 
+//
+//  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/thread/thread_time.hpp>
+#include <boost/date_time/posix_time/conversion.hpp>
+#include <pthread.h>
+#ifndef _WIN32
+#include <unistd.h>
+#endif
+
+#include <boost/config/abi_prefix.hpp>
+
+namespace boost
+{
+    namespace detail
+    {
+        inline struct timespec get_timespec(boost::system_time const& abs_time)
+        {
+            struct timespec timeout={0,0};
+            boost::posix_time::time_duration const time_since_epoch=abs_time-boost::posix_time::from_time_t(0);
+            
+            timeout.tv_sec=time_since_epoch.total_seconds();
+            timeout.tv_nsec=(long)(time_since_epoch.fractional_seconds()*(1000000000l/time_since_epoch.ticks_per_second()));
+            return timeout;
+        }
+    }
+}
+
+#include <boost/config/abi_suffix.hpp>
+
+#endif
diff --git a/deal.II/contrib/boost/include/boost/thread/recursive_mutex.hpp b/deal.II/contrib/boost/include/boost/thread/recursive_mutex.hpp
new file mode 100644 (file)
index 0000000..d5f6116
--- /dev/null
@@ -0,0 +1,21 @@
+#ifndef BOOST_THREAD_RECURSIVE_MUTEX_HPP
+#define BOOST_THREAD_RECURSIVE_MUTEX_HPP
+
+//  recursive_mutex.hpp
+//
+//  (C) Copyright 2007 Anthony Williams 
+//
+//  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/thread/detail/platform.hpp>
+#if defined(BOOST_THREAD_PLATFORM_WIN32)
+#include <boost/thread/win32/recursive_mutex.hpp>
+#elif defined(BOOST_THREAD_PLATFORM_PTHREAD)
+#include <boost/thread/pthread/recursive_mutex.hpp>
+#else
+#error "Boost threads unavailable on this platform"
+#endif
+
+#endif
diff --git a/deal.II/contrib/boost/include/boost/thread/shared_mutex.hpp b/deal.II/contrib/boost/include/boost/thread/shared_mutex.hpp
new file mode 100644 (file)
index 0000000..51eda0d
--- /dev/null
@@ -0,0 +1,21 @@
+#ifndef BOOST_THREAD_SHARED_MUTEX_HPP
+#define BOOST_THREAD_SHARED_MUTEX_HPP
+
+//  shared_mutex.hpp
+//
+//  (C) Copyright 2007 Anthony Williams 
+//
+//  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/thread/detail/platform.hpp>
+#if defined(BOOST_THREAD_PLATFORM_WIN32)
+#include <boost/thread/win32/shared_mutex.hpp>
+#elif defined(BOOST_THREAD_PLATFORM_PTHREAD)
+#include <boost/thread/pthread/shared_mutex.hpp>
+#else
+#error "Boost threads unavailable on this platform"
+#endif
+
+#endif
diff --git a/deal.II/contrib/boost/include/boost/thread/thread.hpp b/deal.II/contrib/boost/include/boost/thread/thread.hpp
new file mode 100644 (file)
index 0000000..6146132
--- /dev/null
@@ -0,0 +1,25 @@
+#ifndef BOOST_THREAD_THREAD_HPP
+#define BOOST_THREAD_THREAD_HPP
+
+//  thread.hpp
+//
+//  (C) Copyright 2007-8 Anthony Williams 
+//
+//  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/thread/detail/platform.hpp>
+
+#if defined(BOOST_THREAD_PLATFORM_WIN32)
+#include <boost/thread/win32/thread_data.hpp>
+#elif defined(BOOST_THREAD_PLATFORM_PTHREAD)
+#include <boost/thread/pthread/thread_data.hpp>
+#else
+#error "Boost threads unavailable on this platform"
+#endif
+
+#include <boost/thread/detail/thread.hpp>
+
+
+#endif
diff --git a/deal.II/contrib/boost/include/boost/thread/thread_time.hpp b/deal.II/contrib/boost/include/boost/thread/thread_time.hpp
new file mode 100644 (file)
index 0000000..8b557d5
--- /dev/null
@@ -0,0 +1,50 @@
+#ifndef BOOST_THREAD_TIME_HPP
+#define BOOST_THREAD_TIME_HPP
+//  (C) Copyright 2007 Anthony Williams 
+//
+//  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/date_time/microsec_time_clock.hpp>
+#include <boost/date_time/posix_time/posix_time_types.hpp>
+
+#include <boost/config/abi_prefix.hpp>
+
+namespace boost
+{
+    typedef boost::posix_time::ptime system_time;
+    
+    inline system_time get_system_time()
+    {
+        return boost::date_time::microsec_clock<system_time>::universal_time();
+    }
+
+    namespace detail
+    {
+        inline system_time get_system_time_sentinel()
+        {
+            return system_time(boost::posix_time::pos_infin);
+        }
+
+        inline unsigned long get_milliseconds_until(system_time const& target_time)
+        {
+            if(target_time.is_pos_infinity())
+            {
+                return ~(unsigned long)0;
+            }
+            system_time const now=get_system_time();
+            if(target_time<=now)
+            {
+                return 0;
+            }
+            return static_cast<unsigned long>((target_time-now).total_milliseconds()+1);
+        }
+
+    }
+    
+}
+
+#include <boost/config/abi_suffix.hpp>
+
+#endif
diff --git a/deal.II/contrib/boost/include/boost/thread/tss.hpp b/deal.II/contrib/boost/include/boost/thread/tss.hpp
new file mode 100644 (file)
index 0000000..76380aa
--- /dev/null
@@ -0,0 +1,111 @@
+#ifndef BOOST_THREAD_TSS_HPP
+#define BOOST_THREAD_TSS_HPP
+// 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)
+// (C) Copyright 2007-8 Anthony Williams
+
+#include <boost/thread/detail/config.hpp>
+#include <boost/shared_ptr.hpp>
+#include <boost/thread/detail/thread_heap_alloc.hpp>
+
+#include <boost/config/abi_prefix.hpp>
+
+namespace boost
+{
+    namespace detail
+    {
+        struct tss_cleanup_function
+        {
+            virtual ~tss_cleanup_function()
+            {}
+            
+            virtual void operator()(void* data)=0;
+        };
+        
+        BOOST_THREAD_DECL void set_tss_data(void const* key,boost::shared_ptr<tss_cleanup_function> func,void* tss_data,bool cleanup_existing);
+        BOOST_THREAD_DECL void* get_tss_data(void const* key);
+    }
+
+    template <typename T>
+    class thread_specific_ptr
+    {
+    private:
+        thread_specific_ptr(thread_specific_ptr&);
+        thread_specific_ptr& operator=(thread_specific_ptr&);
+
+        struct delete_data:
+            detail::tss_cleanup_function
+        {
+            void operator()(void* data)
+            {
+                delete static_cast<T*>(data);
+            }
+        };
+        
+        struct run_custom_cleanup_function:
+            detail::tss_cleanup_function
+        {
+            void (*cleanup_function)(T*);
+            
+            explicit run_custom_cleanup_function(void (*cleanup_function_)(T*)):
+                cleanup_function(cleanup_function_)
+            {}
+            
+            void operator()(void* data)
+            {
+                cleanup_function(static_cast<T*>(data));
+            }
+        };
+
+
+        boost::shared_ptr<detail::tss_cleanup_function> cleanup;
+        
+    public:
+        thread_specific_ptr():
+            cleanup(detail::heap_new<delete_data>(),detail::do_heap_delete<delete_data>())
+        {}
+        explicit thread_specific_ptr(void (*func_)(T*))
+        {
+            if(func_)
+            {
+                cleanup.reset(detail::heap_new<run_custom_cleanup_function>(func_),detail::do_heap_delete<run_custom_cleanup_function>());
+            }
+        }
+        ~thread_specific_ptr()
+        {
+            reset();
+        }
+
+        T* get() const
+        {
+            return static_cast<T*>(detail::get_tss_data(this));
+        }
+        T* operator->() const
+        {
+            return get();
+        }
+        T& operator*() const
+        {
+            return *get();
+        }
+        T* release()
+        {
+            T* const temp=get();
+            detail::set_tss_data(this,boost::shared_ptr<detail::tss_cleanup_function>(),0,false);
+            return temp;
+        }
+        void reset(T* new_value=0)
+        {
+            T* const current_value=get();
+            if(current_value!=new_value)
+            {
+                detail::set_tss_data(this,cleanup,new_value,true);
+            }
+        }
+    };
+}
+
+#include <boost/config/abi_suffix.hpp>
+
+#endif
diff --git a/deal.II/contrib/boost/include/boost/thread/win32/basic_recursive_mutex.hpp b/deal.II/contrib/boost/include/boost/thread/win32/basic_recursive_mutex.hpp
new file mode 100644 (file)
index 0000000..05eb8d7
--- /dev/null
@@ -0,0 +1,120 @@
+#ifndef BOOST_BASIC_RECURSIVE_MUTEX_WIN32_HPP
+#define BOOST_BASIC_RECURSIVE_MUTEX_WIN32_HPP
+
+//  basic_recursive_mutex.hpp
+//
+//  (C) Copyright 2006-8 Anthony Williams 
+//
+//  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 "thread_primitives.hpp"
+#include "basic_timed_mutex.hpp"
+
+#include <boost/config/abi_prefix.hpp>
+
+namespace boost
+{
+    namespace detail
+    {
+        template<typename underlying_mutex_type>
+        struct basic_recursive_mutex_impl
+        {
+            long recursion_count;
+            long locking_thread_id;
+            underlying_mutex_type mutex;
+
+            void initialize()
+            {
+                recursion_count=0;
+                locking_thread_id=0;
+                mutex.initialize();
+            }
+
+            void destroy()
+            {
+                mutex.destroy();
+            }
+
+            bool try_lock()
+            {
+                long const current_thread_id=win32::GetCurrentThreadId();
+                return try_recursive_lock(current_thread_id) || try_basic_lock(current_thread_id);
+            }
+            
+            void lock()
+            {
+                long const current_thread_id=win32::GetCurrentThreadId();
+                if(!try_recursive_lock(current_thread_id))
+                {
+                    mutex.lock();
+                    BOOST_INTERLOCKED_EXCHANGE(&locking_thread_id,current_thread_id);
+                    recursion_count=1;
+                }
+            }
+            bool timed_lock(::boost::system_time const& target)
+            {
+                long const current_thread_id=win32::GetCurrentThreadId();
+                return try_recursive_lock(current_thread_id) || try_timed_lock(current_thread_id,target);
+            }
+            template<typename Duration>
+            bool timed_lock(Duration const& timeout)
+            {
+                return timed_lock(get_system_time()+timeout);
+            }
+
+            void unlock()
+            {
+                if(!--recursion_count)
+                {
+                    BOOST_INTERLOCKED_EXCHANGE(&locking_thread_id,0);
+                    mutex.unlock();
+                }
+            }
+
+        private:
+            bool try_recursive_lock(long current_thread_id)
+            {
+                if(::boost::detail::interlocked_read_acquire(&locking_thread_id)==current_thread_id)
+                {
+                    ++recursion_count;
+                    return true;
+                }
+                return false;
+            }
+            
+            bool try_basic_lock(long current_thread_id)
+            {
+                if(mutex.try_lock())
+                {
+                    BOOST_INTERLOCKED_EXCHANGE(&locking_thread_id,current_thread_id);
+                    recursion_count=1;
+                    return true;
+                }
+                return false;
+            }
+            
+            bool try_timed_lock(long current_thread_id,::boost::system_time const& target)
+            {
+                if(mutex.timed_lock(target))
+                {
+                    BOOST_INTERLOCKED_EXCHANGE(&locking_thread_id,current_thread_id);
+                    recursion_count=1;
+                    return true;
+                }
+                return false;
+            }
+            
+        };
+
+        typedef basic_recursive_mutex_impl<basic_timed_mutex> basic_recursive_mutex;
+        typedef basic_recursive_mutex_impl<basic_timed_mutex> basic_recursive_timed_mutex;
+    }
+}
+
+#define BOOST_BASIC_RECURSIVE_MUTEX_INITIALIZER {0}
+
+#include <boost/config/abi_suffix.hpp>
+
+#endif
diff --git a/deal.II/contrib/boost/include/boost/thread/win32/basic_timed_mutex.hpp b/deal.II/contrib/boost/include/boost/thread/win32/basic_timed_mutex.hpp
new file mode 100644 (file)
index 0000000..751bdbd
--- /dev/null
@@ -0,0 +1,178 @@
+#ifndef BOOST_BASIC_TIMED_MUTEX_WIN32_HPP
+#define BOOST_BASIC_TIMED_MUTEX_WIN32_HPP
+
+//  basic_timed_mutex_win32.hpp
+//
+//  (C) Copyright 2006-8 Anthony Williams 
+//
+//  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/assert.hpp>
+#include "thread_primitives.hpp"
+#include "interlocked_read.hpp"
+#include <boost/thread/thread_time.hpp>
+#include <boost/thread/xtime.hpp>
+#include <boost/detail/interlocked.hpp>
+
+#include <boost/config/abi_prefix.hpp>
+
+namespace boost
+{
+    namespace detail
+    {
+        struct basic_timed_mutex
+        {
+            BOOST_STATIC_CONSTANT(unsigned char,lock_flag_bit=31);
+            BOOST_STATIC_CONSTANT(unsigned char,event_set_flag_bit=30);
+            BOOST_STATIC_CONSTANT(long,lock_flag_value=1<<lock_flag_bit);
+            BOOST_STATIC_CONSTANT(long,event_set_flag_value=1<<event_set_flag_bit);
+            long active_count;
+            void* event;
+
+            void initialize()
+            {
+                active_count=0;
+                event=0;
+            }
+
+            void destroy()
+            {
+#ifdef BOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable:4312)
+#endif
+                void* const old_event=BOOST_INTERLOCKED_EXCHANGE_POINTER(&event,0);
+#ifdef BOOST_MSVC
+#pragma warning(pop)
+#endif
+                if(old_event)
+                {
+                    win32::CloseHandle(old_event);
+                }
+            }
+            
+          
+            bool try_lock()
+            {
+                return !win32::interlocked_bit_test_and_set(&active_count,lock_flag_bit);
+            }
+            
+            void lock()
+            {
+                BOOST_VERIFY(timed_lock(::boost::detail::get_system_time_sentinel()));
+            }
+            bool timed_lock(::boost::system_time const& wait_until)
+            {
+                if(!win32::interlocked_bit_test_and_set(&active_count,lock_flag_bit))
+                {
+                    return true;
+                }
+                long old_count=active_count;
+                for(;;)
+                {
+                    long const new_count=(old_count&lock_flag_value)?(old_count+1):(old_count|lock_flag_value);
+                    long const current=BOOST_INTERLOCKED_COMPARE_EXCHANGE(&active_count,new_count,old_count);
+                    if(current==old_count)
+                    {
+                        break;
+                    }
+                    old_count=current;
+                }
+
+                if(old_count&lock_flag_value)
+                {
+                    bool lock_acquired=false;
+                    void* const sem=get_event();
+
+                    do
+                    {
+                        if(win32::WaitForSingleObject(sem,::boost::detail::get_milliseconds_until(wait_until))!=0)
+                        {
+                            BOOST_INTERLOCKED_DECREMENT(&active_count);
+                            return false;
+                        }
+                        old_count&=~lock_flag_value;
+                        old_count|=event_set_flag_value;
+                        for(;;)
+                        {
+                            long const new_count=((old_count&lock_flag_value)?old_count:((old_count-1)|lock_flag_value))&~event_set_flag_value;
+                            long const current=BOOST_INTERLOCKED_COMPARE_EXCHANGE(&active_count,new_count,old_count);
+                            if(current==old_count)
+                            {
+                                break;
+                            }
+                            old_count=current;
+                        }
+                        lock_acquired=!(old_count&lock_flag_value);
+                    }
+                    while(!lock_acquired);
+                }
+                return true;
+            }
+
+            template<typename Duration>
+            bool timed_lock(Duration const& timeout)
+            {
+                return timed_lock(get_system_time()+timeout);
+            }
+
+            bool timed_lock(boost::xtime const& timeout)
+            {
+                return timed_lock(system_time(timeout));
+            }
+
+            void unlock()
+            {
+                long const offset=lock_flag_value;
+                long const old_count=BOOST_INTERLOCKED_EXCHANGE_ADD(&active_count,lock_flag_value);
+                if(!(old_count&event_set_flag_value) && (old_count>offset))
+                {
+                    if(!win32::interlocked_bit_test_and_set(&active_count,event_set_flag_bit))
+                    {
+                        win32::SetEvent(get_event());
+                    }
+                }
+            }
+
+        private:
+            void* get_event()
+            {
+                void* current_event=::boost::detail::interlocked_read_acquire(&event);
+                
+                if(!current_event)
+                {
+                    void* const new_event=win32::create_anonymous_event(win32::auto_reset_event,win32::event_initially_reset);
+#ifdef BOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable:4311)
+#pragma warning(disable:4312)
+#endif
+                    void* const old_event=BOOST_INTERLOCKED_COMPARE_EXCHANGE_POINTER(&event,new_event,0);
+#ifdef BOOST_MSVC
+#pragma warning(pop)
+#endif
+                    if(old_event!=0)
+                    {
+                        win32::CloseHandle(new_event);
+                        return old_event;
+                    }
+                    else
+                    {
+                        return new_event;
+                    }
+                }
+                return current_event;
+            }
+            
+        };
+        
+    }
+}
+
+#define BOOST_BASIC_TIMED_MUTEX_INITIALIZER {0}
+
+#include <boost/config/abi_suffix.hpp>
+
+#endif
diff --git a/deal.II/contrib/boost/include/boost/thread/win32/condition_variable.hpp b/deal.II/contrib/boost/include/boost/thread/win32/condition_variable.hpp
new file mode 100644 (file)
index 0000000..6e676b4
--- /dev/null
@@ -0,0 +1,418 @@
+#ifndef BOOST_THREAD_CONDITION_VARIABLE_WIN32_HPP
+#define BOOST_THREAD_CONDITION_VARIABLE_WIN32_HPP
+// 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)
+// (C) Copyright 2007-8 Anthony Williams
+
+#include <boost/thread/mutex.hpp>
+#include "thread_primitives.hpp"
+#include <limits.h>
+#include <boost/assert.hpp>
+#include <algorithm>
+#include <boost/thread/thread.hpp>
+#include <boost/thread/thread_time.hpp>
+#include "interlocked_read.hpp"
+#include <boost/thread/xtime.hpp>
+#include <vector>
+#include <boost/intrusive_ptr.hpp>
+
+#include <boost/config/abi_prefix.hpp>
+
+namespace boost
+{
+    namespace detail
+    {
+        class basic_cv_list_entry;
+        void intrusive_ptr_add_ref(basic_cv_list_entry * p);
+        void intrusive_ptr_release(basic_cv_list_entry * p);
+        
+        class basic_cv_list_entry
+        {
+        private:
+            detail::win32::handle_manager semaphore;
+            detail::win32::handle_manager wake_sem;
+            long waiters;
+            bool notified;
+            long references;
+
+            basic_cv_list_entry(basic_cv_list_entry&);
+            void operator=(basic_cv_list_entry&);
+            
+        public:
+            explicit basic_cv_list_entry(detail::win32::handle_manager const& wake_sem_):
+                semaphore(detail::win32::create_anonymous_semaphore(0,LONG_MAX)),
+                wake_sem(wake_sem_.duplicate()),
+                waiters(1),notified(false),references(0)
+            {}
+
+            static bool no_waiters(boost::intrusive_ptr<basic_cv_list_entry> const& entry)
+            {
+                return !detail::interlocked_read_acquire(&entry->waiters);
+            }
+
+            void add_waiter()
+            {
+                BOOST_INTERLOCKED_INCREMENT(&waiters);
+            }
+            
+            void remove_waiter()
+            {
+                BOOST_INTERLOCKED_DECREMENT(&waiters);
+            }
+
+            void release(unsigned count_to_release)
+            {
+                notified=true;
+                detail::win32::ReleaseSemaphore(semaphore,count_to_release,0);
+            }
+
+            void release_waiters()
+            {
+                release(detail::interlocked_read_acquire(&waiters));
+            }
+
+            bool is_notified() const
+            {
+                return notified;
+            }
+
+            bool wait(timeout wait_until)
+            {
+                return this_thread::interruptible_wait(semaphore,wait_until);
+            }
+
+            bool woken()
+            {
+                unsigned long const woken_result=detail::win32::WaitForSingleObject(wake_sem,0);
+                BOOST_ASSERT((woken_result==detail::win32::timeout) || (woken_result==0));
+                return woken_result==0;
+            }
+
+            friend void intrusive_ptr_add_ref(basic_cv_list_entry * p);
+            friend void intrusive_ptr_release(basic_cv_list_entry * p);
+        };
+
+        inline void intrusive_ptr_add_ref(basic_cv_list_entry * p)
+        {
+            BOOST_INTERLOCKED_INCREMENT(&p->references);
+        }
+            
+        inline void intrusive_ptr_release(basic_cv_list_entry * p)
+        {
+            if(!BOOST_INTERLOCKED_DECREMENT(&p->references))
+            {
+                delete p;
+            }
+        }
+
+        class basic_condition_variable
+        {
+            boost::mutex internal_mutex;
+            long total_count;
+            unsigned active_generation_count;
+
+            typedef basic_cv_list_entry list_entry;
+
+            typedef boost::intrusive_ptr<list_entry> entry_ptr;
+            typedef std::vector<entry_ptr> generation_list;
+
+            generation_list generations;
+            detail::win32::handle_manager wake_sem;
+
+            void wake_waiters(long count_to_wake)
+            {
+                detail::interlocked_write_release(&total_count,total_count-count_to_wake);
+                detail::win32::ReleaseSemaphore(wake_sem,count_to_wake,0);
+            }
+            
+            template<typename lock_type>
+            struct relocker
+            {
+                lock_type& lock;
+                bool unlocked;
+                
+                relocker(lock_type& lock_):
+                    lock(lock_),unlocked(false)
+                {}
+                void unlock()
+                {
+                    lock.unlock();
+                    unlocked=true;
+                }
+                ~relocker()
+                {
+                    if(unlocked)
+                    {
+                        lock.lock();
+                    }
+                    
+                }
+            private:
+                relocker(relocker&);
+                void operator=(relocker&);
+            };
+            
+
+            entry_ptr get_wait_entry()
+            {
+                boost::lock_guard<boost::mutex> internal_lock(internal_mutex);
+
+                if(!wake_sem)
+                {
+                    wake_sem=detail::win32::create_anonymous_semaphore(0,LONG_MAX);
+                    BOOST_ASSERT(wake_sem);
+                }
+
+                detail::interlocked_write_release(&total_count,total_count+1);
+                if(generations.empty() || generations.back()->is_notified())
+                {
+                    entry_ptr new_entry(new list_entry(wake_sem));
+                    generations.push_back(new_entry);
+                    return new_entry;
+                }
+                else
+                {
+                    generations.back()->add_waiter();
+                    return generations.back();
+                }
+            }
+            
+            struct entry_manager
+            {
+                entry_ptr const entry;
+                    
+                entry_manager(entry_ptr const& entry_):
+                    entry(entry_)
+                {}
+                    
+                ~entry_manager()
+                {
+                    entry->remove_waiter();
+                }
+
+                list_entry* operator->()
+                {
+                    return entry.get();
+                }
+
+            private:
+                void operator=(entry_manager&);
+                entry_manager(entry_manager&);
+            };
+                
+
+        protected:
+            template<typename lock_type>
+            bool do_wait(lock_type& lock,timeout wait_until)
+            {
+                relocker<lock_type> locker(lock);
+                
+                entry_manager entry(get_wait_entry());
+
+                locker.unlock();
+
+                bool woken=false;
+                while(!woken)
+                {
+                    if(!entry->wait(wait_until))
+                    {
+                        return false;
+                    }
+                
+                    woken=entry->woken();
+                }
+                return woken;
+            }
+
+            template<typename lock_type,typename predicate_type>
+            bool do_wait(lock_type& m,timeout const& wait_until,predicate_type pred)
+            {
+                while (!pred())
+                {
+                    if(!do_wait(m, wait_until))
+                        return pred();
+                }
+                return true;
+            }
+        
+            basic_condition_variable(const basic_condition_variable& other);
+            basic_condition_variable& operator=(const basic_condition_variable& other);
+
+        public:
+            basic_condition_variable():
+                total_count(0),active_generation_count(0),wake_sem(0)
+            {}
+            
+            ~basic_condition_variable()
+            {}
+
+            void notify_one()
+            {
+                if(detail::interlocked_read_acquire(&total_count))
+                {
+                    boost::lock_guard<boost::mutex> internal_lock(internal_mutex);
+                    if(!total_count)
+                    {
+                        return;
+                    }
+                    wake_waiters(1);
+
+                    for(generation_list::iterator it=generations.begin(),
+                            end=generations.end();
+                        it!=end;++it)
+                    {
+                        (*it)->release(1);
+                    }
+                    generations.erase(std::remove_if(generations.begin(),generations.end(),&basic_cv_list_entry::no_waiters),generations.end());
+                }
+            }
+        
+            void notify_all()
+            {
+                if(detail::interlocked_read_acquire(&total_count))
+                {
+                    boost::lock_guard<boost::mutex> internal_lock(internal_mutex);
+                    if(!total_count)
+                    {
+                        return;
+                    }
+                    wake_waiters(total_count);
+                    for(generation_list::iterator it=generations.begin(),
+                            end=generations.end();
+                        it!=end;++it)
+                    {
+                        (*it)->release_waiters();
+                    }
+                    generations.clear();
+                    wake_sem=detail::win32::handle(0);
+                }
+            }
+        
+        };
+    }
+
+    class condition_variable:
+        private detail::basic_condition_variable
+    {
+    private:
+        condition_variable(condition_variable&);
+        void operator=(condition_variable&);
+    public:
+        condition_variable()
+        {}
+        
+        using detail::basic_condition_variable::notify_one;
+        using detail::basic_condition_variable::notify_all;
+        
+        void wait(unique_lock<mutex>& m)
+        {
+            do_wait(m,detail::timeout::sentinel());
+        }
+
+        template<typename predicate_type>
+        void wait(unique_lock<mutex>& m,predicate_type pred)
+        {
+            while(!pred()) wait(m);
+        }
+        
+
+        bool timed_wait(unique_lock<mutex>& m,boost::system_time const& wait_until)
+        {
+            return do_wait(m,wait_until);
+        }
+
+        bool timed_wait(unique_lock<mutex>& m,boost::xtime const& wait_until)
+        {
+            return do_wait(m,system_time(wait_until));
+        }
+        template<typename duration_type>
+        bool timed_wait(unique_lock<mutex>& m,duration_type const& wait_duration)
+        {
+            return do_wait(m,wait_duration.total_milliseconds());
+        }
+
+        template<typename predicate_type>
+        bool timed_wait(unique_lock<mutex>& m,boost::system_time const& wait_until,predicate_type pred)
+        {
+            return do_wait(m,wait_until,pred);
+        }
+        template<typename predicate_type>
+        bool timed_wait(unique_lock<mutex>& m,boost::xtime const& wait_until,predicate_type pred)
+        {
+            return do_wait(m,system_time(wait_until),pred);
+        }
+        template<typename duration_type,typename predicate_type>
+        bool timed_wait(unique_lock<mutex>& m,duration_type const& wait_duration,predicate_type pred)
+        {
+            return do_wait(m,wait_duration.total_milliseconds(),pred);
+        }
+    };
+    
+    class condition_variable_any:
+        private detail::basic_condition_variable
+    {
+    private:
+        condition_variable_any(condition_variable_any&);
+        void operator=(condition_variable_any&);
+    public:
+        condition_variable_any()
+        {}
+        
+        using detail::basic_condition_variable::notify_one;
+        using detail::basic_condition_variable::notify_all;
+        
+        template<typename lock_type>
+        void wait(lock_type& m)
+        {
+            do_wait(m,detail::timeout::sentinel());
+        }
+
+        template<typename lock_type,typename predicate_type>
+        void wait(lock_type& m,predicate_type pred)
+        {
+            while(!pred()) wait(m);
+        }
+        
+        template<typename lock_type>
+        bool timed_wait(lock_type& m,boost::system_time const& wait_until)
+        {
+            return do_wait(m,wait_until);
+        }
+
+        template<typename lock_type>
+        bool timed_wait(lock_type& m,boost::xtime const& wait_until)
+        {
+            return do_wait(m,system_time(wait_until));
+        }
+
+        template<typename lock_type,typename duration_type>
+        bool timed_wait(lock_type& m,duration_type const& wait_duration)
+        {
+            return do_wait(m,wait_duration.total_milliseconds());
+        }
+
+        template<typename lock_type,typename predicate_type>
+        bool timed_wait(lock_type& m,boost::system_time const& wait_until,predicate_type pred)
+        {
+            return do_wait(m,wait_until,pred);
+        }
+
+        template<typename lock_type,typename predicate_type>
+        bool timed_wait(lock_type& m,boost::xtime const& wait_until,predicate_type pred)
+        {
+            return do_wait(m,system_time(wait_until),pred);
+        }
+
+        template<typename lock_type,typename duration_type,typename predicate_type>
+        bool timed_wait(lock_type& m,duration_type const& wait_duration,predicate_type pred)
+        {
+            return do_wait(m,wait_duration.total_milliseconds(),pred);
+        }
+    };
+
+}
+
+#include <boost/config/abi_suffix.hpp>
+
+#endif
diff --git a/deal.II/contrib/boost/include/boost/thread/win32/interlocked_read.hpp b/deal.II/contrib/boost/include/boost/thread/win32/interlocked_read.hpp
new file mode 100644 (file)
index 0000000..133fb6f
--- /dev/null
@@ -0,0 +1,80 @@
+#ifndef BOOST_THREAD_DETAIL_INTERLOCKED_READ_WIN32_HPP
+#define BOOST_THREAD_DETAIL_INTERLOCKED_READ_WIN32_HPP
+
+//  interlocked_read_win32.hpp
+//
+//  (C) Copyright 2005-8 Anthony Williams 
+//
+//  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/detail/interlocked.hpp>
+
+#include <boost/config/abi_prefix.hpp>
+
+#ifdef BOOST_MSVC
+
+extern "C" void _ReadWriteBarrier(void);
+#pragma intrinsic(_ReadWriteBarrier)
+
+namespace boost
+{
+    namespace detail
+    {
+        inline long interlocked_read_acquire(long volatile* x)
+        {
+            long const res=*x;
+            _ReadWriteBarrier();
+            return res;
+        }
+        inline void* interlocked_read_acquire(void* volatile* x)
+        {
+            void* const res=*x;
+            _ReadWriteBarrier();
+            return res;
+        }
+
+        inline void interlocked_write_release(long volatile* x,long value)
+        {
+            _ReadWriteBarrier();
+            *x=value;
+        }
+        inline void interlocked_write_release(void* volatile* x,void* value)
+        {
+            _ReadWriteBarrier();
+            *x=value;
+        }
+    }
+}
+
+#else
+
+namespace boost
+{
+    namespace detail
+    {
+        inline long interlocked_read_acquire(long volatile* x)
+        {
+            return BOOST_INTERLOCKED_COMPARE_EXCHANGE(x,0,0);
+        }
+        inline void* interlocked_read_acquire(void* volatile* x)
+        {
+            return BOOST_INTERLOCKED_COMPARE_EXCHANGE_POINTER(x,0,0);
+        }
+        inline void interlocked_write_release(long volatile* x,long value)
+        {
+            BOOST_INTERLOCKED_EXCHANGE(x,value);
+        }
+        inline void interlocked_write_release(void* volatile* x,void* value)
+        {
+            BOOST_INTERLOCKED_EXCHANGE_POINTER(x,value);
+        }
+    }
+}
+
+#endif
+
+#include <boost/config/abi_suffix.hpp>
+
+#endif
diff --git a/deal.II/contrib/boost/include/boost/thread/win32/mutex.hpp b/deal.II/contrib/boost/include/boost/thread/win32/mutex.hpp
new file mode 100644 (file)
index 0000000..efe6241
--- /dev/null
@@ -0,0 +1,65 @@
+#ifndef BOOST_THREAD_WIN32_MUTEX_HPP
+#define BOOST_THREAD_WIN32_MUTEX_HPP
+// (C) Copyright 2005-7 Anthony Williams
+// 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 "basic_timed_mutex.hpp"
+#include <boost/utility.hpp>
+#include <boost/thread/exceptions.hpp>
+#include <boost/thread/locks.hpp>
+
+#include <boost/config/abi_prefix.hpp>
+
+namespace boost
+{
+    namespace detail
+    {
+        typedef ::boost::detail::basic_timed_mutex underlying_mutex;
+    }
+
+    class mutex:
+        boost::noncopyable,
+        public ::boost::detail::underlying_mutex
+    {
+    public:
+        mutex()
+        {
+            initialize();
+        }
+        ~mutex()
+        {
+            destroy();
+        }
+
+        typedef unique_lock<mutex> scoped_lock;
+        typedef detail::try_lock_wrapper<mutex> scoped_try_lock;
+    };
+
+    typedef mutex try_mutex;
+
+    class timed_mutex:
+        boost::noncopyable,
+        public ::boost::detail::basic_timed_mutex
+    {
+    public:
+        timed_mutex()
+        {
+            initialize();
+        }
+
+        ~timed_mutex()
+        {
+            destroy();
+        }
+
+        typedef unique_lock<timed_mutex> scoped_timed_lock;
+        typedef detail::try_lock_wrapper<timed_mutex> scoped_try_lock;
+        typedef scoped_timed_lock scoped_lock;
+    };
+}
+
+#include <boost/config/abi_suffix.hpp>
+
+#endif
diff --git a/deal.II/contrib/boost/include/boost/thread/win32/once.hpp b/deal.II/contrib/boost/include/boost/thread/win32/once.hpp
new file mode 100644 (file)
index 0000000..a6fcc94
--- /dev/null
@@ -0,0 +1,136 @@
+#ifndef BOOST_THREAD_WIN32_ONCE_HPP
+#define BOOST_THREAD_WIN32_ONCE_HPP
+
+//  once.hpp
+//
+//  (C) Copyright 2005-7 Anthony Williams 
+//  (C) Copyright 2005 John Maddock
+//
+//  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 <cstring>
+#include <cstddef>
+#include <boost/assert.hpp>
+#include <boost/static_assert.hpp>
+#include <boost/detail/interlocked.hpp>
+#include <boost/thread/win32/thread_primitives.hpp>
+#include <boost/thread/win32/interlocked_read.hpp>
+
+#include <boost/config/abi_prefix.hpp>
+
+#ifdef BOOST_NO_STDC_NAMESPACE
+namespace std
+{
+    using ::memcpy;
+    using ::ptrdiff_t;
+}
+#endif
+
+namespace boost
+{
+    typedef long once_flag;
+
+#define BOOST_ONCE_INIT 0
+
+    namespace detail
+    {
+        struct win32_mutex_scoped_lock
+        {
+            void* const mutex_handle;
+            explicit win32_mutex_scoped_lock(void* mutex_handle_):
+                mutex_handle(mutex_handle_)
+            {
+                BOOST_VERIFY(!win32::WaitForSingleObject(mutex_handle,win32::infinite));
+            }
+            ~win32_mutex_scoped_lock()
+            {
+                BOOST_VERIFY(win32::ReleaseMutex(mutex_handle)!=0);
+            }
+        private:
+            void operator=(win32_mutex_scoped_lock&);
+        };
+
+#ifdef BOOST_NO_ANSI_APIS
+        template <class I>
+        void int_to_string(I p, wchar_t* buf)
+        {
+            for(unsigned i=0; i < sizeof(I)*2; ++i,++buf)
+            {
+                *buf = L'A' + static_cast<wchar_t>((p >> (i*4)) & 0x0f);
+            }
+            *buf = 0;
+        }
+#else
+        template <class I>
+        void int_to_string(I p, char* buf)
+        {
+            for(unsigned i=0; i < sizeof(I)*2; ++i,++buf)
+            {
+                *buf = 'A' + static_cast<char>((p >> (i*4)) & 0x0f);
+            }
+            *buf = 0;
+        }
+#endif
+
+        // create a named mutex. It doesn't really matter what this name is
+        // as long as it is unique both to this process, and to the address of "flag":
+        inline void* create_once_mutex(void* flag_address)
+        {
+        
+#ifdef BOOST_NO_ANSI_APIS
+            typedef wchar_t char_type;
+            static const char_type fixed_mutex_name[]=L"{C15730E2-145C-4c5e-B005-3BC753F42475}-once-flag";
+#else
+            typedef char char_type;
+            static const char_type fixed_mutex_name[]="{C15730E2-145C-4c5e-B005-3BC753F42475}-once-flag";
+#endif
+            unsigned const once_mutex_name_fixed_buffer_size=sizeof(fixed_mutex_name)/sizeof(char_type);
+            unsigned const once_mutex_name_fixed_length=once_mutex_name_fixed_buffer_size-1;
+            unsigned const once_mutex_name_length=once_mutex_name_fixed_buffer_size+sizeof(void*)*2+sizeof(unsigned long)*2;
+            char_type mutex_name[once_mutex_name_length];
+            
+            std::memcpy(mutex_name,fixed_mutex_name,sizeof(fixed_mutex_name));
+
+            BOOST_STATIC_ASSERT(sizeof(void*) == sizeof(std::ptrdiff_t));
+            detail::int_to_string(reinterpret_cast<std::ptrdiff_t>(flag_address), mutex_name + once_mutex_name_fixed_length);
+            detail::int_to_string(win32::GetCurrentProcessId(), mutex_name + once_mutex_name_fixed_length + sizeof(void*)*2);
+
+#ifdef BOOST_NO_ANSI_APIS
+            return win32::CreateMutexW(0, 0, mutex_name);
+#else
+            return win32::CreateMutexA(0, 0, mutex_name);
+#endif
+        }
+
+        
+    }
+    
+
+    template<typename Function>
+    void call_once(once_flag& flag,Function f)
+    {
+        // Try for a quick win: if the procedure has already been called
+        // just skip through:
+        long const function_complete_flag_value=0xc15730e2;
+
+        if(::boost::detail::interlocked_read_acquire(&flag)!=function_complete_flag_value)
+        {
+            void* const mutex_handle(::boost::detail::create_once_mutex(&flag));
+            BOOST_ASSERT(mutex_handle);
+            detail::win32::handle_manager const closer(mutex_handle);
+            detail::win32_mutex_scoped_lock const lock(mutex_handle);
+      
+            if(flag!=function_complete_flag_value)
+            {
+                f();
+                BOOST_INTERLOCKED_EXCHANGE(&flag,function_complete_flag_value);
+            }
+        }
+    }
+}
+
+#include <boost/config/abi_suffix.hpp>
+
+#endif
diff --git a/deal.II/contrib/boost/include/boost/thread/win32/recursive_mutex.hpp b/deal.II/contrib/boost/include/boost/thread/win32/recursive_mutex.hpp
new file mode 100644 (file)
index 0000000..2360a92
--- /dev/null
@@ -0,0 +1,64 @@
+#ifndef BOOST_RECURSIVE_MUTEX_WIN32_HPP
+#define BOOST_RECURSIVE_MUTEX_WIN32_HPP
+
+//  recursive_mutex.hpp
+//
+//  (C) Copyright 2006-7 Anthony Williams 
+//
+//  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/utility.hpp>
+#include "basic_recursive_mutex.hpp"
+#include <boost/thread/exceptions.hpp>
+#include <boost/thread/locks.hpp>
+
+#include <boost/config/abi_prefix.hpp>
+
+namespace boost
+{
+    class recursive_mutex:
+        boost::noncopyable,
+        public ::boost::detail::basic_recursive_mutex
+    {
+    public:
+        recursive_mutex()
+        {
+            ::boost::detail::basic_recursive_mutex::initialize();
+        }
+        ~recursive_mutex()
+        {
+            ::boost::detail::basic_recursive_mutex::destroy();
+        }
+
+        typedef unique_lock<recursive_mutex> scoped_lock;
+        typedef detail::try_lock_wrapper<recursive_mutex> scoped_try_lock;
+    };
+
+    typedef recursive_mutex recursive_try_mutex;
+
+    class recursive_timed_mutex:
+        boost::noncopyable,
+        public ::boost::detail::basic_recursive_timed_mutex
+    {
+    public:
+        recursive_timed_mutex()
+        {
+            ::boost::detail::basic_recursive_timed_mutex::initialize();
+        }
+        ~recursive_timed_mutex()
+        {
+            ::boost::detail::basic_recursive_timed_mutex::destroy();
+        }
+
+        typedef unique_lock<recursive_timed_mutex> scoped_timed_lock;
+        typedef detail::try_lock_wrapper<recursive_timed_mutex> scoped_try_lock;
+        typedef scoped_timed_lock scoped_lock;
+    };
+}
+
+#include <boost/config/abi_suffix.hpp>
+
+#endif
diff --git a/deal.II/contrib/boost/include/boost/thread/win32/shared_mutex.hpp b/deal.II/contrib/boost/include/boost/thread/win32/shared_mutex.hpp
new file mode 100644 (file)
index 0000000..58e8093
--- /dev/null
@@ -0,0 +1,566 @@
+#ifndef BOOST_THREAD_WIN32_SHARED_MUTEX_HPP
+#define BOOST_THREAD_WIN32_SHARED_MUTEX_HPP
+
+//  (C) Copyright 2006-8 Anthony Williams
+//
+//  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/assert.hpp>
+#include <boost/detail/interlocked.hpp>
+#include <boost/thread/win32/thread_primitives.hpp>
+#include <boost/static_assert.hpp>
+#include <limits.h>
+#include <boost/utility.hpp>
+#include <boost/thread/thread_time.hpp>
+
+#include <boost/config/abi_prefix.hpp>
+
+namespace boost
+{
+    class shared_mutex:
+        private boost::noncopyable
+    {
+    private:
+        struct state_data
+        {
+            unsigned shared_count:11,
+                shared_waiting:11,
+                exclusive:1,
+                upgrade:1,
+                exclusive_waiting:7,
+                exclusive_waiting_blocked:1;
+
+            friend bool operator==(state_data const& lhs,state_data const& rhs)
+            {
+                return *reinterpret_cast<unsigned const*>(&lhs)==*reinterpret_cast<unsigned const*>(&rhs);
+            }
+        };
+        
+
+        template<typename T>
+        T interlocked_compare_exchange(T* target,T new_value,T comparand)
+        {
+            BOOST_STATIC_ASSERT(sizeof(T)==sizeof(long));
+            long const res=BOOST_INTERLOCKED_COMPARE_EXCHANGE(reinterpret_cast<long*>(target),
+                                                              *reinterpret_cast<long*>(&new_value),
+                                                              *reinterpret_cast<long*>(&comparand));
+            return *reinterpret_cast<T const*>(&res);
+        }
+
+        state_data state;
+        detail::win32::handle semaphores[2];
+        detail::win32::handle &unlock_sem;
+        detail::win32::handle &exclusive_sem;
+        detail::win32::handle upgrade_sem;
+
+        void release_waiters(state_data old_state)
+        {
+            if(old_state.exclusive_waiting)
+            {
+                BOOST_VERIFY(detail::win32::ReleaseSemaphore(exclusive_sem,1,0)!=0);
+            }
+                        
+            if(old_state.shared_waiting || old_state.exclusive_waiting)
+            {
+                BOOST_VERIFY(detail::win32::ReleaseSemaphore(unlock_sem,old_state.shared_waiting + (old_state.exclusive_waiting?1:0),0)!=0);
+            }
+        }
+        
+
+    public:
+        shared_mutex():
+            unlock_sem(semaphores[0]),
+            exclusive_sem(semaphores[1]) 
+        {
+            unlock_sem=detail::win32::create_anonymous_semaphore(0,LONG_MAX);
+            exclusive_sem=detail::win32::create_anonymous_semaphore(0,LONG_MAX);
+            upgrade_sem=detail::win32::create_anonymous_semaphore(0,LONG_MAX);
+            state_data state_={0};
+            state=state_;
+        }
+
+        ~shared_mutex()
+        {
+            detail::win32::CloseHandle(upgrade_sem);
+            detail::win32::CloseHandle(unlock_sem);
+            detail::win32::CloseHandle(exclusive_sem);
+        }
+
+        bool try_lock_shared()
+        {
+            state_data old_state=state;
+            for(;;)
+            {
+                state_data new_state=old_state;
+                if(!new_state.exclusive && !new_state.exclusive_waiting_blocked)
+                {
+                    ++new_state.shared_count;
+                }
+                
+                state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state);
+                if(current_state==old_state)
+                {
+                    break;
+                }
+                old_state=current_state;
+            }
+            return !(old_state.exclusive| old_state.exclusive_waiting_blocked);
+        }
+
+        void lock_shared()
+        {
+            BOOST_VERIFY(timed_lock_shared(::boost::detail::get_system_time_sentinel()));
+        }
+
+        template<typename TimeDuration>
+        bool timed_lock_shared(TimeDuration const & relative_time)
+        {
+            return timed_lock_shared(get_system_time()+relative_time);
+        }
+
+        bool timed_lock_shared(boost::system_time const& wait_until)
+        {
+            for(;;)
+            {
+                state_data old_state=state;
+                for(;;)
+                {
+                    state_data new_state=old_state;
+                    if(new_state.exclusive || new_state.exclusive_waiting_blocked)
+                    {
+                        ++new_state.shared_waiting;
+                    }
+                    else
+                    {
+                        ++new_state.shared_count;
+                    }
+
+                    state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state);
+                    if(current_state==old_state)
+                    {
+                        break;
+                    }
+                    old_state=current_state;
+                }
+
+                if(!(old_state.exclusive| old_state.exclusive_waiting_blocked))
+                {
+                    return true;
+                }
+                    
+                unsigned long const res=detail::win32::WaitForSingleObject(unlock_sem,::boost::detail::get_milliseconds_until(wait_until));
+                if(res==detail::win32::timeout)
+                {
+                    for(;;)
+                    {
+                        state_data new_state=old_state;
+                        if(new_state.exclusive || new_state.exclusive_waiting_blocked)
+                        {
+                            if(new_state.shared_waiting)
+                            {
+                                --new_state.shared_waiting;
+                            }
+                        }
+                        else
+                        {
+                            ++new_state.shared_count;
+                        }
+
+                        state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state);
+                        if(current_state==old_state)
+                        {
+                            break;
+                        }
+                        old_state=current_state;
+                    }
+
+                    if(!(old_state.exclusive| old_state.exclusive_waiting_blocked))
+                    {
+                        return true;
+                    }
+                    return false;
+                }
+                
+                BOOST_ASSERT(res==0);
+            }
+        }
+
+        void unlock_shared()
+        {
+            state_data old_state=state;
+            for(;;)
+            {
+                state_data new_state=old_state;
+                bool const last_reader=!--new_state.shared_count;
+                
+                if(last_reader)
+                {
+                    if(new_state.upgrade)
+                    {
+                        new_state.upgrade=false;
+                        new_state.exclusive=true;
+                    }
+                    else
+                    {
+                        if(new_state.exclusive_waiting)
+                        {
+                            --new_state.exclusive_waiting;
+                            new_state.exclusive_waiting_blocked=false;
+                        }
+                        new_state.shared_waiting=0;
+                    }
+                }
+                
+                state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state);
+                if(current_state==old_state)
+                {
+                    if(last_reader)
+                    {
+                        if(old_state.upgrade)
+                        {
+                            BOOST_VERIFY(detail::win32::ReleaseSemaphore(upgrade_sem,1,0)!=0);
+                        }
+                        else
+                        {
+                            release_waiters(old_state);
+                        }
+                    }
+                    break;
+                }
+                old_state=current_state;
+            }
+        }
+
+        void lock()
+        {
+            BOOST_VERIFY(timed_lock(::boost::detail::get_system_time_sentinel()));
+        }
+
+        template<typename TimeDuration>
+        bool timed_lock(TimeDuration const & relative_time)
+        {
+            return timed_lock(get_system_time()+relative_time);
+        }
+
+        bool try_lock()
+        {
+            state_data old_state=state;
+            for(;;)
+            {
+                state_data new_state=old_state;
+                if(new_state.shared_count || new_state.exclusive)
+                {
+                    return false;
+                }
+                else
+                {
+                    new_state.exclusive=true;
+                }
+                
+                state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state);
+                if(current_state==old_state)
+                {
+                    break;
+                }
+                old_state=current_state;
+            }
+            return true;
+        }
+
+
+        bool timed_lock(boost::system_time const& wait_until)
+        {
+            for(;;)
+            {
+                state_data old_state=state;
+
+                for(;;)
+                {
+                    state_data new_state=old_state;
+                    if(new_state.shared_count || new_state.exclusive)
+                    {
+                        ++new_state.exclusive_waiting;
+                        new_state.exclusive_waiting_blocked=true;
+                    }
+                    else
+                    {
+                        new_state.exclusive=true;
+                    }
+
+                    state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state);
+                    if(current_state==old_state)
+                    {
+                        break;
+                    }
+                    old_state=current_state;
+                }
+
+                if(!old_state.shared_count && !old_state.exclusive)
+                {
+                    return true;
+                }
+                unsigned long const wait_res=detail::win32::WaitForMultipleObjects(2,semaphores,true,::boost::detail::get_milliseconds_until(wait_until));
+                if(wait_res==detail::win32::timeout)
+                {
+                    for(;;)
+                    {
+                        state_data new_state=old_state;
+                        if(new_state.shared_count || new_state.exclusive)
+                        {
+                            if(new_state.exclusive_waiting)
+                            {
+                                if(!--new_state.exclusive_waiting)
+                                {
+                                    new_state.exclusive_waiting_blocked=false;
+                                }
+                            }
+                        }
+                        else
+                        {
+                            new_state.exclusive=true;
+                        }
+
+                        state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state);
+                        if(current_state==old_state)
+                        {
+                            break;
+                        }
+                        old_state=current_state;
+                    }
+                    if(!old_state.shared_count && !old_state.exclusive)
+                    {
+                        return true;
+                    }
+                    return false;
+                }
+                BOOST_ASSERT(wait_res<2);
+            }
+        }
+
+        void unlock()
+        {
+            state_data old_state=state;
+            for(;;)
+            {
+                state_data new_state=old_state;
+                new_state.exclusive=false;
+                if(new_state.exclusive_waiting)
+                {
+                    --new_state.exclusive_waiting;
+                    new_state.exclusive_waiting_blocked=false;
+                }
+                new_state.shared_waiting=0;
+
+                state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state);
+                if(current_state==old_state)
+                {
+                    break;
+                }
+                old_state=current_state;
+            }
+            release_waiters(old_state);
+        }
+
+        void lock_upgrade()
+        {
+            for(;;)
+            {
+                state_data old_state=state;
+                for(;;)
+                {
+                    state_data new_state=old_state;
+                    if(new_state.exclusive || new_state.exclusive_waiting_blocked || new_state.upgrade)
+                    {
+                        ++new_state.shared_waiting;
+                    }
+                    else
+                    {
+                        ++new_state.shared_count;
+                        new_state.upgrade=true;
+                    }
+
+                    state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state);
+                    if(current_state==old_state)
+                    {
+                        break;
+                    }
+                    old_state=current_state;
+                }
+
+                if(!(old_state.exclusive|| old_state.exclusive_waiting_blocked|| old_state.upgrade))
+                {
+                    return;
+                }
+                    
+                BOOST_VERIFY(!detail::win32::WaitForSingleObject(unlock_sem,detail::win32::infinite));
+            }
+        }
+
+        bool try_lock_upgrade()
+        {
+            state_data old_state=state;
+            for(;;)
+            {
+                state_data new_state=old_state;
+                if(new_state.exclusive || new_state.exclusive_waiting_blocked || new_state.upgrade)
+                {
+                    return false;
+                }
+                else
+                {
+                    ++new_state.shared_count;
+                    new_state.upgrade=true;
+                }
+                
+                state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state);
+                if(current_state==old_state)
+                {
+                    break;
+                }
+                old_state=current_state;
+            }
+            return true;
+        }
+
+        void unlock_upgrade()
+        {
+            state_data old_state=state;
+            for(;;)
+            {
+                state_data new_state=old_state;
+                new_state.upgrade=false;
+                bool const last_reader=!--new_state.shared_count;
+                
+                if(last_reader)
+                {
+                    if(new_state.exclusive_waiting)
+                    {
+                        --new_state.exclusive_waiting;
+                        new_state.exclusive_waiting_blocked=false;
+                    }
+                    new_state.shared_waiting=0;
+                }
+                
+                state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state);
+                if(current_state==old_state)
+                {
+                    if(last_reader)
+                    {
+                        release_waiters(old_state);
+                    }
+                    break;
+                }
+                old_state=current_state;
+            }
+        }
+
+        void unlock_upgrade_and_lock()
+        {
+            state_data old_state=state;
+            for(;;)
+            {
+                state_data new_state=old_state;
+                bool const last_reader=!--new_state.shared_count;
+                
+                if(last_reader)
+                {
+                    new_state.upgrade=false;
+                    new_state.exclusive=true;
+                }
+                
+                state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state);
+                if(current_state==old_state)
+                {
+                    if(!last_reader)
+                    {
+                        BOOST_VERIFY(!detail::win32::WaitForSingleObject(upgrade_sem,detail::win32::infinite));
+                    }
+                    break;
+                }
+                old_state=current_state;
+            }
+        }
+
+        void unlock_and_lock_upgrade()
+        {
+            state_data old_state=state;
+            for(;;)
+            {
+                state_data new_state=old_state;
+                new_state.exclusive=false;
+                new_state.upgrade=true;
+                ++new_state.shared_count;
+                if(new_state.exclusive_waiting)
+                {
+                    --new_state.exclusive_waiting;
+                    new_state.exclusive_waiting_blocked=false;
+                }
+                new_state.shared_waiting=0;
+
+                state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state);
+                if(current_state==old_state)
+                {
+                    break;
+                }
+                old_state=current_state;
+            }
+            release_waiters(old_state);
+        }
+        
+        void unlock_and_lock_shared()
+        {
+            state_data old_state=state;
+            for(;;)
+            {
+                state_data new_state=old_state;
+                new_state.exclusive=false;
+                ++new_state.shared_count;
+                if(new_state.exclusive_waiting)
+                {
+                    --new_state.exclusive_waiting;
+                    new_state.exclusive_waiting_blocked=false;
+                }
+                new_state.shared_waiting=0;
+
+                state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state);
+                if(current_state==old_state)
+                {
+                    break;
+                }
+                old_state=current_state;
+            }
+            release_waiters(old_state);
+        }
+        
+        void unlock_upgrade_and_lock_shared()
+        {
+            state_data old_state=state;
+            for(;;)
+            {
+                state_data new_state=old_state;
+                new_state.upgrade=false;
+                if(new_state.exclusive_waiting)
+                {
+                    --new_state.exclusive_waiting;
+                    new_state.exclusive_waiting_blocked=false;
+                }
+                new_state.shared_waiting=0;
+
+                state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state);
+                if(current_state==old_state)
+                {
+                    break;
+                }
+                old_state=current_state;
+            }
+            release_waiters(old_state);
+        }
+        
+    };
+}
+
+#include <boost/config/abi_suffix.hpp>
+
+#endif
diff --git a/deal.II/contrib/boost/include/boost/thread/win32/thread_data.hpp b/deal.II/contrib/boost/include/boost/thread/win32/thread_data.hpp
new file mode 100644 (file)
index 0000000..1a6a1e0
--- /dev/null
@@ -0,0 +1,178 @@
+#ifndef BOOST_THREAD_PTHREAD_THREAD_DATA_HPP
+#define BOOST_THREAD_PTHREAD_THREAD_DATA_HPP
+// 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)
+// (C) Copyright 2008 Anthony Williams
+
+#include <boost/thread/detail/config.hpp>
+#include <boost/intrusive_ptr.hpp>
+#include <boost/thread/thread_time.hpp>
+#include "thread_primitives.hpp"
+#include "thread_heap_alloc.hpp"
+
+#include <boost/config/abi_prefix.hpp>
+
+namespace boost
+{
+    namespace detail
+    {
+        struct thread_exit_callback_node;
+        struct tss_data_node;
+
+        struct thread_data_base;
+        void intrusive_ptr_add_ref(thread_data_base * p);
+        void intrusive_ptr_release(thread_data_base * p);
+        
+        struct thread_data_base
+        {
+            long count;
+            detail::win32::handle_manager thread_handle;
+            detail::win32::handle_manager interruption_handle;
+            boost::detail::thread_exit_callback_node* thread_exit_callbacks;
+            boost::detail::tss_data_node* tss_data;
+            bool interruption_enabled;
+            unsigned id;
+
+            thread_data_base():
+                count(0),thread_handle(detail::win32::invalid_handle_value),
+                interruption_handle(create_anonymous_event(detail::win32::manual_reset_event,detail::win32::event_initially_reset)),
+                thread_exit_callbacks(0),tss_data(0),
+                interruption_enabled(true),
+                id(0)
+            {}
+            virtual ~thread_data_base()
+            {}
+
+            friend void intrusive_ptr_add_ref(thread_data_base * p)
+            {
+                BOOST_INTERLOCKED_INCREMENT(&p->count);
+            }
+            
+            friend void intrusive_ptr_release(thread_data_base * p)
+            {
+                if(!BOOST_INTERLOCKED_DECREMENT(&p->count))
+                {
+                    detail::heap_delete(p);
+                }
+            }
+
+            void interrupt()
+            {
+                BOOST_VERIFY(detail::win32::SetEvent(interruption_handle)!=0);
+            }
+            
+            typedef detail::win32::handle native_handle_type;
+
+            virtual void run()=0;
+        };
+
+        typedef boost::intrusive_ptr<detail::thread_data_base> thread_data_ptr;
+
+        struct timeout
+        {
+            unsigned long start;
+            uintmax_t milliseconds;
+            bool relative;
+            boost::system_time abs_time;
+
+            static unsigned long const max_non_infinite_wait=0xfffffffe;
+
+            timeout(uintmax_t milliseconds_):
+                start(win32::GetTickCount()),
+                milliseconds(milliseconds_),
+                relative(true),
+                abs_time(boost::get_system_time())
+            {}
+
+            timeout(boost::system_time const& abs_time_):
+                start(win32::GetTickCount()),
+                milliseconds(0),
+                relative(false),
+                abs_time(abs_time_)
+            {}
+
+            struct remaining_time
+            {
+                bool more;
+                unsigned long milliseconds;
+
+                remaining_time(uintmax_t remaining):
+                    more(remaining>max_non_infinite_wait),
+                    milliseconds(more?max_non_infinite_wait:(unsigned long)remaining)
+                {}
+            };
+
+            remaining_time remaining_milliseconds() const
+            {
+                if(is_sentinel())
+                {
+                    return remaining_time(win32::infinite);
+                }
+                else if(relative)
+                {
+                    unsigned long const now=win32::GetTickCount();
+                    unsigned long const elapsed=now-start;
+                    return remaining_time((elapsed<milliseconds)?(milliseconds-elapsed):0);
+                }
+                else
+                {
+                    system_time const now=get_system_time();
+                    if(abs_time<=now)
+                    {
+                        return remaining_time(0);
+                    }
+                    return remaining_time((abs_time-now).total_milliseconds()+1);
+                }
+            }
+
+            bool is_sentinel() const
+            {
+                return milliseconds==~uintmax_t(0);
+            }
+            
+
+            static timeout sentinel()
+            {
+                return timeout(sentinel_type());
+            }
+        private:
+            struct sentinel_type
+            {};
+                
+            explicit timeout(sentinel_type):
+                start(0),milliseconds(~uintmax_t(0)),relative(true)
+            {}
+        };
+    }
+
+    namespace this_thread
+    {
+        void BOOST_THREAD_DECL yield();
+
+        bool BOOST_THREAD_DECL interruptible_wait(detail::win32::handle handle_to_wait_for,detail::timeout target_time);
+        inline void interruptible_wait(unsigned long milliseconds)
+        {
+            interruptible_wait(detail::win32::invalid_handle_value,milliseconds);
+        }
+        inline void interruptible_wait(system_time const& abs_time)
+        {
+            interruptible_wait(detail::win32::invalid_handle_value,abs_time);
+        }
+
+        template<typename TimeDuration>
+        inline void sleep(TimeDuration const& rel_time)
+        {
+            interruptible_wait(static_cast<unsigned long>(rel_time.total_milliseconds()));
+        }
+        inline void sleep(system_time const& abs_time)
+        {
+            interruptible_wait(abs_time);
+        }
+    }
+    
+}
+
+#include <boost/config/abi_suffix.hpp>
+
+#endif
diff --git a/deal.II/contrib/boost/include/boost/thread/win32/thread_heap_alloc.hpp b/deal.II/contrib/boost/include/boost/thread/win32/thread_heap_alloc.hpp
new file mode 100644 (file)
index 0000000..9f8186f
--- /dev/null
@@ -0,0 +1,397 @@
+// 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)
+// (C) Copyright 2007 Anthony Williams
+#ifndef THREAD_HEAP_ALLOC_HPP
+#define THREAD_HEAP_ALLOC_HPP
+#include <new>
+#include "thread_primitives.hpp"
+#include <stdexcept>
+#include <boost/assert.hpp>
+
+#if defined( BOOST_USE_WINDOWS_H )
+# include <windows.h>
+
+namespace boost
+{
+    namespace detail
+    {
+        namespace win32
+        {
+            using ::GetProcessHeap;
+            using ::HeapAlloc;
+            using ::HeapFree;
+        }
+    }
+}
+
+#else
+
+# ifdef HeapAlloc
+# undef HeapAlloc
+# endif
+
+namespace boost
+{
+    namespace detail
+    {
+        namespace win32
+        {
+            extern "C"
+            {
+                __declspec(dllimport) handle __stdcall GetProcessHeap();
+                __declspec(dllimport) void* __stdcall HeapAlloc(handle,unsigned long,ulong_ptr);
+                __declspec(dllimport) int __stdcall HeapFree(handle,unsigned long,void*);
+            }
+        }
+    }
+}
+
+#endif
+
+#include <boost/config/abi_prefix.hpp>
+
+namespace boost
+{
+    namespace detail
+    {
+        inline BOOST_THREAD_DECL void* allocate_raw_heap_memory(unsigned size)
+        {
+            void* const heap_memory=detail::win32::HeapAlloc(detail::win32::GetProcessHeap(),0,size);
+            if(!heap_memory)
+            {
+                throw std::bad_alloc();
+            }
+            return heap_memory;
+        }
+
+        inline BOOST_THREAD_DECL void free_raw_heap_memory(void* heap_memory)
+        {
+            BOOST_VERIFY(detail::win32::HeapFree(detail::win32::GetProcessHeap(),0,heap_memory)!=0);
+        }
+            
+        template<typename T>
+        inline T* heap_new()
+        {
+            void* const heap_memory=allocate_raw_heap_memory(sizeof(T));
+            try
+            {
+                T* const data=new (heap_memory) T();
+                return data;
+            }
+            catch(...)
+            {
+                free_raw_heap_memory(heap_memory);
+                throw;
+            }
+        }
+
+#ifdef BOOST_HAS_RVALUE_REFS
+        template<typename T,typename A1>
+        inline T* heap_new(A1&& a1)
+        {
+            void* const heap_memory=allocate_raw_heap_memory(sizeof(T));
+            try
+            {
+                T* const data=new (heap_memory) T(static_cast<A1&&>(a1));
+                return data;
+            }
+            catch(...)
+            {
+                free_raw_heap_memory(heap_memory);
+                throw;
+            }
+        }
+        template<typename T,typename A1,typename A2>
+        inline T* heap_new(A1&& a1,A2&& a2)
+        {
+            void* const heap_memory=allocate_raw_heap_memory(sizeof(T));
+            try
+            {
+                T* const data=new (heap_memory) T(static_cast<A1&&>(a1),static_cast<A2&&>(a2));
+                return data;
+            }
+            catch(...)
+            {
+                free_raw_heap_memory(heap_memory);
+                throw;
+            }
+        }
+        template<typename T,typename A1,typename A2,typename A3>
+        inline T* heap_new(A1&& a1,A2&& a2,A3&& a3)
+        {
+            void* const heap_memory=allocate_raw_heap_memory(sizeof(T));
+            try
+            {
+                T* const data=new (heap_memory) T(static_cast<A1&&>(a1),static_cast<A2&&>(a2),
+                                                  static_cast<A3&&>(a3));
+                return data;
+            }
+            catch(...)
+            {
+                free_raw_heap_memory(heap_memory);
+                throw;
+            }
+        }
+        template<typename T,typename A1,typename A2,typename A3,typename A4>
+        inline T* heap_new(A1&& a1,A2&& a2,A3&& a3,A4&& a4)
+        {
+            void* const heap_memory=allocate_raw_heap_memory(sizeof(T));
+            try
+            {
+                T* const data=new (heap_memory) T(static_cast<A1&&>(a1),static_cast<A2&&>(a2),
+                                                  static_cast<A3&&>(a3),static_cast<A4&&>(a4));
+                return data;
+            }
+            catch(...)
+            {
+                free_raw_heap_memory(heap_memory);
+                throw;
+            }
+        }
+#else
+        template<typename T,typename A1>
+        inline T* heap_new_impl(A1 a1)
+        {
+            void* const heap_memory=allocate_raw_heap_memory(sizeof(T));
+            try
+            {
+                T* const data=new (heap_memory) T(a1);
+                return data;
+            }
+            catch(...)
+            {
+                free_raw_heap_memory(heap_memory);
+                throw;
+            }
+        }
+
+        template<typename T,typename A1,typename A2>
+        inline T* heap_new_impl(A1 a1,A2 a2)
+        {
+            void* const heap_memory=allocate_raw_heap_memory(sizeof(T));
+            try
+            {
+                T* const data=new (heap_memory) T(a1,a2);
+                return data;
+            }
+            catch(...)
+            {
+                free_raw_heap_memory(heap_memory);
+                throw;
+            }
+        }
+
+        template<typename T,typename A1,typename A2,typename A3>
+        inline T* heap_new_impl(A1 a1,A2 a2,A3 a3)
+        {
+            void* const heap_memory=allocate_raw_heap_memory(sizeof(T));
+            try
+            {
+                T* const data=new (heap_memory) T(a1,a2,a3);
+                return data;
+            }
+            catch(...)
+            {
+                free_raw_heap_memory(heap_memory);
+                throw;
+            }
+        }
+
+        template<typename T,typename A1,typename A2,typename A3,typename A4>
+        inline T* heap_new_impl(A1 a1,A2 a2,A3 a3,A4 a4)
+        {
+            void* const heap_memory=allocate_raw_heap_memory(sizeof(T));
+            try
+            {
+                T* const data=new (heap_memory) T(a1,a2,a3,a4);
+                return data;
+            }
+            catch(...)
+            {
+                free_raw_heap_memory(heap_memory);
+                throw;
+            }
+        }
+
+
+        template<typename T,typename A1>
+        inline T* heap_new(A1 const& a1)
+        {
+            return heap_new_impl<T,A1 const&>(a1);
+        }
+        template<typename T,typename A1>
+        inline T* heap_new(A1& a1)
+        {
+            return heap_new_impl<T,A1&>(a1);
+        }
+        
+        template<typename T,typename A1,typename A2>
+        inline T* heap_new(A1 const& a1,A2 const& a2)
+        {
+            return heap_new_impl<T,A1 const&,A2 const&>(a1,a2);
+        }
+        template<typename T,typename A1,typename A2>
+        inline T* heap_new(A1& a1,A2 const& a2)
+        {
+            return heap_new_impl<T,A1&,A2 const&>(a1,a2);
+        }
+        template<typename T,typename A1,typename A2>
+        inline T* heap_new(A1 const& a1,A2& a2)
+        {
+            return heap_new_impl<T,A1 const&,A2&>(a1,a2);
+        }
+        template<typename T,typename A1,typename A2>
+        inline T* heap_new(A1& a1,A2& a2)
+        {
+            return heap_new_impl<T,A1&,A2&>(a1,a2);
+        }
+
+        template<typename T,typename A1,typename A2,typename A3>
+        inline T* heap_new(A1 const& a1,A2 const& a2,A3 const& a3)
+        {
+            return heap_new_impl<T,A1 const&,A2 const&,A3 const&>(a1,a2,a3);
+        }
+        template<typename T,typename A1,typename A2,typename A3>
+        inline T* heap_new(A1& a1,A2 const& a2,A3 const& a3)
+        {
+            return heap_new_impl<T,A1&,A2 const&,A3 const&>(a1,a2,a3);
+        }
+        template<typename T,typename A1,typename A2,typename A3>
+        inline T* heap_new(A1 const& a1,A2& a2,A3 const& a3)
+        {
+            return heap_new_impl<T,A1 const&,A2&,A3 const&>(a1,a2,a3);
+        }
+        template<typename T,typename A1,typename A2,typename A3>
+        inline T* heap_new(A1& a1,A2& a2,A3 const& a3)
+        {
+            return heap_new_impl<T,A1&,A2&,A3 const&>(a1,a2,a3);
+        }
+
+        template<typename T,typename A1,typename A2,typename A3>
+        inline T* heap_new(A1 const& a1,A2 const& a2,A3& a3)
+        {
+            return heap_new_impl<T,A1 const&,A2 const&,A3&>(a1,a2,a3);
+        }
+        template<typename T,typename A1,typename A2,typename A3>
+        inline T* heap_new(A1& a1,A2 const& a2,A3& a3)
+        {
+            return heap_new_impl<T,A1&,A2 const&,A3&>(a1,a2,a3);
+        }
+        template<typename T,typename A1,typename A2,typename A3>
+        inline T* heap_new(A1 const& a1,A2& a2,A3& a3)
+        {
+            return heap_new_impl<T,A1 const&,A2&,A3&>(a1,a2,a3);
+        }
+        template<typename T,typename A1,typename A2,typename A3>
+        inline T* heap_new(A1& a1,A2& a2,A3& a3)
+        {
+            return heap_new_impl<T,A1&,A2&,A3&>(a1,a2,a3);
+        }
+
+        template<typename T,typename A1,typename A2,typename A3,typename A4>
+        inline T* heap_new(A1 const& a1,A2 const& a2,A3 const& a3,A4 const& a4)
+        {
+            return heap_new_impl<T,A1 const&,A2 const&,A3 const&,A4 const&>(a1,a2,a3,a4);
+        }
+        template<typename T,typename A1,typename A2,typename A3,typename A4>
+        inline T* heap_new(A1& a1,A2 const& a2,A3 const& a3,A4 const& a4)
+        {
+            return heap_new_impl<T,A1&,A2 const&,A3 const&,A4 const&>(a1,a2,a3,a4);
+        }
+        template<typename T,typename A1,typename A2,typename A3,typename A4>
+        inline T* heap_new(A1 const& a1,A2& a2,A3 const& a3,A4 const& a4)
+        {
+            return heap_new_impl<T,A1 const&,A2&,A3 const&,A4 const&>(a1,a2,a3,a4);
+        }
+        template<typename T,typename A1,typename A2,typename A3,typename A4>
+        inline T* heap_new(A1& a1,A2& a2,A3 const& a3,A4 const& a4)
+        {
+            return heap_new_impl<T,A1&,A2&,A3 const&,A4 const&>(a1,a2,a3,a4);
+        }
+
+        template<typename T,typename A1,typename A2,typename A3,typename A4>
+        inline T* heap_new(A1 const& a1,A2 const& a2,A3& a3,A4 const& a4)
+        {
+            return heap_new_impl<T,A1 const&,A2 const&,A3&,A4 const&>(a1,a2,a3,a4);
+        }
+        template<typename T,typename A1,typename A2,typename A3,typename A4>
+        inline T* heap_new(A1& a1,A2 const& a2,A3& a3,A4 const& a4)
+        {
+            return heap_new_impl<T,A1&,A2 const&,A3&,A4 const&>(a1,a2,a3,a4);
+        }
+        template<typename T,typename A1,typename A2,typename A3,typename A4>
+        inline T* heap_new(A1 const& a1,A2& a2,A3& a3,A4 const& a4)
+        {
+            return heap_new_impl<T,A1 const&,A2&,A3&,A4 const&>(a1,a2,a3,a4);
+        }
+        template<typename T,typename A1,typename A2,typename A3,typename A4>
+        inline T* heap_new(A1& a1,A2& a2,A3& a3,A4 const& a4)
+        {
+            return heap_new_impl<T,A1&,A2&,A3&,A4 const&>(a1,a2,a3,a4);
+        }
+        template<typename T,typename A1,typename A2,typename A3,typename A4>
+        inline T* heap_new(A1 const& a1,A2 const& a2,A3 const& a3,A4& a4)
+        {
+            return heap_new_impl<T,A1 const&,A2 const&,A3 const&,A4&>(a1,a2,a3,a4);
+        }
+        template<typename T,typename A1,typename A2,typename A3,typename A4>
+        inline T* heap_new(A1& a1,A2 const& a2,A3 const& a3,A4& a4)
+        {
+            return heap_new_impl<T,A1&,A2 const&,A3 const&,A4&>(a1,a2,a3,a4);
+        }
+        template<typename T,typename A1,typename A2,typename A3,typename A4>
+        inline T* heap_new(A1 const& a1,A2& a2,A3 const& a3,A4& a4)
+        {
+            return heap_new_impl<T,A1 const&,A2&,A3 const&,A4&>(a1,a2,a3,a4);
+        }
+        template<typename T,typename A1,typename A2,typename A3,typename A4>
+        inline T* heap_new(A1& a1,A2& a2,A3 const& a3,A4& a4)
+        {
+            return heap_new_impl<T,A1&,A2&,A3 const&,A4&>(a1,a2,a3,a4);
+        }
+
+        template<typename T,typename A1,typename A2,typename A3,typename A4>
+        inline T* heap_new(A1 const& a1,A2 const& a2,A3& a3,A4& a4)
+        {
+            return heap_new_impl<T,A1 const&,A2 const&,A3&,A4&>(a1,a2,a3,a4);
+        }
+        template<typename T,typename A1,typename A2,typename A3,typename A4>
+        inline T* heap_new(A1& a1,A2 const& a2,A3& a3,A4& a4)
+        {
+            return heap_new_impl<T,A1&,A2 const&,A3&,A4&>(a1,a2,a3,a4);
+        }
+        template<typename T,typename A1,typename A2,typename A3,typename A4>
+        inline T* heap_new(A1 const& a1,A2& a2,A3& a3,A4& a4)
+        {
+            return heap_new_impl<T,A1 const&,A2&,A3&,A4&>(a1,a2,a3,a4);
+        }
+        template<typename T,typename A1,typename A2,typename A3,typename A4>
+        inline T* heap_new(A1& a1,A2& a2,A3& a3,A4& a4)
+        {
+            return heap_new_impl<T,A1&,A2&,A3&,A4&>(a1,a2,a3,a4);
+        }
+        
+#endif        
+        template<typename T>
+        inline void heap_delete(T* data)
+        {
+            data->~T();
+            free_raw_heap_memory(data);
+        }
+
+        template<typename T>
+        struct do_heap_delete
+        {
+            void operator()(T* data) const
+            {
+                detail::heap_delete(data);
+            }
+        };
+    }
+}
+
+#include <boost/config/abi_suffix.hpp>
+
+
+#endif
diff --git a/deal.II/contrib/boost/include/boost/thread/win32/thread_primitives.hpp b/deal.II/contrib/boost/include/boost/thread/win32/thread_primitives.hpp
new file mode 100644 (file)
index 0000000..67a1bc3
--- /dev/null
@@ -0,0 +1,398 @@
+#ifndef BOOST_WIN32_THREAD_PRIMITIVES_HPP
+#define BOOST_WIN32_THREAD_PRIMITIVES_HPP
+
+//  win32_thread_primitives.hpp
+//
+//  (C) Copyright 2005-7 Anthony Williams 
+//  (C) Copyright 2007 David Deakins 
+//
+//  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 <boost/assert.hpp>
+#include <boost/thread/exceptions.hpp>
+#include <boost/detail/interlocked.hpp>
+#include <algorithm>
+
+#if defined( BOOST_USE_WINDOWS_H )
+# include <windows.h>
+
+namespace boost
+{
+    namespace detail
+    {
+        namespace win32
+        {
+            typedef ULONG_PTR ulong_ptr;
+            typedef HANDLE handle;
+            unsigned const infinite=INFINITE;
+            unsigned const timeout=WAIT_TIMEOUT;
+            handle const invalid_handle_value=INVALID_HANDLE_VALUE;
+
+# ifdef BOOST_NO_ANSI_APIS
+            using ::CreateMutexW;
+            using ::CreateEventW;
+            using ::CreateSemaphoreW;
+# else
+            using ::CreateMutexA;
+            using ::CreateEventA;
+            using ::CreateSemaphoreA;
+# endif
+            using ::CloseHandle;
+            using ::ReleaseMutex;
+            using ::ReleaseSemaphore;
+            using ::SetEvent;
+            using ::ResetEvent;
+            using ::WaitForMultipleObjects;
+            using ::WaitForSingleObject;
+            using ::GetCurrentProcessId;
+            using ::GetCurrentThreadId;
+            using ::GetCurrentThread;
+            using ::GetCurrentProcess;
+            using ::DuplicateHandle;
+            using ::SleepEx;
+            using ::Sleep;
+            using ::QueueUserAPC;
+            using ::GetTickCount;
+        }
+    }
+}
+#elif defined( WIN32 ) || defined( _WIN32 ) || defined( __WIN32__ )
+
+# ifdef UNDER_CE
+#  ifndef WINAPI
+#   ifndef _WIN32_WCE_EMULATION
+#    define WINAPI  __cdecl     // Note this doesn't match the desktop definition
+#   else
+#    define WINAPI  __stdcall
+#   endif
+#  endif
+
+#  ifdef __cplusplus
+extern "C" {
+#  endif
+typedef int BOOL;
+typedef unsigned long DWORD;
+typedef void* HANDLE;
+
+#  include <kfuncs.h>
+#  ifdef __cplusplus
+}
+#  endif
+# endif
+
+namespace boost
+{
+    namespace detail
+    {
+        namespace win32
+        {
+            
+# ifdef _WIN64
+            typedef unsigned __int64 ulong_ptr;
+# else
+            typedef unsigned long ulong_ptr;
+# endif
+            typedef void* handle;
+            unsigned const infinite=~0U;
+            unsigned const timeout=258U;
+            handle const invalid_handle_value=(handle)(-1);
+
+            extern "C"
+            {
+                struct _SECURITY_ATTRIBUTES;
+# ifdef BOOST_NO_ANSI_APIS
+                __declspec(dllimport) void* __stdcall CreateMutexW(_SECURITY_ATTRIBUTES*,int,wchar_t const*);
+                __declspec(dllimport) void* __stdcall CreateSemaphoreW(_SECURITY_ATTRIBUTES*,long,long,wchar_t const*);
+                __declspec(dllimport) void* __stdcall CreateEventW(_SECURITY_ATTRIBUTES*,int,int,wchar_t const*);
+# else
+                __declspec(dllimport) void* __stdcall CreateMutexA(_SECURITY_ATTRIBUTES*,int,char const*);
+                __declspec(dllimport) void* __stdcall CreateSemaphoreA(_SECURITY_ATTRIBUTES*,long,long,char const*);
+                __declspec(dllimport) void* __stdcall CreateEventA(_SECURITY_ATTRIBUTES*,int,int,char const*);
+# endif
+                __declspec(dllimport) int __stdcall CloseHandle(void*);
+                __declspec(dllimport) int __stdcall ReleaseMutex(void*);
+                __declspec(dllimport) unsigned long __stdcall WaitForSingleObject(void*,unsigned long);
+                __declspec(dllimport) unsigned long __stdcall WaitForMultipleObjects(unsigned long nCount,void* const * lpHandles,int bWaitAll,unsigned long dwMilliseconds);
+                __declspec(dllimport) int __stdcall ReleaseSemaphore(void*,long,long*);
+                __declspec(dllimport) int __stdcall DuplicateHandle(void*,void*,void*,void**,unsigned long,int,unsigned long);
+                __declspec(dllimport) unsigned long __stdcall SleepEx(unsigned long,int);
+                __declspec(dllimport) void __stdcall Sleep(unsigned long);
+                typedef void (__stdcall *queue_user_apc_callback_function)(ulong_ptr);
+                __declspec(dllimport) unsigned long __stdcall QueueUserAPC(queue_user_apc_callback_function,void*,ulong_ptr);
+
+                __declspec(dllimport) unsigned long __stdcall GetTickCount();
+
+# ifndef UNDER_CE
+                __declspec(dllimport) unsigned long __stdcall GetCurrentProcessId();
+                __declspec(dllimport) unsigned long __stdcall GetCurrentThreadId();
+                __declspec(dllimport) void* __stdcall GetCurrentThread();
+                __declspec(dllimport) void* __stdcall GetCurrentProcess();
+                __declspec(dllimport) int __stdcall SetEvent(void*);
+                __declspec(dllimport) int __stdcall ResetEvent(void*);
+# else
+                using ::GetCurrentProcessId;
+                using ::GetCurrentThreadId;
+                using ::GetCurrentThread;
+                using ::GetCurrentProcess;
+                using ::SetEvent;
+                using ::ResetEvent;
+# endif
+            }
+        }
+    }
+}
+#else
+# error "Win32 functions not available"
+#endif
+
+#include <boost/config/abi_prefix.hpp>
+
+namespace boost
+{
+    namespace detail
+    {
+        namespace win32
+        {
+            enum event_type
+            {
+                auto_reset_event=false,
+                manual_reset_event=true
+            };
+            
+            enum initial_event_state
+            {
+                event_initially_reset=false,
+                event_initially_set=true
+            };
+            
+            inline handle create_anonymous_event(event_type type,initial_event_state state)
+            {
+#if !defined(BOOST_NO_ANSI_APIS)  
+                handle const res=win32::CreateEventA(0,type,state,0);
+#else
+                handle const res=win32::CreateEventW(0,type,state,0);
+#endif                
+                if(!res)
+                {
+                    throw thread_resource_error();
+                }
+                return res;
+            }
+
+            inline handle create_anonymous_semaphore(long initial_count,long max_count)
+            {
+#if !defined(BOOST_NO_ANSI_APIS)  
+                handle const res=CreateSemaphoreA(0,initial_count,max_count,0);
+#else
+                handle const res=CreateSemaphoreW(0,initial_count,max_count,0);
+#endif               
+                if(!res)
+                {
+                    throw thread_resource_error();
+                }
+                return res;
+            }
+
+            inline handle duplicate_handle(handle source)
+            {
+                handle const current_process=GetCurrentProcess();
+                long const same_access_flag=2;
+                handle new_handle=0;
+                bool const success=DuplicateHandle(current_process,source,current_process,&new_handle,0,false,same_access_flag)!=0;
+                if(!success)
+                {
+                    throw thread_resource_error();
+                }
+                return new_handle;
+            }
+
+            inline void release_semaphore(handle semaphore,long count)
+            {
+                BOOST_VERIFY(ReleaseSemaphore(semaphore,count,0)!=0);
+            }
+
+            class handle_manager
+            {
+            private:
+                handle handle_to_manage;
+                handle_manager(handle_manager&);
+                handle_manager& operator=(handle_manager&);
+
+                void cleanup()
+                {
+                    if(handle_to_manage && handle_to_manage!=invalid_handle_value)
+                    {
+                        BOOST_VERIFY(CloseHandle(handle_to_manage));
+                    }
+                }
+                
+            public:
+                explicit handle_manager(handle handle_to_manage_):
+                    handle_to_manage(handle_to_manage_)
+                {}
+                handle_manager():
+                    handle_to_manage(0)
+                {}
+                
+                handle_manager& operator=(handle new_handle)
+                {
+                    cleanup();
+                    handle_to_manage=new_handle;
+                    return *this;
+                }
+
+                operator handle() const
+                {
+                    return handle_to_manage;
+                }
+
+                handle duplicate() const
+                {
+                    return duplicate_handle(handle_to_manage);
+                }
+
+                void swap(handle_manager& other)
+                {
+                    std::swap(handle_to_manage,other.handle_to_manage);
+                }
+
+                handle release()
+                {
+                    handle const res=handle_to_manage;
+                    handle_to_manage=0;
+                    return res;
+                }
+
+                bool operator!() const
+                {
+                    return !handle_to_manage;
+                }
+                
+                ~handle_manager()
+                {
+                    cleanup();
+                }
+            };
+            
+        }
+    }
+}
+
+#if defined(BOOST_MSVC) && (_MSC_VER>=1400)  && !defined(UNDER_CE)
+
+namespace boost
+{
+    namespace detail
+    {
+        namespace win32
+        {
+#if _MSC_VER==1400
+            extern "C" unsigned char _interlockedbittestandset(long *a,long b);
+            extern "C" unsigned char _interlockedbittestandreset(long *a,long b);
+#else
+            extern "C" unsigned char _interlockedbittestandset(volatile long *a,long b);
+            extern "C" unsigned char _interlockedbittestandreset(volatile long *a,long b);
+#endif
+
+#pragma intrinsic(_interlockedbittestandset)
+#pragma intrinsic(_interlockedbittestandreset)
+
+            inline bool interlocked_bit_test_and_set(long* x,long bit)
+            {
+                return _interlockedbittestandset(x,bit)!=0;
+            }
+
+            inline bool interlocked_bit_test_and_reset(long* x,long bit)
+            {
+                return _interlockedbittestandreset(x,bit)!=0;
+            }
+            
+        }
+    }
+}
+#define BOOST_THREAD_BTS_DEFINED
+#elif (defined(BOOST_MSVC) || defined(BOOST_INTEL_WIN)) && defined(_M_IX86)
+namespace boost
+{
+    namespace detail
+    {
+        namespace win32
+        {
+            inline bool interlocked_bit_test_and_set(long* x,long bit)
+            {
+                __asm {
+                    mov eax,bit;
+                    mov edx,x;
+                    lock bts [edx],eax;
+                    setc al;
+                };          
+            }
+
+            inline bool interlocked_bit_test_and_reset(long* x,long bit)
+            {
+                __asm {
+                    mov eax,bit;
+                    mov edx,x;
+                    lock btr [edx],eax;
+                    setc al;
+                };          
+            }
+            
+        }
+    }
+}
+#define BOOST_THREAD_BTS_DEFINED
+#endif
+
+#ifndef BOOST_THREAD_BTS_DEFINED
+
+namespace boost
+{
+    namespace detail
+    {
+        namespace win32
+        {
+            inline bool interlocked_bit_test_and_set(long* x,long bit)
+            {
+                long const value=1<<bit;
+                long old=*x;
+                do
+                {
+                    long const current=BOOST_INTERLOCKED_COMPARE_EXCHANGE(x,old|value,old);
+                    if(current==old)
+                    {
+                        break;
+                    }
+                    old=current;
+                }
+                while(true);
+                return (old&value)!=0;
+            }
+
+            inline bool interlocked_bit_test_and_reset(long* x,long bit)
+            {
+                long const value=1<<bit;
+                long old=*x;
+                do
+                {
+                    long const current=BOOST_INTERLOCKED_COMPARE_EXCHANGE(x,old&~value,old);
+                    if(current==old)
+                    {
+                        break;
+                    }
+                    old=current;
+                }
+                while(true);
+                return (old&value)!=0;
+            }
+        }
+    }
+}
+#endif
+
+#include <boost/config/abi_suffix.hpp>
+
+#endif
diff --git a/deal.II/contrib/boost/include/boost/thread/xtime.hpp b/deal.II/contrib/boost/include/boost/thread/xtime.hpp
new file mode 100644 (file)
index 0000000..7cc6272
--- /dev/null
@@ -0,0 +1,92 @@
+// Copyright (C) 2001-2003
+// William E. Kempf
+// Copyright (C) 2007-8 Anthony Williams
+//
+//  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)
+
+#ifndef BOOST_XTIME_WEK070601_HPP
+#define BOOST_XTIME_WEK070601_HPP
+
+#include <boost/thread/detail/config.hpp>
+
+#include <boost/cstdint.hpp>
+#include <boost/thread/thread_time.hpp>
+#include <boost/date_time/posix_time/conversion.hpp>
+
+#include <boost/config/abi_prefix.hpp>
+
+namespace boost {
+
+enum xtime_clock_types
+{
+    TIME_UTC=1
+//    TIME_TAI,
+//    TIME_MONOTONIC,
+//    TIME_PROCESS,
+//    TIME_THREAD,
+//    TIME_LOCAL,
+//    TIME_SYNC,
+//    TIME_RESOLUTION
+};
+
+struct xtime
+{
+#if defined(BOOST_NO_INT64_T)
+    typedef int_fast32_t xtime_sec_t; //INT_FAST32_MIN <= sec <= INT_FAST32_MAX
+#else
+    typedef int_fast64_t xtime_sec_t; //INT_FAST64_MIN <= sec <= INT_FAST64_MAX
+#endif
+
+    typedef int_fast32_t xtime_nsec_t; //0 <= xtime.nsec < NANOSECONDS_PER_SECOND
+
+    xtime_sec_t sec;
+    xtime_nsec_t nsec;
+
+    operator system_time() const
+    {
+        return boost::posix_time::from_time_t(0)+
+            boost::posix_time::seconds(static_cast<long>(sec))+
+#ifdef BOOST_DATE_TIME_HAS_NANOSECONDS
+            boost::posix_time::nanoseconds(nsec);
+#else
+        boost::posix_time::microseconds((nsec+500)/1000);
+#endif
+    }
+    
+};
+
+inline xtime get_xtime(boost::system_time const& abs_time)
+{
+    xtime res;
+    boost::posix_time::time_duration const time_since_epoch=abs_time-boost::posix_time::from_time_t(0);
+            
+    res.sec=static_cast<xtime::xtime_sec_t>(time_since_epoch.total_seconds());
+    res.nsec=static_cast<xtime::xtime_nsec_t>(time_since_epoch.fractional_seconds()*(1000000000/time_since_epoch.ticks_per_second()));
+    return res;
+}
+
+inline int xtime_get(struct xtime* xtp, int clock_type)
+{
+    if (clock_type == TIME_UTC)
+    {
+        *xtp=get_xtime(get_system_time());
+        return clock_type;
+    }
+    return 0;
+}
+
+
+inline int xtime_cmp(const xtime& xt1, const xtime& xt2)
+{
+    if (xt1.sec == xt2.sec)
+        return (int)(xt1.nsec - xt2.nsec);
+    else 
+        return (xt1.sec > xt2.sec) ? 1 : -1;
+}
+
+} // namespace boost
+
+#include <boost/config/abi_suffix.hpp>
+
+#endif //BOOST_XTIME_WEK070601_HPP
diff --git a/deal.II/contrib/boost/libs/thread/build/Jamfile.v2 b/deal.II/contrib/boost/libs/thread/build/Jamfile.v2
new file mode 100644 (file)
index 0000000..e69ff90
--- /dev/null
@@ -0,0 +1,208 @@
+# $Id: Jamfile.v2 42230 2007-12-21 11:51:05Z anthonyw $
+# Copyright 2006-2007 Roland Schwarz.
+# Copyright 2007 Anthony Williams
+# 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)
+
+#########################################################################
+# The boost threading library can be built on top of different API's
+# Currently this is the win32 API and the pthreads API.
+# Pthread is native on unix variants.
+# To get pthread on windows you need the pthread win32 library
+# http://sourceware.org/pthreads-win32 which is available under LGPL.
+#
+# You need to provide the include path and lib path in the variables
+# PTW32_INCLUDE and PTW32_LIB respectively. You can specify these
+# paths in site-config.jam, user-config.jam or in the environment.
+# A new feature is provided to request a specific API:
+# <threadapi>win32 and <threadapi)pthread.
+#
+# The naming of the resulting libraries is mostly the same for the
+# variant native to the build platform, i.e.
+# boost_thread and the boost specific tagging.
+# For the library variant that is not native on the build platform
+# an additional tag is applied:
+# boost_thread_pthread for the pthread variant on windows, and
+# boost_thread_win32 for the win32 variant (likely when built on cygwin).
+#
+# To request the pthread variant on windows, from boost root you would
+# say e.g:
+# bjam msvc-8.0 --with-thread install threadapi=pthread
+#########################################################################
+
+import os ;
+import feature ;
+import indirect ;
+import path ;
+
+project boost/thread
+    : source-location ../src
+    : requirements <threading>multi
+      <link>static:<define>BOOST_THREAD_BUILD_LIB=1
+      <link>shared:<define>BOOST_THREAD_BUILD_DLL=1
+      -<tag>@$(BOOST_JAMROOT_MODULE)%$(BOOST_JAMROOT_MODULE).tag
+      <tag>@$(__name__).tag
+    : default-build <threading>multi
+    ;
+
+local rule default_threadapi ( )
+{
+    local api = pthread ;
+    if [ os.name ] = "NT" { api = win32 ; }
+    return $(api) ;
+}
+
+feature.feature threadapi : pthread win32 : propagated ;
+feature.set-default threadapi : [ default_threadapi ] ;
+
+rule tag ( name : type ? : property-set )
+{
+    local result = $(name) ;
+    
+    if $(type) in STATIC_LIB SHARED_LIB IMPORT_LIB
+    {
+        local api = [ $(property-set).get <threadapi> ] ;
+        
+        # non native api gets additional tag
+        if $(api) != [ default_threadapi ] {
+            result = $(result)_$(api) ;
+        }
+    }
+    
+    # forward to the boost tagging rule
+    return  [ indirect.call $(BOOST_JAMROOT_MODULE)%$(BOOST_JAMROOT_MODULE).tag 
+                $(result) : $(type) : $(property-set) ] ;
+}
+
+rule win32_pthread_paths ( properties * )
+{
+    local result ;
+    local PTW32_INCLUDE ;
+    local PTW32_LIB ;
+    PTW32_INCLUDE  = [ modules.peek             : PTW32_INCLUDE ] ;
+    PTW32_LIB      = [ modules.peek             : PTW32_LIB     ] ;
+    PTW32_INCLUDE ?= [ modules.peek user-config : PTW32_INCLUDE ] ;
+    PTW32_LIB     ?= [ modules.peek user-config : PTW32_LIB     ] ;
+    PTW32_INCLUDE ?= [ modules.peek site-config : PTW32_INCLUDE ] ;
+    PTW32_LIB     ?= [ modules.peek site-config : PTW32_LIB     ] ;
+
+    if ! ( $(PTW32_INCLUDE) && $(PTW32_LIB) )
+    {
+        if  ! $(.notified)
+        {
+            echo "************************************************************" ;
+            echo "Trying to build Boost.Thread with pthread support."           ;
+            echo "If you need pthread you should specify the paths."            ;
+            echo "You can specify them in site-config.jam, user-config.jam"     ;
+            echo "or in the environment."                                       ;
+            echo "For example:"                                                 ;
+            echo "PTW32_INCLUDE=C:\\Program Files\\ptw32\\Pre-built2\\include"  ;
+            echo "PTW32_LIB=C:\\Program Files\\ptw32\\Pre-built2\\lib"          ;
+            echo "************************************************************" ;
+            .notified = true ;
+        }
+    }
+    else
+    {
+        local include_path = [ path.make $(PTW32_INCLUDE) ] ;
+        local lib_path = [ path.make $(PTW32_LIB) ] ;
+        local libname = pthread ;
+        if <toolset>msvc in $(properties)
+        {
+            libname = $(libname)VC2.lib ;
+        }
+        if <toolset>gcc in $(properties)
+        {
+            libname = lib$(libname)GC2.a ;
+        }
+        lib_path = [ path.glob $(lib_path) : $(libname) ] ;
+        if ! $(lib_path)
+        {
+            if  ! $(.notified)
+            {
+                echo "************************************************************" ;
+                echo "Trying to build Boost.Thread with pthread support."           ;
+                echo "But the library" $(libname) "could not be found in path"      ;
+                echo $(PTW32_LIB)                                                   ;
+                echo "************************************************************" ;
+                .notified = true ;
+            }
+        }
+        else 
+        {
+            result += <include>$(include_path) ;
+            result += <library>$(lib_path) ;
+        }
+    }
+    return $(result) ;
+}
+
+rule usage-requirements ( properties * )
+{
+    local result ;
+    if <threadapi>pthread in $(properties)
+    {
+        result += <define>BOOST_THREAD_POSIX ;
+        if <target-os>windows in $(properties)
+        {
+            result += [ win32_pthread_paths $(properties) ] ;
+            # TODO: What is for static linking? Is the <library> also needed
+            # in that case?
+        }
+    }
+    return $(result) ;
+}
+
+rule requirements ( properties * )
+{
+    local result ;
+
+    if <threadapi>pthread in $(properties)
+    {
+        result += <define>BOOST_THREAD_POSIX ;
+        if <target-os>windows in $(properties) 
+        {
+            local paths = [ win32_pthread_paths $(properties) ] ;
+            if $(paths)
+            {
+                result += $(paths) ;
+            }
+            else
+            {
+                result = <build>no ;
+            }
+        }
+    }
+    return $(result) ;
+}
+
+alias thread_sources
+    : ## win32 sources ##
+      win32/thread.cpp
+      win32/exceptions.cpp
+      win32/tss_dll.cpp
+      win32/tss_pe.cpp
+    : ## requirements ##
+      <threadapi>win32
+    ;
+
+alias thread_sources
+    : ## pthread sources ##
+      pthread/thread.cpp
+      pthread/exceptions.cpp
+      pthread/once.cpp
+    : ## requirements ##
+      <threadapi>pthread
+    ;
+
+explicit thread_sources ;
+
+lib boost_thread
+    : thread_sources
+    : <conditional>@requirements
+    :
+    : <link>shared:<define>BOOST_THREAD_USE_DLL=1
+      <link>static:<define>BOOST_THREAD_USE_LIB=1
+      <conditional>@usage-requirements
+    ;
diff --git a/deal.II/contrib/boost/libs/thread/doc/Jamfile.v2 b/deal.II/contrib/boost/libs/thread/doc/Jamfile.v2
new file mode 100644 (file)
index 0000000..dc68fc3
--- /dev/null
@@ -0,0 +1,55 @@
+# (C) Copyright 2008 Anthony Williams
+#
+# 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)
+
+path-constant boost-images : ../../../doc/src/images ;
+
+xml thread : thread.qbk ;
+
+boostbook standalone
+    :
+        thread
+    :
+        # HTML options first:
+        # Use graphics not text for navigation:
+        <xsl:param>navig.graphics=1
+        # How far down we chunk nested sections, basically all of them:
+        <xsl:param>chunk.section.depth=3
+        # Don't put the first section on the same page as the TOC:
+        <xsl:param>chunk.first.sections=1
+        # How far down sections get TOC's
+        <xsl:param>toc.section.depth=10
+        # Max depth in each TOC:
+        <xsl:param>toc.max.depth=3
+        # How far down we go with TOC's
+        <xsl:param>generate.section.toc.level=10
+        # Path for links to Boost:
+        <xsl:param>boost.root=../../../..
+        # Path for libraries index:
+        <xsl:param>boost.libraries=../../../../libs/libraries.htm
+        # Use the main Boost stylesheet:
+        <xsl:param>html.stylesheet=../../../../doc/html/boostbook.css
+        
+        # PDF Options:
+        # TOC Generation: this is needed for FOP-0.9 and later:
+        #<xsl:param>fop1.extensions=1
+        # Or enable this if you're using XEP:
+        <xsl:param>xep.extensions=1
+        # TOC generation: this is needed for FOP 0.2, but must not be set to zero for FOP-0.9!
+        <xsl:param>fop.extensions=0
+        # No indent on body text:
+        <xsl:param>body.start.indent=0pt
+        # Margin size:
+        <xsl:param>page.margin.inner=0.5in
+        # Margin size:
+        <xsl:param>page.margin.outer=0.5in
+        # Yes, we want graphics for admonishments:
+        <xsl:param>admon.graphics=1
+        # Set this one for PDF generation *only*:
+        # default pnd graphics are awful in PDF form,
+        # better use SVG's instead:
+        <format>pdf:<xsl:param>admon.graphics.extension=".svg"
+        <format>pdf:<xsl:param>admon.graphics.path=$(boost-images)/
+    ;
+
diff --git a/deal.II/contrib/boost/libs/thread/doc/acknowledgements.qbk b/deal.II/contrib/boost/libs/thread/doc/acknowledgements.qbk
new file mode 100644 (file)
index 0000000..1f21921
--- /dev/null
@@ -0,0 +1,23 @@
+[/
+  (C) Copyright 2007-8 Anthony Williams.
+  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).
+]
+
+[section:acknowledgements Acknowledgments]
+
+The original implementation of __boost_thread__ was written by William Kempf, with contributions from numerous others. This new
+version initially grew out of an attempt to rewrite __boost_thread__ to William Kempf's design with fresh code that could be
+released under the Boost Software License. However, as the C++ Standards committee have been actively discussing standardizing a
+thread library for C++, this library has evolved to reflect the proposals, whilst retaining as much backwards-compatibility as
+possible.
+
+Particular thanks must be given to Roland Schwarz, who contributed a lot of time and code to the original __boost_thread__ library,
+and who has been actively involved with the rewrite. The scheme for dividing the platform-specific implementations into separate
+directories was devised by Roland, and his input has contributed greatly to improving the quality of the current implementation.
+
+Thanks also must go to Peter Dimov, Howard Hinnant, Alexander Terekhov, Chris Thomasson and others for their comments on the
+implementation details of the code.
+
+[endsect]
diff --git a/deal.II/contrib/boost/libs/thread/doc/barrier.qbk b/deal.II/contrib/boost/libs/thread/doc/barrier.qbk
new file mode 100644 (file)
index 0000000..7e7c3e1
--- /dev/null
@@ -0,0 +1,72 @@
+[/
+  (C) Copyright 2007-8 Anthony Williams.
+  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).
+]
+
+[section:barriers Barriers]
+
+A barrier is a simple concept. Also known as a ['rendezvous], it is a synchronization point between multiple threads. The barrier is
+configured for a particular number of threads (`n`), and as threads reach the barrier they must wait until all `n` threads have
+arrived. Once the `n`-th thread has reached the barrier, all the waiting threads can proceed, and the barrier is reset.
+
+[section:barrier Class `barrier`]
+
+    #include <boost/thread/barrier.hpp>
+
+    class barrier
+    {
+    public:
+        barrier(unsigned int count);
+        ~barrier();
+
+        bool wait();
+    };
+
+Instances of __barrier__ are not copyable or movable.
+
+[heading Constructor]
+
+    barrier(unsigned int count);
+
+[variablelist
+
+[[Effects:] [Construct a barrier for `count` threads.]]
+
+[[Throws:] [__thread_resource_error__ if an error occurs.]]
+
+]
+
+[heading Destructor]
+
+    ~barrier();
+
+[variablelist
+
+[[Precondition:] [No threads are waiting on `*this`.]]
+
+[[Effects:] [Destroys `*this`.]]
+
+[[Throws:] [Nothing.]]
+
+]
+
+[heading Member function `wait`]
+
+    bool wait();
+
+[variablelist
+
+[[Effects:] [Block until `count` threads have called `wait` on `*this`. When the `count`-th thread calls `wait`, all waiting threads
+are unblocked, and the barrier is reset. ]]
+
+[[Returns:] [`true` for exactly one thread from each batch of waiting threads, `false` otherwise.]]
+
+[[Throws:] [__thread_resource_error__ if an error occurs.]]
+
+]
+
+[endsect]
+
+[endsect]
diff --git a/deal.II/contrib/boost/libs/thread/doc/changes.qbk b/deal.II/contrib/boost/libs/thread/doc/changes.qbk
new file mode 100644 (file)
index 0000000..25ae147
--- /dev/null
@@ -0,0 +1,83 @@
+[/
+  (C) Copyright 2007-8 Anthony Williams.
+  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).
+]
+
+[section:changes Changes since boost 1.35]
+
+The 1.36.0 release of Boost includes a few new features in the thread library:
+
+* New generic __lock_multiple_ref__ and __try_lock_multiple_ref__ functions for locking multiple mutexes at once.
+
+* Rvalue reference support for move semantics where the compilers supports it.
+
+* A few bugs fixed and missing functions added (including the serious win32 condition variable bug).
+
+* `scoped_try_lock` types are now backwards-compatible with Boost 1.34.0 and previous releases.
+
+* Support for passing function arguments to the thread function by supplying additional arguments to the __thread__ constructor.
+
+* Backwards-compatibility overloads added for `timed_lock` and `timed_wait` functions to allow use of `xtime` for timeouts.
+
+[heading Changes since boost 1.34]
+
+Almost every line of code in __boost_thread__ has been changed since the 1.34 release of boost. However, most of the interface
+changes have been extensions, so the new code is largely backwards-compatible with the old code. The new features and breaking
+changes are described below.
+
+[heading New Features]
+
+* Instances of __thread__ and of the various lock types are now movable.
+
+* Threads can be interrupted at __interruption_points__.
+
+* Condition variables can now be used with any type that implements the __lockable_concept__, through the use of
+`boost::condition_variable_any` (`boost::condition` is a `typedef` to `boost::condition_variable_any`, provided for backwards
+compatibility). `boost::condition_variable` is provided as an optimization, and will only work with
+`boost::unique_lock<boost::mutex>` (`boost::mutex::scoped_lock`).
+
+* Thread IDs are separated from __thread__, so a thread can obtain it's own ID (using `boost::this_thread::get_id()`), and IDs can
+be used as keys in associative containers, as they have the full set of comparison operators.
+
+* Timeouts are now implemented using the Boost DateTime library, through a typedef `boost::system_time` for absolute timeouts, and
+with support for relative timeouts in many cases. `boost::xtime` is supported for backwards compatibility only.
+
+* Locks are implemented as publicly accessible templates `boost::lock_guard`, `boost::unique_lock`, `boost::shared_lock`, and
+`boost::upgrade_lock`, which are templated on the type of the mutex. The __lockable_concept__ has been extended to include publicly
+available __lock_ref__ and __unlock_ref__ member functions, which are used by the lock types.
+
+[heading Breaking Changes]
+
+The list below should cover all changes to the public interface which break backwards compatibility.
+
+* __try_mutex__ has been removed, and the functionality subsumed into __mutex__. __try_mutex__ is left as a `typedef`,
+but is no longer a separate class.
+
+* __recursive_try_mutex__ has been removed, and the functionality subsumed into
+__recursive_mutex__. __recursive_try_mutex__ is left as a `typedef`, but is no longer a separate class.
+
+* `boost::detail::thread::lock_ops` has been removed. Code that relies on the `lock_ops` implementation detail will no longer work,
+as this has been removed, as it is no longer necessary now that mutex types now have public __lock_ref__ and __unlock_ref__ member
+functions.
+
+* `scoped_lock` constructors with a second parameter of type `bool` are no longer provided. With previous boost releases,
+``boost::mutex::scoped_lock some_lock(some_mutex,false);`` could be used to create a lock object that was associated with a mutex,
+but did not lock it on construction. This facility has now been replaced with the constructor that takes a
+`boost::defer_lock_type` as the second parameter: ``boost::mutex::scoped_lock some_lock(some_mutex,boost::defer_lock);``
+
+* The `locked()` member function of the `scoped_lock` types has been renamed to __owns_lock_ref__.
+
+* You can no longer obtain a __thread__ instance representing the current thread: a default-constructed __thread__ object is not
+associated with any thread. The only use for such a thread object was to support the comparison operators: this functionality has
+been moved to __thread_id__.
+
+* The broken `boost::read_write_mutex` has been replaced with __shared_mutex__.
+
+* __mutex__ is now never recursive. For Boost releases prior to 1.35 __mutex__ was recursive on Windows and not on POSIX platforms.
+
+* When using a __recursive_mutex__ with a call to [cond_any_wait_link `boost::condition_variable_any::wait()`], the mutex is only
+  unlocked one level, and not completely. This prior behaviour was not guaranteed and did not feature in the tests.
+
+[endsect]
diff --git a/deal.II/contrib/boost/libs/thread/doc/condition_variables.qbk b/deal.II/contrib/boost/libs/thread/doc/condition_variables.qbk
new file mode 100644 (file)
index 0000000..e54dd34
--- /dev/null
@@ -0,0 +1,513 @@
+[/
+  (C) Copyright 2007-8 Anthony Williams.
+  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).
+]
+
+[section:condvar_ref Condition Variables]
+
+[heading Synopsis]
+
+The classes `condition_variable` and `condition_variable_any` provide a
+mechanism for one thread to wait for notification from another thread that a
+particular condition has become true. The general usage pattern is that one
+thread locks a mutex and then calls `wait` on an instance of
+`condition_variable` or `condition_variable_any`. When the thread is woken from
+the wait, then it checks to see if the appropriate condition is now true, and
+continues if so. If the condition is not true, then the thread then calls `wait`
+again to resume waiting. In the simplest case, this condition is just a boolean
+variable:
+
+    boost::condition_variable cond;
+    boost::mutex mut;
+    bool data_ready;
+
+    void process_data();
+
+    void wait_for_data_to_process()
+    {
+        boost::unique_lock<boost::mutex> lock(mut);
+        while(!data_ready)
+        {
+            cond.wait(lock);
+        }
+        process_data();
+    }
+
+Notice that the `lock` is passed to `wait`: `wait` will atomically add the
+thread to the set of threads waiting on the condition variable, and unlock the
+mutex. When the thread is woken, the mutex will be locked again before the call
+to `wait` returns. This allows other threads to acquire the mutex in order to
+update the shared data, and ensures that the data associated with the condition
+is correctly synchronized.
+
+In the mean time, another thread sets the condition to `true`, and then calls
+either `notify_one` or `notify_all` on the condition variable to wake one
+waiting thread or all the waiting threads respectively.
+
+    void retrieve_data();
+    void prepare_data();
+
+    void prepare_data_for_processing()
+    {
+        retrieve_data();
+        prepare_data();
+        {
+            boost::lock_guard<boost::mutex> lock(mut);
+            data_ready=true;
+        }
+        cond.notify_one();
+    }
+
+Note that the same mutex is locked before the shared data is updated, but that
+the mutex does not have to be locked across the call to `notify_one`.
+
+This example uses an object of type `condition_variable`, but would work just as
+well with an object of type `condition_variable_any`: `condition_variable_any`
+is more general, and will work with any kind of lock or mutex, whereas
+`condition_variable` requires that the lock passed to `wait` is an instance of
+`boost::unique_lock<boost::mutex>`. This enables `condition_variable` to make
+optimizations in some cases, based on the knowledge of the mutex type;
+`condition_variable_any` typically has a more complex implementation than
+`condition_variable`.
+
+[section:condition_variable Class `condition_variable`]
+
+    #include <boost/thread/condition_variable.hpp>
+
+    namespace boost
+    {
+        class condition_variable
+        {
+        public:
+            condition_variable();
+            ~condition_variable();
+
+            void notify_one();
+            void notify_all();
+
+            void wait(boost::unique_lock<boost::mutex>& lock);
+
+            template<typename predicate_type>
+            void wait(boost::unique_lock<boost::mutex>& lock,predicate_type predicate);
+
+            bool timed_wait(boost::unique_lock<boost::mutex>& lock,boost::system_time const& abs_time);
+
+            template<typename duration_type>
+            bool timed_wait(boost::unique_lock<boost::mutex>& lock,duration_type const& rel_time);
+
+            template<typename predicate_type>
+            bool timed_wait(boost::unique_lock<boost::mutex>& lock,boost::system_time const& abs_time,predicate_type predicate);
+
+            template<typename duration_type,typename predicate_type>
+            bool timed_wait(boost::unique_lock<boost::mutex>& lock,duration_type const& rel_time,predicate_type predicate);
+
+        // backwards compatibility
+
+            bool timed_wait(boost::unique_lock<boost::mutex>& lock,boost::xtime const& abs_time);
+
+            template<typename predicate_type>
+            bool timed_wait(boost::unique_lock<boost::mutex>& lock,boost::xtime const& abs_time,predicate_type predicate);
+        };
+    }
+
+[section:constructor `condition_variable()`]
+
+[variablelist
+
+[[Effects:] [Constructs an object of class `condition_variable`.]]
+
+[[Throws:] [__thread_resource_error__ if an error occurs.]]
+
+]
+
+[endsect]
+
+[section:destructor `~condition_variable()`]
+
+[variablelist
+
+[[Precondition:] [All threads waiting on `*this` have been notified by a call to
+`notify_one` or `notify_all` (though the respective calls to `wait` or
+`timed_wait` need not have returned).]]
+
+[[Effects:] [Destroys the object.]]
+
+[[Throws:] [Nothing.]]
+
+]
+
+[endsect]
+
+[section:notify_one `void notify_one()`]
+
+[variablelist
+
+[[Effects:] [If any threads are currently __blocked__ waiting on `*this` in a call
+to `wait` or `timed_wait`, unblocks one of those threads.]]
+
+[[Throws:] [Nothing.]]
+
+]
+
+[endsect]
+
+[section:notify_all `void notify_all()`]
+
+[variablelist
+
+[[Effects:] [If any threads are currently __blocked__ waiting on `*this` in a call
+to `wait` or `timed_wait`, unblocks all of those threads.]]
+
+[[Throws:] [Nothing.]]
+
+]
+
+[endsect]
+
+[section:wait `void wait(boost::unique_lock<boost::mutex>& lock)`]
+
+[variablelist
+
+[[Precondition:] [`lock` is locked by the current thread, and either no other
+thread is currently waiting on `*this`, or the execution of the `mutex()` member
+function on the `lock` objects supplied in the calls to `wait` or `timed_wait`
+in all the threads currently waiting on `*this` would return the same value as
+`lock->mutex()` for this call to `wait`.]]
+
+[[Effects:] [Atomically call `lock.unlock()` and blocks the current thread. The
+thread will unblock when notified by a call to `this->notify_one()` or
+`this->notify_all()`, or spuriously. When the thread is unblocked (for whatever
+reason), the lock is reacquired by invoking `lock.lock()` before the call to
+`wait` returns. The lock is also reacquired by invoking `lock.lock()` if the
+function exits with an exception.]]
+
+[[Postcondition:] [`lock` is locked by the current thread.]]
+
+[[Throws:] [__thread_resource_error__ if an error
+occurs. __thread_interrupted__ if the wait was interrupted by a call to
+__interrupt__ on the __thread__ object associated with the current thread of execution.]]
+
+]
+
+[endsect]
+
+[section:wait_predicate `template<typename predicate_type> void wait(boost::unique_lock<boost::mutex>& lock, predicate_type pred)`]
+
+[variablelist
+
+[[Effects:] [As-if ``
+while(!pred())
+{
+    wait(lock);
+}
+``]]
+
+]
+
+[endsect]
+
+[section:timed_wait `bool timed_wait(boost::unique_lock<boost::mutex>& lock,boost::system_time const& abs_time)`]
+
+[variablelist
+
+[[Precondition:] [`lock` is locked by the current thread, and either no other
+thread is currently waiting on `*this`, or the execution of the `mutex()` member
+function on the `lock` objects supplied in the calls to `wait` or `timed_wait`
+in all the threads currently waiting on `*this` would return the same value as
+`lock->mutex()` for this call to `wait`.]]
+
+[[Effects:] [Atomically call `lock.unlock()` and blocks the current thread. The
+thread will unblock when notified by a call to `this->notify_one()` or
+`this->notify_all()`, when the time as reported by `boost::get_system_time()`
+would be equal to or later than the specified `abs_time`, or spuriously. When
+the thread is unblocked (for whatever reason), the lock is reacquired by
+invoking `lock.lock()` before the call to `wait` returns. The lock is also
+reacquired by invoking `lock.lock()` if the function exits with an exception.]]
+
+[[Returns:] [`false` if the call is returning because the time specified by
+`abs_time` was reached, `true` otherwise.]]
+
+[[Postcondition:] [`lock` is locked by the current thread.]]
+
+[[Throws:] [__thread_resource_error__ if an error
+occurs. __thread_interrupted__ if the wait was interrupted by a call to
+__interrupt__ on the __thread__ object associated with the current thread of execution.]]
+
+]
+
+[endsect]
+
+[section:timed_wait_rel `template<typename duration_type> bool timed_wait(boost::unique_lock<boost::mutex>& lock,duration_type const& rel_time)`]
+
+[variablelist
+
+[[Precondition:] [`lock` is locked by the current thread, and either no other
+thread is currently waiting on `*this`, or the execution of the `mutex()` member
+function on the `lock` objects supplied in the calls to `wait` or `timed_wait`
+in all the threads currently waiting on `*this` would return the same value as
+`lock->mutex()` for this call to `wait`.]]
+
+[[Effects:] [Atomically call `lock.unlock()` and blocks the current thread. The
+thread will unblock when notified by a call to `this->notify_one()` or
+`this->notify_all()`, after the period of time indicated by the `rel_time`
+argument has elapsed, or spuriously. When the thread is unblocked (for whatever
+reason), the lock is reacquired by invoking `lock.lock()` before the call to
+`wait` returns. The lock is also reacquired by invoking `lock.lock()` if the
+function exits with an exception.]]
+
+[[Returns:] [`false` if the call is returning because the time period specified
+by `rel_time` has elapsed, `true` otherwise.]]
+
+[[Postcondition:] [`lock` is locked by the current thread.]]
+
+[[Throws:] [__thread_resource_error__ if an error
+occurs. __thread_interrupted__ if the wait was interrupted by a call to
+__interrupt__ on the __thread__ object associated with the current thread of execution.]]
+
+]
+
+[note The duration overload of timed_wait is difficult to use correctly. The overload taking a predicate should be preferred in most cases.]
+
+[endsect]
+
+[section:timed_wait_predicate `template<typename predicate_type> bool timed_wait(boost::unique_lock<boost::mutex>& lock, boost::system_time const& abs_time, predicate_type pred)`]
+
+[variablelist
+
+[[Effects:] [As-if ``
+while(!pred())
+{
+    if(!timed_wait(lock,abs_time))
+    {
+        return pred();
+    }
+}
+return true;
+``]]
+
+]
+
+[endsect]
+
+
+[endsect]
+
+[section:condition_variable_any Class `condition_variable_any`]
+
+    #include <boost/thread/condition_variable.hpp>
+
+    namespace boost
+    {
+        class condition_variable_any
+        {
+        public:
+            condition_variable_any();
+            ~condition_variable_any();
+
+            void notify_one();
+            void notify_all();
+
+            template<typename lock_type>
+            void wait(lock_type& lock);
+
+            template<typename lock_type,typename predicate_type>
+            void wait(lock_type& lock,predicate_type predicate);
+
+            template<typename lock_type>
+            bool timed_wait(lock_type& lock,boost::system_time const& abs_time);
+
+            template<typename lock_type,typename duration_type>
+            bool timed_wait(lock_type& lock,duration_type const& rel_time);
+
+            template<typename lock_type,typename predicate_type>
+            bool timed_wait(lock_type& lock,boost::system_time const& abs_time,predicate_type predicate);
+
+            template<typename lock_type,typename duration_type,typename predicate_type>
+            bool timed_wait(lock_type& lock,duration_type const& rel_time,predicate_type predicate);
+
+        // backwards compatibility
+
+            template<typename lock_type>
+            bool timed_wait(lock_type>& lock,boost::xtime const& abs_time);
+
+            template<typename lock_type,typename predicate_type>
+            bool timed_wait(lock_type& lock,boost::xtime const& abs_time,predicate_type predicate);
+        };
+    }
+
+[section:constructor `condition_variable_any()`]
+
+[variablelist
+
+[[Effects:] [Constructs an object of class `condition_variable_any`.]]
+
+[[Throws:] [__thread_resource_error__ if an error occurs.]]
+
+]
+
+[endsect]
+
+[section:destructor `~condition_variable_any()`]
+
+[variablelist
+
+[[Precondition:] [All threads waiting on `*this` have been notified by a call to
+`notify_one` or `notify_all` (though the respective calls to `wait` or
+`timed_wait` need not have returned).]]
+
+[[Effects:] [Destroys the object.]]
+
+[[Throws:] [Nothing.]]
+
+]
+
+[endsect]
+
+[section:notify_one `void notify_one()`]
+
+[variablelist
+
+[[Effects:] [If any threads are currently __blocked__ waiting on `*this` in a call
+to `wait` or `timed_wait`, unblocks one of those threads.]]
+
+[[Throws:] [Nothing.]]
+
+]
+
+[endsect]
+
+[section:notify_all `void notify_all()`]
+
+[variablelist
+
+[[Effects:] [If any threads are currently __blocked__ waiting on `*this` in a call
+to `wait` or `timed_wait`, unblocks all of those threads.]]
+
+[[Throws:] [Nothing.]]
+
+]
+
+[endsect]
+
+[section:wait `template<typename lock_type> void wait(lock_type& lock)`]
+
+[variablelist
+
+[[Effects:] [Atomically call `lock.unlock()` and blocks the current thread. The
+thread will unblock when notified by a call to `this->notify_one()` or
+`this->notify_all()`, or spuriously. When the thread is unblocked (for whatever
+reason), the lock is reacquired by invoking `lock.lock()` before the call to
+`wait` returns. The lock is also reacquired by invoking `lock.lock()` if the
+function exits with an exception.]]
+
+[[Postcondition:] [`lock` is locked by the current thread.]]
+
+[[Throws:] [__thread_resource_error__ if an error
+occurs. __thread_interrupted__ if the wait was interrupted by a call to
+__interrupt__ on the __thread__ object associated with the current thread of execution.]]
+
+]
+
+[endsect]
+
+[section:wait_predicate `template<typename lock_type,typename predicate_type> void wait(lock_type& lock, predicate_type pred)`]
+
+[variablelist
+
+[[Effects:] [As-if ``
+while(!pred())
+{
+    wait(lock);
+}
+``]]
+
+]
+
+[endsect]
+
+[section:timed_wait `template<typename lock_type> bool timed_wait(lock_type& lock,boost::system_time const& abs_time)`]
+
+[variablelist
+
+[[Effects:] [Atomically call `lock.unlock()` and blocks the current thread. The
+thread will unblock when notified by a call to `this->notify_one()` or
+`this->notify_all()`, when the time as reported by `boost::get_system_time()`
+would be equal to or later than the specified `abs_time`, or spuriously. When
+the thread is unblocked (for whatever reason), the lock is reacquired by
+invoking `lock.lock()` before the call to `wait` returns. The lock is also
+reacquired by invoking `lock.lock()` if the function exits with an exception.]]
+
+[[Returns:] [`false` if the call is returning because the time specified by
+`abs_time` was reached, `true` otherwise.]]
+
+[[Postcondition:] [`lock` is locked by the current thread.]]
+
+[[Throws:] [__thread_resource_error__ if an error
+occurs. __thread_interrupted__ if the wait was interrupted by a call to
+__interrupt__ on the __thread__ object associated with the current thread of execution.]]
+
+]
+
+[endsect]
+
+[section:timed_wait_rel `template<typename lock_type,typename duration_type> bool timed_wait(lock_type& lock,duration_type const& rel_time)`]
+
+[variablelist
+
+[[Effects:] [Atomically call `lock.unlock()` and blocks the current thread. The
+thread will unblock when notified by a call to `this->notify_one()` or
+`this->notify_all()`, after the period of time indicated by the `rel_time`
+argument has elapsed, or spuriously. When the thread is unblocked (for whatever
+reason), the lock is reacquired by invoking `lock.lock()` before the call to
+`wait` returns. The lock is also reacquired by invoking `lock.lock()` if the
+function exits with an exception.]]
+
+[[Returns:] [`false` if the call is returning because the time period specified
+by `rel_time` has elapsed, `true` otherwise.]]
+
+[[Postcondition:] [`lock` is locked by the current thread.]]
+
+[[Throws:] [__thread_resource_error__ if an error
+occurs. __thread_interrupted__ if the wait was interrupted by a call to
+__interrupt__ on the __thread__ object associated with the current thread of execution.]]
+
+]
+
+[note The duration overload of timed_wait is difficult to use correctly. The overload taking a predicate should be preferred in most cases.]
+
+[endsect]
+
+[section:timed_wait_predicate `template<typename lock_type,typename predicate_type> bool timed_wait(lock_type& lock, boost::system_time const& abs_time, predicate_type pred)`]
+
+[variablelist
+
+[[Effects:] [As-if ``
+while(!pred())
+{
+    if(!timed_wait(lock,abs_time))
+    {
+        return pred();
+    }
+}
+return true;
+``]]
+
+]
+
+[endsect]
+
+[endsect]
+
+[section:condition Typedef `condition`]
+
+    #include <boost/thread/condition.hpp>
+
+    typedef condition_variable_any condition;
+
+The typedef `condition` is provided for backwards compatibility with previous boost releases.
+
+[endsect]
+
+[endsect]
diff --git a/deal.II/contrib/boost/libs/thread/doc/index.html b/deal.II/contrib/boost/libs/thread/doc/index.html
new file mode 100644 (file)
index 0000000..4d1b5db
--- /dev/null
@@ -0,0 +1,12 @@
+<!-- Copyright (c) 2002-2003 Beman Dawes, William E. Kempf.
+     Subject to the Boost Software License, Version 1.0. 
+     (See accompanying file LICENSE_1_0.txt or  http://www.boost.org/LICENSE_1_0.txt)
+-->
+<html>
+<head>
+<meta http-equiv="refresh" content="0; URL=../../../doc/html/thread.html">
+</head>
+<body>
+Automatic redirection failed, please go to <a href="../../../doc/html/thread.html">../../../doc/html/thread.html</a>
+</body>
+</html>
diff --git a/deal.II/contrib/boost/libs/thread/doc/mutex_concepts.qbk b/deal.II/contrib/boost/libs/thread/doc/mutex_concepts.qbk
new file mode 100644 (file)
index 0000000..1affa78
--- /dev/null
@@ -0,0 +1,1119 @@
+[/
+  (C) Copyright 2007-8 Anthony Williams.
+  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).
+]
+
+[section:mutex_concepts Mutex Concepts]
+
+A mutex object facilitates protection against data races and allows thread-safe synchronization of data between threads. A thread
+obtains ownership of a mutex object by calling one of the lock functions and relinquishes ownership by calling the corresponding
+unlock function. Mutexes may be either recursive or non-recursive, and may grant simultaneous ownership to one or many
+threads. __boost_thread__ supplies recursive and non-recursive mutexes with exclusive ownership semantics, along with a shared
+ownership (multiple-reader / single-writer) mutex.
+
+__boost_thread__ supports four basic concepts for lockable objects: __lockable_concept_type__, __timed_lockable_concept_type__,
+__shared_lockable_concept_type__ and __upgrade_lockable_concept_type__. Each mutex type implements one or more of these concepts, as
+do the various lock types.
+
+[section:lockable `Lockable` Concept]
+
+The __lockable_concept__ models exclusive ownership. A type that implements the __lockable_concept__ shall provide the following
+member functions:
+
+* [lock_ref_link `void lock();`]
+* [try_lock_ref_link `bool try_lock();`]
+* [unlock_ref_link `void unlock();`]
+
+Lock ownership acquired through a call to __lock_ref__ or __try_lock_ref__ must be released through a call to __unlock_ref__.
+
+[section:lock `void lock()`]
+
+[variablelist
+
+[[Effects:] [The current thread blocks until ownership can be obtained for the current thread.]]
+
+[[Postcondition:] [The current thread owns `*this`.]]
+
+[[Throws:] [__thread_resource_error__ if an error occurs.]]
+
+]
+[endsect]
+
+[section:try_lock `bool try_lock()`]
+
+[variablelist
+
+[[Effects:] [Attempt to obtain ownership for the current thread without blocking.]]
+
+[[Returns:] [`true` if ownership was obtained for the current thread, `false` otherwise.]]
+
+[[Postcondition:] [If the call returns `true`, the current thread owns the `*this`.]]
+
+[[Throws:] [__thread_resource_error__ if an error occurs.]]
+
+]
+[endsect]
+
+[section:unlock `void unlock()`]
+
+[variablelist
+
+[[Precondition:] [The current thread owns `*this`.]]
+
+[[Effects:] [Releases ownership by the current thread.]]
+
+[[Postcondition:] [The current thread no longer owns `*this`.]]
+
+[[Throws:] [Nothing]]
+]
+[endsect]
+[endsect]
+
+[section:timed_lockable `TimedLockable` Concept]
+
+The __timed_lockable_concept__ refines the __lockable_concept__ to add support for
+timeouts when trying to acquire the lock.
+
+A type that implements the __timed_lockable_concept__ shall meet the requirements
+of the __lockable_concept__. In addition, the following member functions must be
+provided:
+
+* [timed_lock_ref_link `bool timed_lock(boost::system_time const& abs_time);`]
+* [timed_lock_duration_ref_link `template<typename DurationType> bool timed_lock(DurationType const& rel_time);`]
+
+Lock ownership acquired through a call to __timed_lock_ref__ must be released through a call to __unlock_ref__.
+
+[section:timed_lock `bool timed_lock(boost::system_time const& abs_time)`]
+
+[variablelist
+
+[[Effects:] [Attempt to obtain ownership for the current thread. Blocks until ownership can be obtained, or the specified time is
+reached. If the specified time has already passed, behaves as __try_lock_ref__.]]
+
+[[Returns:] [`true` if ownership was obtained for the current thread, `false` otherwise.]]
+
+[[Postcondition:] [If the call returns `true`, the current thread owns `*this`.]]
+
+[[Throws:] [__thread_resource_error__ if an error occurs.]]
+]
+[endsect]
+
+[section:timed_lock_duration `template<typename DurationType> bool
+timed_lock(DurationType const& rel_time)`]
+
+[variablelist
+
+[[Effects:] [As-if [timed_lock_ref_link
+`timed_lock(boost::get_system_time()+rel_time)`].]]
+
+]
+[endsect]
+
+[endsect]
+
+[section:shared_lockable `SharedLockable` Concept]
+
+The __shared_lockable_concept__ is a refinement of the __timed_lockable_concept__ that
+allows for ['shared ownership] as well as ['exclusive ownership]. This is the
+standard multiple-reader / single-write model: at most one thread can have
+exclusive ownership, and if any thread does have exclusive ownership, no other threads
+can have shared or exclusive ownership. Alternatively, many threads may have
+shared ownership.
+
+For a type to implement the __shared_lockable_concept__, as well as meeting the
+requirements of the __timed_lockable_concept__, it must also provide the following
+member functions:
+
+* [lock_shared_ref_link `void lock_shared();`]
+* [try_lock_shared_ref_link `bool try_lock_shared();`]
+* [unlock_shared_ref_link `bool unlock_shared();`]
+* [timed_lock_shared_ref_link `bool timed_lock_shared(boost::system_time const& abs_time);`]
+
+Lock ownership acquired through a call to __lock_shared_ref__, __try_lock_shared_ref__ or __timed_lock_shared_ref__ must be released
+through a call to __unlock_shared_ref__.
+
+[section:lock_shared `void lock_shared()`]
+
+[variablelist
+
+[[Effects:] [The current thread blocks until shared ownership can be obtained for the current thread.]]
+
+[[Postcondition:] [The current thread has shared ownership of `*this`.]]
+
+[[Throws:] [__thread_resource_error__ if an error occurs.]]
+
+]
+[endsect]
+
+[section:try_lock_shared `bool try_lock_shared()`]
+
+[variablelist
+
+[[Effects:] [Attempt to obtain shared ownership for the current thread without blocking.]]
+
+[[Returns:] [`true` if shared ownership was obtained for the current thread, `false` otherwise.]]
+
+[[Postcondition:] [If the call returns `true`, the current thread has shared ownership of `*this`.]]
+
+[[Throws:] [__thread_resource_error__ if an error occurs.]]
+
+]
+[endsect]
+
+[section:timed_lock_shared `bool timed_lock_shared(boost::system_time const& abs_time)`]
+
+[variablelist
+
+[[Effects:] [Attempt to obtain shared ownership for the current thread. Blocks until shared ownership can be obtained, or the
+specified time is reached. If the specified time has already passed, behaves as __try_lock_shared_ref__.]]
+
+[[Returns:] [`true` if shared ownership was acquired for the current thread, `false` otherwise.]]
+
+[[Postcondition:] [If the call returns `true`, the current thread has shared
+ownership of `*this`.]]
+
+[[Throws:] [__thread_resource_error__ if an error occurs.]]
+
+]
+[endsect]
+
+[section:unlock_shared `void unlock_shared()`]
+
+[variablelist
+
+[[Precondition:] [The current thread has shared ownership of `*this`.]]
+
+[[Effects:] [Releases shared ownership of `*this` by the current thread.]]
+
+[[Postcondition:] [The current thread no longer has shared ownership of `*this`.]]
+
+[[Throws:] [Nothing]]
+
+]
+[endsect]
+
+
+[endsect]
+
+[section:upgrade_lockable `UpgradeLockable` Concept]
+
+The __upgrade_lockable_concept__ is a refinement of the __shared_lockable_concept__ that allows for ['upgradable ownership] as well
+as ['shared ownership] and ['exclusive ownership]. This is an extension to the multiple-reader / single-write model provided by the
+__shared_lockable_concept__: a single thread may have ['upgradable ownership] at the same time as others have ['shared
+ownership]. The thread with ['upgradable ownership] may at any time attempt to upgrade that ownership to ['exclusive ownership]. If
+no other threads have shared ownership, the upgrade is completed immediately, and the thread now has ['exclusive ownership], which
+must be relinquished by a call to __unlock_ref__, just as if it had been acquired by a call to __lock_ref__.
+
+If a thread with ['upgradable ownership] tries to upgrade whilst other threads have ['shared ownership], the attempt will fail and
+the thread will block until ['exclusive ownership] can be acquired.
+
+Ownership can also be ['downgraded] as well as ['upgraded]: exclusive ownership of an implementation of the
+__upgrade_lockable_concept__ can be downgraded to upgradable ownership or shared ownership, and upgradable ownership can be
+downgraded to plain shared ownership.
+
+For a type to implement the __upgrade_lockable_concept__, as well as meeting the
+requirements of the __shared_lockable_concept__, it must also provide the following
+member functions:
+
+* [lock_upgrade_ref_link `void lock_upgrade();`]
+* [unlock_upgrade_ref_link `bool unlock_upgrade();`]
+* [unlock_upgrade_and_lock_ref_link `void unlock_upgrade_and_lock();`]
+* [unlock_and_lock_upgrade_ref_link `void unlock_and_lock_upgrade();`]
+* [unlock_upgrade_and_lock_shared_ref_link `void unlock_upgrade_and_lock_shared();`]
+
+Lock ownership acquired through a call to __lock_upgrade_ref__ must be released through a call to __unlock_upgrade_ref__. If the
+ownership type is changed through a call to one of the `unlock_xxx_and_lock_yyy()` functions, ownership must be released through a
+call to the unlock function corresponding to the new level of ownership.
+
+
+[section:lock_upgrade `void lock_upgrade()`]
+
+[variablelist
+
+[[Effects:] [The current thread blocks until upgrade ownership can be obtained for the current thread.]]
+
+[[Postcondition:] [The current thread has upgrade ownership of `*this`.]]
+
+[[Throws:] [__thread_resource_error__ if an error occurs.]]
+
+]
+[endsect]
+
+[section:unlock_upgrade `void unlock_upgrade()`]
+
+[variablelist
+
+[[Precondition:] [The current thread has upgrade ownership of `*this`.]]
+
+[[Effects:] [Releases upgrade ownership of `*this` by the current thread.]]
+
+[[Postcondition:] [The current thread no longer has upgrade ownership of `*this`.]]
+
+[[Throws:] [Nothing]]
+
+]
+[endsect]
+
+[section:unlock_upgrade_and_lock `void unlock_upgrade_and_lock()`]
+
+[variablelist
+
+[[Precondition:] [The current thread has upgrade ownership of `*this`.]]
+
+[[Effects:] [Atomically releases upgrade ownership of `*this` by the current thread and acquires exclusive ownership of `*this`. If
+any other threads have shared ownership, blocks until exclusive ownership can be acquired.]]
+
+[[Postcondition:] [The current thread has exclusive ownership of `*this`.]]
+
+[[Throws:] [Nothing]]
+
+]
+[endsect]
+
+[section:unlock_upgrade_and_lock_shared `void unlock_upgrade_and_lock_shared()`]
+
+[variablelist
+
+[[Precondition:] [The current thread has upgrade ownership of `*this`.]]
+
+[[Effects:] [Atomically releases upgrade ownership of `*this` by the current thread and acquires shared ownership of `*this` without
+blocking.]]
+
+[[Postcondition:] [The current thread has shared ownership of `*this`.]]
+
+[[Throws:] [Nothing]]
+
+]
+[endsect]
+
+[section:unlock_and_lock_upgrade `void unlock_and_lock_upgrade()`]
+
+[variablelist
+
+[[Precondition:] [The current thread has exclusive ownership of `*this`.]]
+
+[[Effects:] [Atomically releases exclusive ownership of `*this` by the current thread and acquires upgrade ownership of `*this`
+without blocking.]]
+
+[[Postcondition:] [The current thread has upgrade ownership of `*this`.]]
+
+[[Throws:] [Nothing]]
+
+]
+[endsect]
+
+[endsect]
+
+[endsect]
+
+[section:locks Lock Types]
+
+[section:lock_guard Class template `lock_guard`]
+
+    #include <boost/thread/locks.hpp>
+
+    template<typename Lockable>
+    class lock_guard
+    {
+    public:
+        explicit lock_guard(Lockable& m_);
+        lock_guard(Lockable& m_,boost::adopt_lock_t);
+
+        ~lock_guard();
+    };
+
+__lock_guard__ is very simple: on construction it
+acquires ownership of the implementation of the __lockable_concept__ supplied as
+the constructor parameter. On destruction, the ownership is released. This
+provides simple RAII-style locking of a __lockable_concept_type__ object, to facilitate exception-safe
+locking and unlocking. In addition, the [link
+thread.synchronization.locks.lock_guard.constructor_adopt `lock_guard(Lockable &
+m,boost::adopt_lock_t)` constructor] allows the __lock_guard__ object to
+take ownership of a lock already held by the current thread.
+
+[section:constructor `lock_guard(Lockable & m)`]
+
+[variablelist
+
+[[Effects:] [Stores a reference to `m`. Invokes [lock_ref_link `m.lock()`].]]
+
+[[Throws:] [Any exception thrown by the call to [lock_ref_link `m.lock()`].]]
+
+]
+
+[endsect]
+
+[section:constructor_adopt `lock_guard(Lockable & m,boost::adopt_lock_t)`]
+
+[variablelist
+
+[[Precondition:] [The current thread owns a lock on `m` equivalent to one
+obtained by a call to [lock_ref_link `m.lock()`].]]
+
+[[Effects:] [Stores a reference to `m`. Takes ownership of the lock state of
+`m`.]]
+
+[[Throws:] [Nothing.]]
+
+]
+
+[endsect]
+
+[section:destructor `~lock_guard()`]
+
+[variablelist
+
+[[Effects:] [Invokes [unlock_ref_link `m.unlock()`] on the __lockable_concept_type__
+object passed to the constructor.]]
+
+[[Throws:] [Nothing.]]
+
+]
+
+[endsect]
+
+[endsect]
+
+[section:unique_lock Class template `unique_lock`]
+
+    #include <boost/thread/locks.hpp>
+
+    template<typename Lockable>
+    class unique_lock
+    {
+    public:
+        unique_lock();
+        explicit unique_lock(Lockable& m_);
+        unique_lock(Lockable& m_,adopt_lock_t);
+        unique_lock(Lockable& m_,defer_lock_t);
+        unique_lock(Lockable& m_,try_to_lock_t);
+        unique_lock(Lockable& m_,system_time const& target_time);
+
+        ~unique_lock();
+
+        unique_lock(detail::thread_move_t<unique_lock<Lockable> > other);
+        unique_lock(detail::thread_move_t<upgrade_lock<Lockable> > other);
+
+        operator detail::thread_move_t<unique_lock<Lockable> >();
+        detail::thread_move_t<unique_lock<Lockable> > move();
+        unique_lock& operator=(detail::thread_move_t<unique_lock<Lockable> > other);
+        unique_lock& operator=(detail::thread_move_t<upgrade_lock<Lockable> > other);
+
+        void swap(unique_lock& other);
+        void swap(detail::thread_move_t<unique_lock<Lockable> > other);
+
+        void lock();
+        bool try_lock();
+
+        template<typename TimeDuration>
+        bool timed_lock(TimeDuration const& relative_time);
+        bool timed_lock(::boost::system_time const& absolute_time);
+
+        void unlock();
+
+        bool owns_lock() const;
+        operator ``['unspecified-bool-type]``() const;
+        bool operator!() const;
+
+        Lockable* mutex() const;
+        Lockable* release();
+    };
+
+__unique_lock__ is more complex than __lock_guard__: not only does it provide for RAII-style locking, it also allows for deferring
+acquiring the lock until the __lock_ref__ member function is called explicitly, or trying to acquire the lock in a non-blocking
+fashion, or with a timeout. Consequently, __unlock_ref__ is only called in the destructor if the lock object has locked the
+__lockable_concept_type__ object, or otherwise adopted a lock on the __lockable_concept_type__ object.
+
+Specializations of __unique_lock__ model the __timed_lockable_concept__ if the supplied __lockable_concept_type__ type itself models
+__timed_lockable_concept__ (e.g. `boost::unique_lock<boost::timed_mutex>`), or the __lockable_concept__ otherwise
+(e.g. `boost::unique_lock<boost::mutex>`). 
+
+An instance of __unique_lock__ is said to ['own] the lock state of a __lockable_concept_type__ `m` if __mutex_func_ref__ returns a
+pointer to `m` and __owns_lock_ref__ returns `true`. If an object that ['owns] the lock state of a __lockable_concept_type__ object
+is destroyed, then the destructor will invoke [unlock_ref_link `mutex()->unlock()`].
+
+The member functions of __unique_lock__ are not thread-safe. In particular, __unique_lock__ is intended to model the ownership of a
+__lockable_concept_type__ object by a particular thread, and the member functions that release ownership of the lock state
+(including the destructor) must be called by the same thread that acquired ownership of the lock state.
+
+[section:defaultconstructor `unique_lock()`]
+
+[variablelist
+
+[[Effects:] [Creates a lock object with no associated mutex.]]
+
+[[Postcondition:] [__owns_lock_ref__ returns `false`. __mutex_func_ref__ returns `NULL`.]]
+
+[[Throws:] [Nothing.]]
+
+]
+
+[endsect]
+
+[section:constructor `unique_lock(Lockable & m)`]
+
+[variablelist
+
+[[Effects:] [Stores a reference to `m`. Invokes [lock_ref_link `m.lock()`].]]
+
+[[Postcondition:] [__owns_lock_ref__ returns `true`. __mutex_func_ref__ returns `&m`.]]
+
+[[Throws:] [Any exception thrown by the call to [lock_ref_link `m.lock()`].]]
+
+]
+
+[endsect]
+
+[section:constructor_adopt `unique_lock(Lockable & m,boost::adopt_lock_t)`]
+
+[variablelist
+
+[[Precondition:] [The current thread owns an exclusive lock on `m`.]]
+
+[[Effects:] [Stores a reference to `m`. Takes ownership of the lock state of `m`.]]
+
+[[Postcondition:] [__owns_lock_ref__ returns `true`. __mutex_func_ref__ returns `&m`.]]
+
+[[Throws:] [Nothing.]]
+
+]
+
+[endsect]
+
+[section:constructor_defer `unique_lock(Lockable & m,boost::defer_lock_t)`]
+
+[variablelist
+
+[[Effects:] [Stores a reference to `m`.]]
+
+[[Postcondition:] [__owns_lock_ref__ returns `false`. __mutex_func_ref__ returns `&m`.]]
+
+[[Throws:] [Nothing.]]
+
+]
+
+[endsect]
+
+[section:constructor_try `unique_lock(Lockable & m,boost::try_to_lock_t)`]
+
+[variablelist
+
+[[Effects:] [Stores a reference to `m`. Invokes [try_lock_ref_link
+`m.try_lock()`], and takes ownership of the lock state if the call returns
+`true`.]]
+
+[[Postcondition:] [__mutex_func_ref__ returns `&m`. If the call to __try_lock_ref__
+returned `true`, then __owns_lock_ref__ returns `true`, otherwise __owns_lock_ref__
+returns `false`.]]
+
+[[Throws:] [Nothing.]]
+
+]
+
+[endsect]
+
+[section:constructor_abs_time `unique_lock(Lockable & m,boost::system_time const& abs_time)`]
+
+[variablelist
+
+[[Effects:] [Stores a reference to `m`. Invokes [timed_lock_ref_link
+`m.timed_lock(abs_time)`], and takes ownership of the lock state if the call
+returns `true`.]]
+
+[[Postcondition:] [__mutex_func_ref__ returns `&m`. If the call to __timed_lock_ref__
+returned `true`, then __owns_lock_ref__ returns `true`, otherwise __owns_lock_ref__
+returns `false`.]]
+
+[[Throws:] [Any exceptions thrown by the call to [timed_lock_ref_link `m.timed_lock(abs_time)`].]]
+
+]
+
+[endsect]
+
+[section:destructor `~unique_lock()`]
+
+[variablelist
+
+[[Effects:] [Invokes __mutex_func_ref__`->`[unlock_ref_link `unlock()`] if
+__owns_lock_ref__ returns `true`.]]
+
+[[Throws:] [Nothing.]]
+
+]
+
+[endsect]
+
+[section:owns_lock `bool owns_lock() const`]
+
+[variablelist
+
+[[Returns:] [`true` if the `*this` owns the lock on the __lockable_concept_type__
+object associated with `*this`.]]
+
+[[Throws:] [Nothing.]]
+
+]
+
+[endsect]
+
+[section:mutex `Lockable* mutex() const`]
+
+[variablelist
+
+[[Returns:] [A pointer to the __lockable_concept_type__ object associated with
+`*this`, or `NULL` if there is no such object.]]
+
+[[Throws:] [Nothing.]]
+
+]
+
+[endsect]
+
+[section:bool_conversion `operator unspecified-bool-type() const`]
+
+[variablelist
+
+[[Returns:] [If __owns_lock_ref__ would return `true`, a value that evaluates to
+`true` in boolean contexts, otherwise a value that evaluates to `false` in
+boolean contexts.]]
+
+[[Throws:] [Nothing.]]
+
+]
+
+[endsect]
+
+[section:operator_not `bool operator!() const`]
+
+[variablelist
+
+[[Returns:] [`!` __owns_lock_ref__.]]
+
+[[Throws:] [Nothing.]]
+
+]
+
+[endsect]
+
+[section:release `Lockable* release()`]
+
+[variablelist
+
+[[Effects:] [The association between `*this` and the __lockable_concept_type__ object is removed, without affecting the lock state
+of the __lockable_concept_type__ object. If __owns_lock_ref__ would have returned `true`, it is the responsibility of the calling
+code to ensure that the __lockable_concept_type__ is correctly unlocked.]]
+
+[[Returns:] [A pointer to the __lockable_concept_type__ object associated with `*this` at the point of the call, or `NULL` if there
+is no such object.]]
+
+[[Throws:] [Nothing.]]
+
+[[Postcondition:] [`*this` is no longer associated with any __lockable_concept_type__ object. __mutex_func_ref__ returns `NULL` and
+__owns_lock_ref__ returns `false`.]]
+
+]
+
+[endsect]
+
+[endsect]
+
+[section:shared_lock Class template `shared_lock`]
+
+    #include <boost/thread/locks.hpp>
+
+    template<typename Lockable>
+    class shared_lock
+    {
+    public:
+        shared_lock();
+        explicit shared_lock(Lockable& m_);
+        shared_lock(Lockable& m_,adopt_lock_t);
+        shared_lock(Lockable& m_,defer_lock_t);
+        shared_lock(Lockable& m_,try_to_lock_t);
+        shared_lock(Lockable& m_,system_time const& target_time);
+        shared_lock(detail::thread_move_t<shared_lock<Lockable> > other);
+        shared_lock(detail::thread_move_t<unique_lock<Lockable> > other);
+        shared_lock(detail::thread_move_t<upgrade_lock<Lockable> > other);
+
+        ~shared_lock();
+
+        operator detail::thread_move_t<shared_lock<Lockable> >();
+        detail::thread_move_t<shared_lock<Lockable> > move();
+
+        shared_lock& operator=(detail::thread_move_t<shared_lock<Lockable> > other);
+        shared_lock& operator=(detail::thread_move_t<unique_lock<Lockable> > other);
+        shared_lock& operator=(detail::thread_move_t<upgrade_lock<Lockable> > other);
+        void swap(shared_lock& other);
+
+        void lock();
+        bool try_lock();
+        bool timed_lock(boost::system_time const& target_time);
+        void unlock();
+
+        operator ``['unspecified-bool-type]``() const;
+        bool operator!() const;
+        bool owns_lock() const;
+    };
+
+Like __unique_lock__, __shared_lock__ models the __lockable_concept__, but rather than acquiring unique ownership of the supplied
+__lockable_concept_type__ object, locking an instance of __shared_lock__ acquires shared ownership.
+
+Like __unique_lock__, not only does it provide for RAII-style locking, it also allows for deferring acquiring the lock until the
+__lock_ref__ member function is called explicitly, or trying to acquire the lock in a non-blocking fashion, or with a
+timeout. Consequently, __unlock_ref__ is only called in the destructor if the lock object has locked the __lockable_concept_type__
+object, or otherwise adopted a lock on the __lockable_concept_type__ object.
+
+An instance of __shared_lock__ is said to ['own] the lock state of a __lockable_concept_type__ `m` if __mutex_func_ref__ returns a
+pointer to `m` and __owns_lock_ref__ returns `true`. If an object that ['owns] the lock state of a __lockable_concept_type__ object
+is destroyed, then the destructor will invoke [unlock_shared_ref_link `mutex()->unlock_shared()`].
+
+The member functions of __shared_lock__ are not thread-safe. In particular, __shared_lock__ is intended to model the shared
+ownership of a __lockable_concept_type__ object by a particular thread, and the member functions that release ownership of the lock
+state (including the destructor) must be called by the same thread that acquired ownership of the lock state.
+
+[section:defaultconstructor `shared_lock()`]
+
+[variablelist
+
+[[Effects:] [Creates a lock object with no associated mutex.]]
+
+[[Postcondition:] [__owns_lock_ref__ returns `false`. __mutex_func_ref__ returns `NULL`.]]
+
+[[Throws:] [Nothing.]]
+
+]
+
+[endsect]
+
+[section:constructor `shared_lock(Lockable & m)`]
+
+[variablelist
+
+[[Effects:] [Stores a reference to `m`. Invokes [lock_shared_ref_link `m.lock_shared()`].]]
+
+[[Postcondition:] [__owns_lock_shared_ref__ returns `true`. __mutex_func_ref__ returns `&m`.]]
+
+[[Throws:] [Any exception thrown by the call to [lock_shared_ref_link `m.lock_shared()`].]]
+
+]
+
+[endsect]
+
+[section:constructor_adopt `shared_lock(Lockable & m,boost::adopt_lock_t)`]
+
+[variablelist
+
+[[Precondition:] [The current thread owns an exclusive lock on `m`.]]
+
+[[Effects:] [Stores a reference to `m`. Takes ownership of the lock state of `m`.]]
+
+[[Postcondition:] [__owns_lock_shared_ref__ returns `true`. __mutex_func_ref__ returns `&m`.]]
+
+[[Throws:] [Nothing.]]
+
+]
+
+[endsect]
+
+[section:constructor_defer `shared_lock(Lockable & m,boost::defer_lock_t)`]
+
+[variablelist
+
+[[Effects:] [Stores a reference to `m`.]]
+
+[[Postcondition:] [__owns_lock_shared_ref__ returns `false`. __mutex_func_ref__ returns `&m`.]]
+
+[[Throws:] [Nothing.]]
+
+]
+
+[endsect]
+
+[section:constructor_try `shared_lock(Lockable & m,boost::try_to_lock_t)`]
+
+[variablelist
+
+[[Effects:] [Stores a reference to `m`. Invokes [try_lock_shared_ref_link
+`m.try_lock_shared()`], and takes ownership of the lock state if the call returns
+`true`.]]
+
+[[Postcondition:] [__mutex_func_ref__ returns `&m`. If the call to __try_lock_shared_ref__
+returned `true`, then __owns_lock_shared_ref__ returns `true`, otherwise __owns_lock_shared_ref__
+returns `false`.]]
+
+[[Throws:] [Nothing.]]
+
+]
+
+[endsect]
+
+[section:constructor_abs_time `shared_lock(Lockable & m,boost::system_time const& abs_time)`]
+
+[variablelist
+
+[[Effects:] [Stores a reference to `m`. Invokes [timed_lock_shared_ref_link
+`m.timed_lock(abs_time)`], and takes ownership of the lock state if the call
+returns `true`.]]
+
+[[Postcondition:] [__mutex_func_ref__ returns `&m`. If the call to __timed_lock_shared_ref__
+returned `true`, then __owns_lock_shared_ref__ returns `true`, otherwise __owns_lock_shared_ref__
+returns `false`.]]
+
+[[Throws:] [Any exceptions thrown by the call to [timed_lock_shared_ref_link `m.timed_lock(abs_time)`].]]
+
+]
+
+[endsect]
+
+[section:destructor `~shared_lock()`]
+
+[variablelist
+
+[[Effects:] [Invokes __mutex_func_ref__`->`[unlock_shared_ref_link `unlock_shared()`] if
+__owns_lock_shared_ref__ returns `true`.]]
+
+[[Throws:] [Nothing.]]
+
+]
+
+[endsect]
+
+[section:owns_lock `bool owns_lock() const`]
+
+[variablelist
+
+[[Returns:] [`true` if the `*this` owns the lock on the __lockable_concept_type__
+object associated with `*this`.]]
+
+[[Throws:] [Nothing.]]
+
+]
+
+[endsect]
+
+[section:mutex `Lockable* mutex() const`]
+
+[variablelist
+
+[[Returns:] [A pointer to the __lockable_concept_type__ object associated with
+`*this`, or `NULL` if there is no such object.]]
+
+[[Throws:] [Nothing.]]
+
+]
+
+[endsect]
+
+[section:bool_conversion `operator unspecified-bool-type() const`]
+
+[variablelist
+
+[[Returns:] [If __owns_lock_shared_ref__ would return `true`, a value that evaluates to
+`true` in boolean contexts, otherwise a value that evaluates to `false` in
+boolean contexts.]]
+
+[[Throws:] [Nothing.]]
+
+]
+
+[endsect]
+
+[section:operator_not `bool operator!() const`]
+
+[variablelist
+
+[[Returns:] [`!` __owns_lock_shared_ref__.]]
+
+[[Throws:] [Nothing.]]
+
+]
+
+[endsect]
+
+[section:release `Lockable* release()`]
+
+[variablelist
+
+[[Effects:] [The association between `*this` and the __lockable_concept_type__ object is removed, without affecting the lock state
+of the __lockable_concept_type__ object. If __owns_lock_shared_ref__ would have returned `true`, it is the responsibility of the calling
+code to ensure that the __lockable_concept_type__ is correctly unlocked.]]
+
+[[Returns:] [A pointer to the __lockable_concept_type__ object associated with `*this` at the point of the call, or `NULL` if there
+is no such object.]]
+
+[[Throws:] [Nothing.]]
+
+[[Postcondition:] [`*this` is no longer associated with any __lockable_concept_type__ object. __mutex_func_ref__ returns `NULL` and
+__owns_lock_shared_ref__ returns `false`.]]
+
+]
+
+[endsect]
+
+[endsect]
+
+[section:upgrade_lock Class template `upgrade_lock`]
+
+    #include <boost/thread/locks.hpp>
+
+    template<typename Lockable>
+    class upgrade_lock
+    {
+    public:
+        explicit upgrade_lock(Lockable& m_);
+
+        upgrade_lock(detail::thread_move_t<upgrade_lock<Lockable> > other);
+        upgrade_lock(detail::thread_move_t<unique_lock<Lockable> > other);
+
+        ~upgrade_lock();
+
+        operator detail::thread_move_t<upgrade_lock<Lockable> >();
+        detail::thread_move_t<upgrade_lock<Lockable> > move();
+
+        upgrade_lock& operator=(detail::thread_move_t<upgrade_lock<Lockable> > other);
+        upgrade_lock& operator=(detail::thread_move_t<unique_lock<Lockable> > other);
+
+        void swap(upgrade_lock& other);
+
+        void lock();
+        void unlock();
+
+        operator ``['unspecified-bool-type]``() const;
+        bool operator!() const;
+        bool owns_lock() const;
+    };
+
+Like __unique_lock__, __upgrade_lock__ models the __lockable_concept__, but rather than acquiring unique ownership of the supplied
+__lockable_concept_type__ object, locking an instance of __upgrade_lock__ acquires upgrade ownership.
+
+Like __unique_lock__, not only does it provide for RAII-style locking, it also allows for deferring acquiring the lock until the
+__lock_ref__ member function is called explicitly, or trying to acquire the lock in a non-blocking fashion, or with a
+timeout. Consequently, __unlock_ref__ is only called in the destructor if the lock object has locked the __lockable_concept_type__
+object, or otherwise adopted a lock on the __lockable_concept_type__ object.
+
+An instance of __upgrade_lock__ is said to ['own] the lock state of a __lockable_concept_type__ `m` if __mutex_func_ref__ returns a
+pointer to `m` and __owns_lock_ref__ returns `true`. If an object that ['owns] the lock state of a __lockable_concept_type__ object
+is destroyed, then the destructor will invoke [unlock_upgrade_ref_link `mutex()->unlock_upgrade()`].
+
+The member functions of __upgrade_lock__ are not thread-safe. In particular, __upgrade_lock__ is intended to model the upgrade
+ownership of a __lockable_concept_type__ object by a particular thread, and the member functions that release ownership of the lock
+state (including the destructor) must be called by the same thread that acquired ownership of the lock state.
+
+[endsect]
+
+[section:upgrade_to_unique_lock Class template `upgrade_to_unique_lock`]
+
+    #include <boost/thread/locks.hpp>
+
+    template <class Lockable>
+    class upgrade_to_unique_lock
+    {
+    public:
+        explicit upgrade_to_unique_lock(upgrade_lock<Lockable>& m_);
+
+        ~upgrade_to_unique_lock();
+
+        upgrade_to_unique_lock(detail::thread_move_t<upgrade_to_unique_lock<Lockable> > other);
+        upgrade_to_unique_lock& operator=(detail::thread_move_t<upgrade_to_unique_lock<Lockable> > other);
+        void swap(upgrade_to_unique_lock& other);
+
+        operator ``['unspecified-bool-type]``() const;
+        bool operator!() const;
+        bool owns_lock() const;
+    };
+
+__upgrade_to_unique_lock__ allows for a temporary upgrade of an __upgrade_lock__ to exclusive ownership. When constructed with a
+reference to an instance of __upgrade_lock__, if that instance has upgrade ownership on some __lockable_concept_type__ object, that
+ownership is upgraded to exclusive ownership. When the __upgrade_to_unique_lock__ instance is destroyed, the ownership of the
+__lockable_concept_type__ is downgraded back to ['upgrade ownership].
+
+[endsect]
+
+[section:scoped_try_lock Mutex-specific class `scoped_try_lock`]
+
+    class MutexType::scoped_try_lock
+    {
+    private:
+        MutexType::scoped_try_lock(MutexType::scoped_try_lock<MutexType>& other);
+        MutexType::scoped_try_lock& operator=(MutexType::scoped_try_lock<MutexType>& other);
+    public:
+        MutexType::scoped_try_lock();
+        explicit MutexType::scoped_try_lock(MutexType& m);
+        MutexType::scoped_try_lock(MutexType& m_,adopt_lock_t);
+        MutexType::scoped_try_lock(MutexType& m_,defer_lock_t);
+        MutexType::scoped_try_lock(MutexType& m_,try_to_lock_t);
+
+        MutexType::scoped_try_lock(MutexType::scoped_try_lock<MutexType>&& other);
+        MutexType::scoped_try_lock& operator=(MutexType::scoped_try_lock<MutexType>&& other);
+
+        void swap(MutexType::scoped_try_lock&& other);
+
+        void lock();
+        bool try_lock();
+        void unlock();
+        bool owns_lock() const;
+
+        MutexType* mutex() const;
+        MutexType* release();
+        bool operator!() const;
+
+        typedef ``['unspecified-bool-type]`` bool_type;
+        operator bool_type() const;
+    };
+
+The member typedef `scoped_try_lock` is provided for each distinct
+`MutexType` as a typedef to a class with the preceding definition. The
+semantics of each constructor and member function are identical to
+those of [unique_lock_link `boost::unique_lock<MutexType>`] for the same `MutexType`, except
+that the constructor that takes a single reference to a mutex will
+call [try_lock_ref_link `m.try_lock()`] rather than `m.lock()`.
+
+
+[endsect]
+
+[endsect]
+
+[section:lock_functions Lock functions]
+
+[section:lock_multiple Non-member function `lock(Lockable1,Lockable2,...)`]
+
+    template<typename Lockable1,typename Lockable2>
+    void lock(Lockable1& l1,Lockable2& l2);
+
+    template<typename Lockable1,typename Lockable2,typename Lockable3>
+    void lock(Lockable1& l1,Lockable2& l2,Lockable3& l3);
+
+    template<typename Lockable1,typename Lockable2,typename Lockable3,typename Lockable4>
+    void lock(Lockable1& l1,Lockable2& l2,Lockable3& l3,Lockable4& l4);
+
+    template<typename Lockable1,typename Lockable2,typename Lockable3,typename Lockable4,typename Lockable5>
+    void lock(Lockable1& l1,Lockable2& l2,Lockable3& l3,Lockable4& l4,Lockable5& l5);
+
+[variablelist
+
+[[Effects:] [Locks the __lockable_concept_type__ objects supplied as
+arguments in an unspecified and indeterminate order in a way that
+avoids deadlock. It is safe to call this function concurrently from
+multiple threads with the same mutexes (or other lockable objects) in
+different orders without risk of deadlock. If any of the __lock_ref__
+or __try_lock_ref__ operations on the supplied
+__lockable_concept_type__ objects throws an exception any locks
+acquired by the function will be released before the function exits.]]
+
+[[Throws:] [Any exceptions thrown by calling __lock_ref__ or
+__try_lock_ref__ on the supplied __lockable_concept_type__ objects.]]
+
+[[Postcondition:] [All the supplied __lockable_concept_type__ objects
+are locked by the calling thread.]]
+
+]
+
+[endsect]
+
+[section:lock_range Non-member function `lock(begin,end)`]
+
+    template<typename ForwardIterator>
+    void lock(ForwardIterator begin,ForwardIterator end);
+
+[variablelist
+
+[[Preconditions:] [The `value_type` of `ForwardIterator` must implement the __lockable_concept__]]
+
+[[Effects:] [Locks all the __lockable_concept_type__ objects in the
+supplied range in an unspecified and indeterminate order in a way that
+avoids deadlock. It is safe to call this function concurrently from
+multiple threads with the same mutexes (or other lockable objects) in
+different orders without risk of deadlock. If any of the __lock_ref__
+or __try_lock_ref__ operations on the __lockable_concept_type__
+objects in the supplied range throws an exception any locks acquired
+by the function will be released before the function exits.]]
+
+[[Throws:] [Any exceptions thrown by calling __lock_ref__ or
+__try_lock_ref__ on the supplied __lockable_concept_type__ objects.]]
+
+[[Postcondition:] [All the __lockable_concept_type__ objects in the
+supplied range are locked by the calling thread.]]
+
+]
+
+[endsect]
+
+[section:try_lock_multiple Non-member function `try_lock(Lockable1,Lockable2,...)`]
+
+    template<typename Lockable1,typename Lockable2>
+    int try_lock(Lockable1& l1,Lockable2& l2);
+
+    template<typename Lockable1,typename Lockable2,typename Lockable3>
+    int try_lock(Lockable1& l1,Lockable2& l2,Lockable3& l3);
+
+    template<typename Lockable1,typename Lockable2,typename Lockable3,typename Lockable4>
+    int try_lock(Lockable1& l1,Lockable2& l2,Lockable3& l3,Lockable4& l4);
+
+    template<typename Lockable1,typename Lockable2,typename Lockable3,typename Lockable4,typename Lockable5>
+    int try_lock(Lockable1& l1,Lockable2& l2,Lockable3& l3,Lockable4& l4,Lockable5& l5);
+
+[variablelist
+
+[[Effects:] [Calls __try_lock_ref__ on each of the
+__lockable_concept_type__ objects supplied as arguments. If any of the
+calls to __try_lock_ref__ returns `false` then all locks acquired are
+released and the zero-based index of the failed lock is returned.
+
+If any of the __try_lock_ref__ operations on the supplied
+__lockable_concept_type__ objects throws an exception any locks
+acquired by the function will be released before the function exits.]]
+
+[[Returns:] [`-1` if all the supplied __lockable_concept_type__ objects
+are now locked by the calling thread, the zero-based index of the
+object which could not be locked otherwise.]]
+
+[[Throws:] [Any exceptions thrown by calling __try_lock_ref__ on the
+supplied __lockable_concept_type__ objects.]]
+
+[[Postcondition:] [If the function returns `-1`, all the supplied
+__lockable_concept_type__ objects are locked by the calling
+thread. Otherwise any locks acquired by this function will have been
+released.]]
+
+]
+
+[endsect]
+
+[section:try_lock_range Non-member function `try_lock(begin,end)`]
+
+    template<typename ForwardIterator>
+    ForwardIterator try_lock(ForwardIterator begin,ForwardIterator end);
+
+[variablelist
+
+[[Preconditions:] [The `value_type` of `ForwardIterator` must implement the __lockable_concept__]]
+
+[[Effects:] [Calls __try_lock_ref__ on each of the
+__lockable_concept_type__ objects in the supplied range. If any of the
+calls to __try_lock_ref__ returns `false` then all locks acquired are
+released and an iterator referencing the failed lock is returned.
+
+If any of the __try_lock_ref__ operations on the supplied
+__lockable_concept_type__ objects throws an exception any locks
+acquired by the function will be released before the function exits.]]
+
+[[Returns:] [`end` if all the supplied __lockable_concept_type__
+objects are now locked by the calling thread, an iterator referencing
+the object which could not be locked otherwise.]]
+
+[[Throws:] [Any exceptions thrown by calling __try_lock_ref__ on the
+supplied __lockable_concept_type__ objects.]]
+
+[[Postcondition:] [If the function returns `end` then all the
+__lockable_concept_type__ objects in the supplied range are locked by
+the calling thread, otherwise all locks acquired by the function have
+been released.]]
+
+]
+
+[endsect]
+
+
+[endsect]
diff --git a/deal.II/contrib/boost/libs/thread/doc/mutexes.qbk b/deal.II/contrib/boost/libs/thread/doc/mutexes.qbk
new file mode 100644 (file)
index 0000000..ddea86a
--- /dev/null
@@ -0,0 +1,224 @@
+[/
+  (C) Copyright 2007-8 Anthony Williams.
+  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).
+]
+
+[section:mutex_types Mutex Types]
+
+[section:mutex Class `mutex`]
+
+    #include <boost/thread/mutex.hpp>
+
+    class mutex:
+        boost::noncopyable
+    {
+    public:
+        mutex();
+        ~mutex();
+        
+        void lock();
+        bool try_lock();
+        void unlock();
+
+        typedef platform-specific-type native_handle_type;
+        native_handle_type native_handle();
+        
+        typedef unique_lock<mutex> scoped_lock;
+        typedef unspecified-type scoped_try_lock;
+    };
+
+__mutex__ implements the __lockable_concept__ to provide an exclusive-ownership mutex. At most one thread can own the lock on a given
+instance of __mutex__ at any time. Multiple concurrent calls to __lock_ref__, __try_lock_ref__ and __unlock_ref__ shall be permitted.
+
+[section:nativehandle Member function `native_handle()`]
+
+    typedef platform-specific-type native_handle_type;
+    native_handle_type native_handle();
+
+[variablelist
+
+[[Effects:] [Returns an instance of `native_handle_type` that can be used with platform-specific APIs to manipulate the underlying
+implementation. If no such instance exists, `native_handle()` and `native_handle_type` are not present.]]
+
+[[Throws:] [Nothing.]]
+
+]
+
+[endsect]
+
+
+[endsect]
+
+[section:try_mutex Typedef `try_mutex`]
+
+    #include <boost/thread/mutex.hpp>
+
+    typedef mutex try_mutex;
+
+__try_mutex__ is a `typedef` to __mutex__, provided for backwards compatibility with previous releases of boost.
+
+[endsect]
+
+[section:timed_mutex Class `timed_mutex`]
+
+    #include <boost/thread/mutex.hpp>
+
+    class timed_mutex:
+        boost::noncopyable
+    {
+    public:
+        timed_mutex();
+        ~timed_mutex();
+
+        void lock();
+        void unlock();
+        bool try_lock();
+        bool timed_lock(system_time const & abs_time);
+
+        template<typename TimeDuration>
+        bool timed_lock(TimeDuration const & relative_time);
+
+        typedef platform-specific-type native_handle_type;
+        native_handle_type native_handle();
+
+        typedef unique_lock<timed_mutex> scoped_timed_lock;
+        typedef unspecified-type scoped_try_lock;
+        typedef scoped_timed_lock scoped_lock;
+    };
+
+__timed_mutex__ implements the __timed_lockable_concept__ to provide an exclusive-ownership mutex. At most one thread can own the
+lock on a given instance of __timed_mutex__ at any time. Multiple concurrent calls to __lock_ref__, __try_lock_ref__,
+__timed_lock_ref__, __timed_lock_duration_ref__ and __unlock_ref__ shall be permitted.
+
+[section:nativehandle Member function `native_handle()`]
+
+    typedef platform-specific-type native_handle_type;
+    native_handle_type native_handle();
+
+[variablelist
+
+[[Effects:] [Returns an instance of `native_handle_type` that can be used with platform-specific APIs to manipulate the underlying
+implementation. If no such instance exists, `native_handle()` and `native_handle_type` are not present.]]
+
+[[Throws:] [Nothing.]]
+
+]
+
+[endsect]
+
+[endsect]
+
+[section:recursive_mutex Class `recursive_mutex`]
+
+    #include <boost/thread/recursive_mutex.hpp>
+
+    class recursive_mutex:
+        boost::noncopyable
+    {
+    public:
+        recursive_mutex();
+        ~recursive_mutex();
+        
+        void lock();
+        bool try_lock();
+        void unlock();
+
+        typedef platform-specific-type native_handle_type;
+        native_handle_type native_handle();
+        
+        typedef unique_lock<recursive_mutex> scoped_lock;
+        typedef unspecified-type scoped_try_lock;
+    };
+
+__recursive_mutex__ implements the __lockable_concept__ to provide an exclusive-ownership recursive mutex. At most one thread can
+own the lock on a given instance of __recursive_mutex__ at any time. Multiple concurrent calls to __lock_ref__, __try_lock_ref__ and
+__unlock_ref__ shall be permitted. A thread that already has exclusive ownership of a given __recursive_mutex__ instance can call
+__lock_ref__ or __try_lock_ref__ to acquire an additional level of ownership of the mutex. __unlock_ref__ must be called once for
+each level of ownership acquired by a single thread before ownership can be acquired by another thread.
+
+[section:nativehandle Member function `native_handle()`]
+
+    typedef platform-specific-type native_handle_type;
+    native_handle_type native_handle();
+
+[variablelist
+
+[[Effects:] [Returns an instance of `native_handle_type` that can be used with platform-specific APIs to manipulate the underlying
+implementation. If no such instance exists, `native_handle()` and `native_handle_type` are not present.]]
+
+[[Throws:] [Nothing.]]
+
+]
+
+[endsect]
+
+[endsect]
+
+[section:recursive_try_mutex Typedef `recursive_try_mutex`]
+
+    #include <boost/thread/recursive_mutex.hpp>
+
+    typedef recursive_mutex recursive_try_mutex;
+
+__recursive_try_mutex__ is a `typedef` to __recursive_mutex__, provided for backwards compatibility with previous releases of boost.
+
+[endsect]
+
+[section:recursive_timed_mutex Class `recursive_timed_mutex`]
+
+    #include <boost/thread/recursive_mutex.hpp>
+
+    class recursive_timed_mutex:
+        boost::noncopyable
+    {
+    public:
+        recursive_timed_mutex();
+        ~recursive_timed_mutex();
+        
+        void lock();
+        bool try_lock();
+        void unlock();
+
+        bool timed_lock(system_time const & abs_time);
+
+        template<typename TimeDuration>
+        bool timed_lock(TimeDuration const & relative_time);
+
+        typedef platform-specific-type native_handle_type;
+        native_handle_type native_handle();
+        
+        typedef unique_lock<recursive_timed_mutex> scoped_lock;
+        typedef unspecified-type scoped_try_lock;
+        typedef scoped_lock scoped_timed_lock;
+    };
+
+__recursive_timed_mutex__ implements the __timed_lockable_concept__ to provide an exclusive-ownership recursive mutex. At most one
+thread can own the lock on a given instance of __recursive_timed_mutex__ at any time. Multiple concurrent calls to __lock_ref__,
+__try_lock_ref__, __timed_lock_ref__, __timed_lock_duration_ref__ and __unlock_ref__ shall be permitted. A thread that already has
+exclusive ownership of a given __recursive_timed_mutex__ instance can call __lock_ref__, __timed_lock_ref__,
+__timed_lock_duration_ref__ or __try_lock_ref__ to acquire an additional level of ownership of the mutex. __unlock_ref__ must be
+called once for each level of ownership acquired by a single thread before ownership can be acquired by another thread.
+
+[section:nativehandle Member function `native_handle()`]
+
+    typedef platform-specific-type native_handle_type;
+    native_handle_type native_handle();
+
+[variablelist
+
+[[Effects:] [Returns an instance of `native_handle_type` that can be used with platform-specific APIs to manipulate the underlying
+implementation. If no such instance exists, `native_handle()` and `native_handle_type` are not present.]]
+
+[[Throws:] [Nothing.]]
+
+]
+
+[endsect]
+
+[endsect]
+
+[include shared_mutex_ref.qbk]
+
+[endsect]
diff --git a/deal.II/contrib/boost/libs/thread/doc/once.qbk b/deal.II/contrib/boost/libs/thread/doc/once.qbk
new file mode 100644 (file)
index 0000000..fd53e7d
--- /dev/null
@@ -0,0 +1,56 @@
+[/
+  (C) Copyright 2007-8 Anthony Williams.
+  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).
+]
+
+[section:once One-time Initialization]
+
+`boost::call_once` provides a mechanism for ensuring that an initialization routine is run exactly once without data races or deadlocks.
+
+[section:once_flag Typedef `once_flag`]
+
+    #include <boost/thread/once.hpp>
+
+    typedef platform-specific-type once_flag;
+    #define BOOST_ONCE_INIT platform-specific-initializer
+
+Objects of type `boost::once_flag` shall be initialized with `BOOST_ONCE_INIT`:
+
+    boost::once_flag f=BOOST_ONCE_INIT;
+
+[endsect]
+
+[section:call_once Non-member function `call_once`]
+
+    #include <boost/thread/once.hpp>
+
+    template<typename Callable>
+    void call_once(once_flag& flag,Callable func);
+
+[variablelist
+
+[[Requires:] [`Callable` is `CopyConstructible`. Copying `func` shall have no side effects, and the effect of calling the copy shall
+be equivalent to calling the original. ]]
+
+[[Effects:] [Calls to `call_once` on the same `once_flag` object are serialized. If there has been no prior effective `call_once` on
+the same `once_flag` object, the argument `func` (or a copy thereof) is called as-if by invoking `func()`, and the invocation of
+`call_once` is effective if and only if `func()` returns without exception. If an exception is thrown, the exception is
+propagated to the caller. If there has been a prior effective `call_once` on the same `once_flag` object, the `call_once` returns
+without invoking `func`. ]]
+
+[[Synchronization:] [The completion of an effective `call_once` invocation on a `once_flag` object, synchronizes with
+all subsequent `call_once` invocations on the same `once_flag` object. ]]
+
+[[Throws:] [`thread_resource_error` when the effects cannot be achieved. or any exception propagated from `func`.]]
+
+]
+
+    void call_once(void (*func)(),once_flag& flag);
+    
+This second overload is provided for backwards compatibility. The effects of `call_once(func,flag)` shall be the same as those of
+`call_once(flag,func)`.
+
+[endsect]
+[endsect]
diff --git a/deal.II/contrib/boost/libs/thread/doc/overview.qbk b/deal.II/contrib/boost/libs/thread/doc/overview.qbk
new file mode 100644 (file)
index 0000000..c647a6d
--- /dev/null
@@ -0,0 +1,30 @@
+[/
+  (C) Copyright 2007-8 Anthony Williams.
+  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).
+]
+
+[section:overview Overview]
+
+__boost_thread__ enables the use of multiple threads of execution with shared data in portable C++ code. It provides classes and
+functions for managing the threads themselves, along with others for synchronizing data between the threads or providing separate
+copies of data specific to individual threads.
+
+The __boost_thread__ library was originally written and designed by William E. Kempf. This version is a major rewrite designed to
+closely follow the proposals presented to the C++ Standards Committee, in particular
+[@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2497.html N2497],
+[@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2320.html N2320],
+[@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2184.html N2184], 
+[@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n2139.html N2139], and 
+[@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n2094.html N2094]
+
+In order to use the classes and functions described here, you can
+either include the specific headers specified by the descriptions of
+each class or function, or include the master thread library header:
+
+    #include <boost/thread.hpp>
+
+which includes all the other headers in turn.
+
+[endsect]
diff --git a/deal.II/contrib/boost/libs/thread/doc/shared_mutex_ref.qbk b/deal.II/contrib/boost/libs/thread/doc/shared_mutex_ref.qbk
new file mode 100644 (file)
index 0000000..49cd167
--- /dev/null
@@ -0,0 +1,44 @@
+[/
+  (C) Copyright 2007-8 Anthony Williams.
+  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).
+]
+
+[section:shared_mutex Class `shared_mutex`]
+
+    #include <boost/thread/shared_mutex.hpp>
+
+    class shared_mutex
+    {
+    public:
+        shared_mutex();
+        ~shared_mutex();
+
+        void lock_shared();
+        bool try_lock_shared();
+        bool timed_lock_shared(system_time const& timeout);
+        void unlock_shared();
+
+        void lock();
+        bool try_lock();
+        bool timed_lock(system_time const& timeout);
+        void unlock();
+
+        void lock_upgrade();
+        void unlock_upgrade();
+
+        void unlock_upgrade_and_lock();
+        void unlock_and_lock_upgrade();
+        void unlock_and_lock_shared();
+        void unlock_upgrade_and_lock_shared();
+    };
+
+The class `boost::shared_mutex` provides an implementation of a multiple-reader / single-writer mutex. It implements the
+__upgrade_lockable_concept__.
+
+Multiple concurrent calls to __lock_ref__, __try_lock_ref__, __timed_lock_ref__, __lock_shared_ref__, __try_lock_shared_ref__ and
+__timed_lock_shared_ref__ shall be permitted.
+
+
+[endsect]
diff --git a/deal.II/contrib/boost/libs/thread/doc/thread.qbk b/deal.II/contrib/boost/libs/thread/doc/thread.qbk
new file mode 100644 (file)
index 0000000..e6346db
--- /dev/null
@@ -0,0 +1,167 @@
+[/
+  (C) Copyright 2007-8 Anthony Williams.
+  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).
+]
+
+[article Thread
+    [quickbook 1.4]
+    [authors [Williams, Anthony]]
+    [copyright 2007-8 Anthony Williams]
+    [purpose C++ Library for launching threads and synchronizing data between them]
+    [category text]
+    [license
+        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])
+    ]
+]
+
+[template lockable_concept_link[link_text] [link thread.synchronization.mutex_concepts.lockable [link_text]]]
+[def __lockable_concept__ [lockable_concept_link `Lockable` concept]]
+[def __lockable_concept_type__ [lockable_concept_link `Lockable`]]
+
+[template timed_lockable_concept_link[link_text] [link thread.synchronization.mutex_concepts.timed_lockable [link_text]]]
+[def __timed_lockable_concept__ [timed_lockable_concept_link `TimedLockable` concept]]
+[def __timed_lockable_concept_type__ [timed_lockable_concept_link `TimedLockable`]]
+
+[template shared_lockable_concept_link[link_text] [link thread.synchronization.mutex_concepts.shared_lockable [link_text]]]
+[def __shared_lockable_concept__ [shared_lockable_concept_link `SharedLockable` concept]]
+[def __shared_lockable_concept_type__ [shared_lockable_concept_link `SharedLockable`]]
+
+[template upgrade_lockable_concept_link[link_text] [link thread.synchronization.mutex_concepts.upgrade_lockable [link_text]]]
+[def __upgrade_lockable_concept__ [upgrade_lockable_concept_link `UpgradeLockable` concept]]
+[def __upgrade_lockable_concept_type__ [upgrade_lockable_concept_link `UpgradeLockable`]]
+
+
+[template lock_ref_link[link_text] [link thread.synchronization.mutex_concepts.lockable.lock [link_text]]]
+[def __lock_ref__ [lock_ref_link `lock()`]]
+
+[template lock_multiple_ref_link[link_text] [link thread.synchronization.lock_functions.lock_multiple [link_text]]]
+[def __lock_multiple_ref__ [lock_multiple_ref_link `lock()`]]
+
+[template try_lock_multiple_ref_link[link_text] [link thread.synchronization.lock_functions.try_lock_multiple [link_text]]]
+[def __try_lock_multiple_ref__ [try_lock_multiple_ref_link `try_lock()`]]
+
+[template unlock_ref_link[link_text] [link thread.synchronization.mutex_concepts.lockable.unlock [link_text]]]
+[def __unlock_ref__ [unlock_ref_link `unlock()`]]
+
+[template try_lock_ref_link[link_text] [link thread.synchronization.mutex_concepts.lockable.try_lock [link_text]]]
+[def __try_lock_ref__ [try_lock_ref_link `try_lock()`]]
+
+[template timed_lock_ref_link[link_text] [link thread.synchronization.mutex_concepts.timed_lockable.timed_lock [link_text]]]
+[def __timed_lock_ref__ [timed_lock_ref_link `timed_lock()`]]
+
+[template timed_lock_duration_ref_link[link_text] [link thread.synchronization.mutex_concepts.timed_lockable.timed_lock_duration [link_text]]]
+[def __timed_lock_duration_ref__ [timed_lock_duration_ref_link `timed_lock()`]]
+
+[template lock_shared_ref_link[link_text] [link thread.synchronization.mutex_concepts.shared_lockable.lock_shared [link_text]]]
+[def __lock_shared_ref__ [lock_shared_ref_link `lock_shared()`]]
+
+[template unlock_shared_ref_link[link_text] [link thread.synchronization.mutex_concepts.shared_lockable.unlock_shared [link_text]]]
+[def __unlock_shared_ref__ [unlock_shared_ref_link `unlock_shared()`]]
+
+[template try_lock_shared_ref_link[link_text] [link thread.synchronization.mutex_concepts.shared_lockable.try_lock_shared [link_text]]]
+[def __try_lock_shared_ref__ [try_lock_shared_ref_link `try_lock_shared()`]]
+
+[template timed_lock_shared_ref_link[link_text] [link thread.synchronization.mutex_concepts.shared_lockable.timed_lock_shared [link_text]]]
+[def __timed_lock_shared_ref__ [timed_lock_shared_ref_link `timed_lock_shared()`]]
+
+[template timed_lock_shared_duration_ref_link[link_text] [link thread.synchronization.mutex_concepts.shared_lockable.timed_lock_shared_duration [link_text]]]
+[def __timed_lock_shared_duration_ref__ [timed_lock_shared_duration_ref_link `timed_lock_shared()`]]
+
+[template lock_upgrade_ref_link[link_text] [link thread.synchronization.mutex_concepts.upgrade_lockable.lock_upgrade [link_text]]]
+[def __lock_upgrade_ref__ [lock_upgrade_ref_link `lock_upgrade()`]]
+
+[template unlock_upgrade_ref_link[link_text] [link thread.synchronization.mutex_concepts.upgrade_lockable.unlock_upgrade [link_text]]]
+[def __unlock_upgrade_ref__ [unlock_upgrade_ref_link `unlock_upgrade()`]]
+
+[template unlock_upgrade_and_lock_ref_link[link_text] [link thread.synchronization.mutex_concepts.upgrade_lockable.unlock_upgrade_and_lock [link_text]]]
+[def __unlock_upgrade_and_lock_ref__ [unlock_upgrade_and_lock_ref_link `unlock_upgrade_and_lock()`]]
+
+[template unlock_and_lock_upgrade_ref_link[link_text] [link thread.synchronization.mutex_concepts.upgrade_lockable.unlock_and_lock_upgrade [link_text]]]
+[def __unlock_and_lock_upgrade_ref__ [unlock_and_lock_upgrade_ref_link `unlock_and_lock_upgrade()`]]
+
+[template unlock_upgrade_and_lock_shared_ref_link[link_text] [link thread.synchronization.mutex_concepts.upgrade_lockable.unlock_upgrade_and_lock_shared [link_text]]]
+[def __unlock_upgrade_and_lock_shared_ref__ [unlock_upgrade_and_lock_shared_ref_link `unlock_upgrade_and_lock_shared()`]]
+
+[template owns_lock_ref_link[link_text] [link thread.synchronization.locks.unique_lock.owns_lock [link_text]]]
+[def __owns_lock_ref__ [owns_lock_ref_link `owns_lock()`]]
+
+[template owns_lock_shared_ref_link[link_text] [link thread.synchronization.locks.shared_lock.owns_lock [link_text]]]
+[def __owns_lock_shared_ref__ [owns_lock_shared_ref_link `owns_lock()`]]
+
+[template mutex_func_ref_link[link_text] [link thread.synchronization.locks.unique_lock.mutex [link_text]]]
+[def __mutex_func_ref__ [mutex_func_ref_link `mutex()`]]
+
+[def __boost_thread__ [*Boost.Thread]]
+[def __not_a_thread__ ['Not-a-Thread]]
+[def __interruption_points__ [link interruption_points ['interruption points]]]
+
+[def __mutex__ [link thread.synchronization.mutex_types.mutex `boost::mutex`]]
+[def __try_mutex__ [link thread.synchronization.mutex_types.try_mutex `boost::try_mutex`]]
+[def __timed_mutex__ [link thread.synchronization.mutex_types.timed_mutex `boost::timed_mutex`]]
+[def __recursive_mutex__ [link thread.synchronization.mutex_types.recursive_mutex `boost::recursive_mutex`]]
+[def __recursive_try_mutex__ [link thread.synchronization.mutex_types.recursive_try_mutex `boost::recursive_try_mutex`]]
+[def __recursive_timed_mutex__ [link thread.synchronization.mutex_types.recursive_timed_mutex `boost::recursive_timed_mutex`]]
+[def __shared_mutex__ [link thread.synchronization.mutex_types.shared_mutex `boost::shared_mutex`]]
+
+[template unique_lock_link[link_text] [link thread.synchronization.locks.unique_lock [link_text]]]
+
+[def __lock_guard__ [link thread.synchronization.locks.lock_guard `boost::lock_guard`]]
+[def __unique_lock__ [unique_lock_link `boost::unique_lock`]]
+[def __shared_lock__ [link thread.synchronization.locks.shared_lock `boost::shared_lock`]]
+[def __upgrade_lock__ [link thread.synchronization.locks.upgrade_lock `boost::upgrade_lock`]]
+[def __upgrade_to_unique_lock__ [link thread.synchronization.locks.upgrade_to_unique_lock `boost::upgrade_to_unique_lock`]]
+
+
+[def __thread__ [link thread.thread_management.thread `boost::thread`]]
+[def __thread_id__ [link thread.thread_management.thread.id `boost::thread::id`]]
+[template join_link[link_text] [link thread.thread_management.thread.join [link_text]]]
+[def __join__ [join_link `join()`]]
+[template timed_join_link[link_text] [link thread.thread_management.thread.timed_join [link_text]]]
+[def __timed_join__ [timed_join_link `timed_join()`]]
+[def __detach__ [link thread.thread_management.thread.detach `detach()`]]
+[def __interrupt__ [link thread.thread_management.thread.interrupt `interrupt()`]]
+[def __sleep__ [link thread.thread_management.this_thread.sleep `boost::this_thread::sleep()`]]
+
+[def __interruption_enabled__ [link thread.thread_management.this_thread.interruption_enabled `boost::this_thread::interruption_enabled()`]]
+[def __interruption_requested__ [link thread.thread_management.this_thread.interruption_requested `boost::this_thread::interruption_requested()`]]
+[def __interruption_point__ [link thread.thread_management.this_thread.interruption_point `boost::this_thread::interruption_point()`]]
+[def __disable_interruption__ [link thread.thread_management.this_thread.disable_interruption `boost::this_thread::disable_interruption`]]
+[def __restore_interruption__ [link thread.thread_management.this_thread.restore_interruption `boost::this_thread::restore_interruption`]]
+
+[def __thread_resource_error__ `boost::thread_resource_error`]
+[def __thread_interrupted__ `boost::thread_interrupted`]
+[def __barrier__ [link thread.synchronization.barriers.barrier `boost::barrier`]]
+
+[template cond_wait_link[link_text] [link thread.synchronization.condvar_ref.condition_variable.wait [link_text]]]
+[def __cond_wait__ [cond_wait_link `wait()`]]
+[template cond_timed_wait_link[link_text] [link thread.synchronization.condvar_ref.condition_variable.timed_wait [link_text]]]
+[def __cond_timed_wait__ [cond_timed_wait_link `timed_wait()`]]
+[template cond_any_wait_link[link_text] [link thread.synchronization.condvar_ref.condition_variable_any.wait [link_text]]]
+[def __cond_any_wait__ [cond_any_wait_link `wait()`]]
+[template cond_any_timed_wait_link[link_text] [link thread.synchronization.condvar_ref.condition_variable_any.timed_wait [link_text]]]
+[def __cond_any_timed_wait__ [cond_any_timed_wait_link `timed_wait()`]]
+
+[def __blocked__ ['blocked]]
+
+[include overview.qbk]
+[include changes.qbk]
+
+[include thread_ref.qbk]
+
+[section:synchronization Synchronization]
+[include mutex_concepts.qbk]
+[include mutexes.qbk]
+[include condition_variables.qbk]
+[include once.qbk]
+[include barrier.qbk]
+[endsect]
+
+[include tss.qbk]
+
+[include time.qbk]
+
+[include acknowledgements.qbk]
diff --git a/deal.II/contrib/boost/libs/thread/doc/thread_ref.qbk b/deal.II/contrib/boost/libs/thread/doc/thread_ref.qbk
new file mode 100644 (file)
index 0000000..43e62ea
--- /dev/null
@@ -0,0 +1,1064 @@
+[/
+  (C) Copyright 2007-8 Anthony Williams.
+  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).
+]
+
+[section:thread_management Thread Management]
+
+[heading Synopsis]
+
+The __thread__ class is responsible for launching and managing threads. Each __thread__ object represents a single thread of execution,
+or __not_a_thread__, and at most one __thread__ object represents a given thread of execution: objects of type __thread__ are not
+copyable.
+
+Objects of type __thread__ are movable, however, so they can be stored in move-aware containers, and returned from functions. This
+allows the details of thread creation to be wrapped in a function.
+
+    boost::thread make_thread();
+
+    void f()
+    {
+        boost::thread some_thread=make_thread();
+        some_thread.join();
+    }
+
+[Note: On compilers that support rvalue references, __thread__ provides a proper move constructor and move-assignment operator, and
+therefore meets the C++0x ['MoveConstructible] and ['MoveAssignable] concepts. With such compilers, __thread__ can therefore be used
+with containers that support those concepts.
+
+For other compilers, move support is provided with a move emulation layer, so containers must explicitly detect that move emulation
+layer. See <boost/thread/detail/move.hpp> for details.]
+
+[heading Launching threads]
+
+A new thread is launched by passing an object of a callable type that can be invoked with no parameters to the constructor. The
+object is then copied into internal storage, and invoked on the newly-created thread of execution. If the object must not (or
+cannot) be copied, then `boost::ref` can be used to pass in a reference to the function object. In this case, the user of
+__boost_thread__ must ensure that the referred-to object outlives the newly-created thread of execution.
+
+    struct callable
+    {
+        void operator()();
+    };
+
+    boost::thread copies_are_safe()
+    {
+        callable x;
+        return boost::thread(x);
+    } // x is destroyed, but the newly-created thread has a copy, so this is OK
+
+    boost::thread oops()
+    {
+        callable x;
+        return boost::thread(boost::ref(x));
+    } // x is destroyed, but the newly-created thread still has a reference
+      // this leads to undefined behaviour
+
+If you wish to construct an instance of __thread__ with a function or callable object that requires arguments to be supplied,
+this can be done by passing additional arguments to the __thread__ constructor:
+
+    void find_the_question(int the_answer);
+
+    boost::thread deep_thought_2(find_the_question,42);
+
+The arguments are ['copied] into the internal thread structure: if a reference is required, use `boost::ref`, just as for references
+to callable functions.
+
+There is an unspecified limit on the number of additional arguments that can be passed.
+
+[heading Exceptions in thread functions]
+
+If the function or callable object passed to the __thread__ constructor propagates an exception when invoked that is not of type
+__thread_interrupted__, `std::terminate()` is called. 
+
+[heading Joining and detaching]
+
+When the __thread__ object that represents a thread of execution is destroyed the thread becomes ['detached]. Once a thread is
+detached, it will continue executing until the invocation of the function or callable object supplied on construction has completed,
+or the program is terminated. A thread can also be detached by explicitly invoking the __detach__ member function on the __thread__
+object. In this case, the __thread__ object ceases to represent the now-detached thread, and instead represents __not_a_thread__.
+
+In order to wait for a thread of execution to finish, the __join__ or __timed_join__ member functions of the __thread__ object must be
+used. __join__ will block the calling thread until the thread represented by the __thread__ object has completed. If the thread of
+execution represented by the __thread__ object has already completed, or the __thread__ object represents __not_a_thread__, then __join__
+returns immediately. __timed_join__ is similar, except that a call to __timed_join__ will also return if the thread being waited for
+does not complete when the specified time has elapsed.
+
+[heading Interruption]
+
+A running thread can be ['interrupted] by invoking the __interrupt__ member function of the corresponding __thread__ object. When the
+interrupted thread next executes one of the specified __interruption_points__ (or if it is currently __blocked__ whilst executing one)
+with interruption enabled, then a __thread_interrupted__ exception will be thrown in the interrupted thread. If not caught,
+this will cause the execution of the interrupted thread to terminate. As with any other exception, the stack will be unwound, and
+destructors for objects of automatic storage duration will be executed.
+
+If a thread wishes to avoid being interrupted, it can create an instance of __disable_interruption__. Objects of this class disable
+interruption for the thread that created them on construction, and restore the interruption state to whatever it was before on
+destruction:
+
+    void f()
+    {
+        // interruption enabled here
+        {
+            boost::this_thread::disable_interruption di;
+            // interruption disabled
+            {
+                boost::this_thread::disable_interruption di2;
+                // interruption still disabled
+            } // di2 destroyed, interruption state restored
+            // interruption still disabled
+        } // di destroyed, interruption state restored
+        // interruption now enabled
+    }
+
+The effects of an instance of __disable_interruption__ can be temporarily reversed by constructing an instance of
+__restore_interruption__, passing in the __disable_interruption__ object in question. This will
+restore the interruption state to what it was when the __disable_interruption__ object was constructed, and then
+disable interruption again when the __restore_interruption__ object is destroyed.
+
+    void g()
+    {
+        // interruption enabled here
+        {
+            boost::this_thread::disable_interruption di;
+            // interruption disabled
+            {
+                boost::this_thread::restore_interruption ri(di);
+                // interruption now enabled
+            } // ri destroyed, interruption disable again
+        } // di destroyed, interruption state restored
+        // interruption now enabled
+    }
+
+At any point, the interruption state for the current thread can be queried by calling __interruption_enabled__.
+
+[#interruption_points]
+
+[heading Predefined Interruption Points]
+
+The following functions are ['interruption points], which will throw __thread_interrupted__ if interruption is enabled for the
+current thread, and interruption is requested for the current thread:
+
+* [join_link `boost::thread::join()`]
+* [timed_join_link `boost::thread::timed_join()`]
+* [cond_wait_link `boost::condition_variable::wait()`]
+* [cond_timed_wait_link `boost::condition_variable::timed_wait()`]
+* [cond_any_wait_link `boost::condition_variable_any::wait()`]
+* [cond_any_timed_wait_link `boost::condition_variable_any::timed_wait()`]
+* [link thread.thread_management.thread.sleep `boost::thread::sleep()`]
+* __sleep__
+* __interruption_point__
+
+[heading Thread IDs]
+
+Objects of class __thread_id__ can be used to identify threads. Each running thread of execution has a unique ID obtainable
+from the corresponding __thread__ by calling the `get_id()` member function, or by calling `boost::this_thread::get_id()` from
+within the thread. Objects of class __thread_id__ can be copied, and used as keys in associative containers: the full range of
+comparison operators is provided. Thread IDs can also be written to an output stream using the stream insertion operator, though the
+output format is unspecified.
+
+Each instance of __thread_id__ either refers to some thread, or __not_a_thread__. Instances that refer to __not_a_thread__
+compare equal to each other, but not equal to any instances that refer to an actual thread of execution. The comparison operators on
+__thread_id__ yield a total order for every non-equal thread ID.
+
+[section:thread Class `thread`]
+
+    #include <boost/thread/thread.hpp>
+
+    class thread
+    {
+    public:
+        thread();
+        ~thread();
+
+        template <class F>
+        explicit thread(F f);
+
+        template <class F,class A1,class A2,...>
+        thread(F f,A1 a1,A2 a2,...);
+
+        template <class F>
+        thread(detail::thread_move_t<F> f);
+
+        // move support
+        thread(detail::thread_move_t<thread> x);
+        thread& operator=(detail::thread_move_t<thread> x);
+        operator detail::thread_move_t<thread>();
+        detail::thread_move_t<thread> move();
+
+        void swap(thread& x);
+
+        class id;
+        id get_id() const;
+
+        bool joinable() const;
+        void join();
+        bool timed_join(const system_time& wait_until);
+
+        template<typename TimeDuration>
+        bool timed_join(TimeDuration const& rel_time);
+
+        void detach();
+
+        static unsigned hardware_concurrency();
+
+        typedef platform-specific-type native_handle_type;
+        native_handle_type native_handle();
+
+        void interrupt();
+        bool interruption_requested() const;
+
+        // backwards compatibility
+        bool operator==(const thread& other) const;
+        bool operator!=(const thread& other) const;
+
+        static void yield();
+        static void sleep(const system_time& xt);
+    };
+
+    void swap(thread& lhs,thread& rhs);
+
+[section:default_constructor Default Constructor]
+
+    thread();
+
+[variablelist
+
+[[Effects:] [Constructs a __thread__ instance that refers to __not_a_thread__.]]
+
+[[Throws:] [Nothing]]
+
+]
+
+[endsect]
+
+[section:callable_constructor Thread Constructor]
+
+    template<typename Callable>
+    thread(Callable func);
+
+[variablelist
+
+[[Preconditions:] [`Callable` must by copyable.]]
+
+[[Effects:] [`func` is copied into storage managed internally by the thread library, and that copy is invoked on a newly-created
+thread of execution. If this invocation results in an exception being propagated into the internals of the thread library that is
+not of type __thread_interrupted__, then `std::terminate()` will be called.]]
+
+[[Postconditions:] [`*this` refers to the newly created thread of execution.]]
+
+[[Throws:] [__thread_resource_error__ if an error occurs.]]
+
+]
+
+[endsect]
+
+[section:multiple_argument_constructor Thread Constructor with arguments]
+
+    template <class F,class A1,class A2,...>
+    thread(F f,A1 a1,A2 a2,...);
+
+[variablelist
+
+[[Preconditions:] [`F` and each `A`n must by copyable or movable.]]
+
+[[Effects:] [As if [link
+thread.thread_management.thread.callable_constructor
+`thread(boost::bind(f,a1,a2,...))`. Consequently, `f` and each `a`n
+are copied into internal storage for access by the new thread.]]]
+
+[[Postconditions:] [`*this` refers to the newly created thread of execution.]]
+
+[[Throws:] [__thread_resource_error__ if an error occurs.]]
+
+[[Note:] [Currently up to nine additional arguments `a1` to `a9` can be specified in addition to the function `f`.]]
+
+]
+
+[endsect]
+
+[section:destructor Thread Destructor]
+
+    ~thread();
+
+[variablelist
+
+[[Effects:] [If `*this` has an associated thread of execution, calls __detach__. Destroys `*this`.]]
+
+[[Throws:] [Nothing.]]
+
+]
+
+[endsect]
+
+[section:joinable Member function `joinable()`]
+
+    bool joinable() const;
+
+[variablelist
+
+[[Returns:] [`true` if `*this` refers to a thread of execution, `false` otherwise.]]
+
+[[Throws:] [Nothing]]
+
+]
+
+
+[endsect]
+
+[section:join Member function `join()`]
+
+    void join();
+
+[variablelist
+
+[[Preconditions:] [`this->get_id()!=boost::this_thread::get_id()`]]
+
+[[Effects:] [If `*this` refers to a thread of execution, waits for that thread of execution to complete.]]
+
+[[Postconditions:] [If `*this` refers to a thread of execution on entry, that thread of execution has completed. `*this` no longer refers to any thread of execution.]]
+
+[[Throws:] [__thread_interrupted__ if the current thread of execution is interrupted.]]
+
+[[Notes:] [`join()` is one of the predefined __interruption_points__.]]
+
+]
+
+[endsect]
+
+[section:timed_join Member function `timed_join()`]
+
+    bool timed_join(const system_time& wait_until);
+
+    template<typename TimeDuration>
+    bool timed_join(TimeDuration const& rel_time);
+
+[variablelist
+
+[[Preconditions:] [`this->get_id()!=boost::this_thread::get_id()`]]
+
+[[Effects:] [If `*this` refers to a thread of execution, waits for that thread of execution to complete, the time `wait_until` has
+been reach or the specified duration `rel_time` has elapsed. If `*this` doesn't refer to a thread of execution, returns immediately.]]
+
+[[Returns:] [`true` if `*this` refers to a thread of execution on entry, and that thread of execution has completed before the call
+times out, `false` otherwise.]]
+
+[[Postconditions:] [If `*this` refers to a thread of execution on entry, and `timed_join` returns `true`, that thread of execution
+has completed, and `*this` no longer refers to any thread of execution. If this call to `timed_join` returns `false`, `*this` is
+unchanged.]]
+
+[[Throws:] [__thread_interrupted__ if the current thread of execution is interrupted.]]
+
+[[Notes:] [`timed_join()` is one of the predefined __interruption_points__.]]
+
+]
+
+[endsect]
+
+[section:detach Member function `detach()`]
+
+    void detach();
+
+[variablelist
+
+[[Effects:] [If `*this` refers to a thread of execution, that thread of execution becomes detached, and no longer has an associated __thread__ object.]]
+
+[[Postconditions:] [`*this` no longer refers to any thread of execution.]]
+
+[[Throws:] [Nothing]]
+
+]
+
+[endsect]
+
+
+[section:get_id Member function `get_id()`]
+
+    thread::id get_id() const;
+
+[variablelist
+
+[[Returns:] [If `*this` refers to a thread of execution, an instance of __thread_id__ that represents that thread. Otherwise returns
+a default-constructed __thread_id__.]]
+
+[[Throws:] [Nothing]]
+
+]
+
+[endsect]
+
+[section:interrupt Member function `interrupt()`]
+
+    void interrupt();
+
+[variablelist
+
+[[Effects:] [If `*this` refers to a thread of execution, request that the thread will be interrupted the next time it enters one of
+the predefined __interruption_points__ with interruption enabled, or if it is currently __blocked__ in a call to one of the
+predefined __interruption_points__ with interruption enabled .]]
+
+[[Throws:] [Nothing]]
+
+]
+        
+
+[endsect]
+
+[section:hardware_concurrency Static member function `hardware_concurrency()`]
+
+    unsigned hardware_concurrency();
+
+[variablelist
+
+[[Returns:] [The number of hardware threads available on the current system (e.g. number of CPUs or cores or hyperthreading units),
+or 0 if this information is not available.]]
+
+[[Throws:] [Nothing]]
+
+]
+
+[endsect]
+
+[section:nativehandle Member function `native_handle()`]
+
+    typedef platform-specific-type native_handle_type;
+    native_handle_type native_handle();
+
+[variablelist
+
+[[Effects:] [Returns an instance of `native_handle_type` that can be used with platform-specific APIs to manipulate the underlying
+implementation. If no such instance exists, `native_handle()` and `native_handle_type` are not present.]]
+
+[[Throws:] [Nothing.]]
+
+]
+
+[endsect]
+
+[section:equals `operator==`]
+
+    bool operator==(const thread& other) const;
+
+[variablelist
+
+[[Returns:] [`get_id()==other.get_id()`]]
+
+]
+
+[endsect]
+
+[section:not_equals `operator!=`]
+
+    bool operator!=(const thread& other) const;
+
+[variablelist
+
+[[Returns:] [`get_id()!=other.get_id()`]]
+
+]
+
+[endsect]
+
+[section:sleep Static member function `sleep()`]
+
+    void sleep(system_time const& abs_time);
+
+[variablelist
+
+[[Effects:] [Suspends the current thread until the specified time has been reached.]]
+
+[[Throws:] [__thread_interrupted__ if the current thread of execution is interrupted.]]
+
+[[Notes:] [`sleep()` is one of the predefined __interruption_points__.]]
+
+]
+
+[endsect]
+
+[section:yield Static member function `yield()`]
+
+    void yield();
+
+[variablelist
+
+[[Effects:] [See [link thread.thread_management.this_thread.yield `boost::this_thread::yield()`].]]
+
+]
+
+[endsect]
+
+[section:swap Member function `swap()`]
+
+    void swap(thread& other);
+
+[variablelist
+
+[[Effects:] [Exchanges the threads of execution associated with `*this` and `other`, so `*this` is associated with the thread of
+execution associated with `other` prior to the call, and vice-versa.]]
+
+[[Postconditions:] [`this->get_id()` returns the same value as `other.get_id()` prior to the call. `other.get_id()` returns the same
+value as `this->get_id()` prior to the call.]]
+
+[[Throws:] [Nothing.]]
+
+]
+
+[endsect]
+
+[section:non_member_swap Non-member function `swap()`]
+
+    #include <boost/thread/thread.hpp>
+
+    void swap(thread& lhs,thread& rhs);
+
+[variablelist
+
+[[Effects:] [[link thread.thread_management.thread.swap `lhs.swap(rhs)`].]]
+
+]
+
+[endsect]
+
+
+[section:id Class `boost::thread::id`]
+
+    #include <boost/thread/thread.hpp>
+
+    class thread::id
+    {
+    public:
+        id();
+
+        bool operator==(const id& y) const;
+        bool operator!=(const id& y) const;
+        bool operator<(const id& y) const;
+        bool operator>(const id& y) const;
+        bool operator<=(const id& y) const;
+        bool operator>=(const id& y) const;
+
+        template<class charT, class traits>
+        friend std::basic_ostream<charT, traits>& 
+        operator<<(std::basic_ostream<charT, traits>& os, const id& x);
+    };
+
+[section:constructor Default constructor]
+
+    id();
+
+[variablelist
+
+[[Effects:] [Constructs a __thread_id__ instance that represents __not_a_thread__.]]
+
+[[Throws:] [Nothing]]
+
+]
+
+[endsect]
+
+[section:is_equal `operator==`]
+
+    bool operator==(const id& y) const;
+
+[variablelist
+
+[[Returns:] [`true` if `*this` and `y` both represent the same thread of execution, or both represent __not_a_thread__, `false`
+otherwise.]]
+
+[[Throws:] [Nothing]]
+
+]
+
+[endsect]
+
+[section:not_equal `operator!=`]
+
+    bool operator!=(const id& y) const;
+
+[variablelist
+
+[[Returns:] [`true` if `*this` and `y` represent different threads of execution, or one represents a thread of execution, and
+the other represent __not_a_thread__, `false` otherwise.]]
+
+[[Throws:] [Nothing]]
+
+]
+
+[endsect]
+
+[section:less_than `operator<`]
+
+    bool operator<(const id& y) const;
+
+[variablelist
+
+[[Returns:] [`true` if `*this!=y` is `true` and the implementation-defined total order of __thread_id__ values places `*this` before
+`y`, `false` otherwise.]]
+
+[[Throws:] [Nothing]]
+
+[[Note:] [A __thread_id__ instance representing __not_a_thread__ will always compare less than an instance representing a thread of
+execution.]]
+
+]
+
+[endsect]
+
+
+[section:greater_than `operator>`]
+
+    bool operator>(const id& y) const;
+
+[variablelist
+
+[[Returns:] [`y<*this`]]
+
+[[Throws:] [Nothing]]
+
+]
+
+[endsect]
+
+[section:less_than_or_equal `operator>=`]
+
+    bool operator<=(const id& y) const;
+
+[variablelist
+
+[[Returns:] [`!(y<*this)`]]
+
+[[Throws:] [Nothing]]
+
+]
+
+[endsect]
+
+[section:greater_than_or_equal `operator>=`]
+
+    bool operator>=(const id& y) const;
+
+[variablelist
+
+[[Returns:] [`!(*this<y)`]]
+
+[[Throws:] [Nothing]]
+
+]
+
+[endsect]
+
+[section:stream_out Friend `operator<<`]
+
+    template<class charT, class traits>
+    friend std::basic_ostream<charT, traits>& 
+    operator<<(std::basic_ostream<charT, traits>& os, const id& x);
+
+[variablelist
+
+[[Effects:] [Writes a representation of the __thread_id__ instance `x` to the stream `os`, such that the representation of two
+instances of __thread_id__ `a` and `b` is the same if `a==b`, and different if `a!=b`.]]
+
+[[Returns:] [`os`]]
+
+]
+
+[endsect]
+
+
+[endsect]
+
+[endsect]
+
+[section:this_thread Namespace `this_thread`]
+
+[section:get_id Non-member function `get_id()`]
+
+    #include <boost/thread/thread.hpp>
+
+    namespace this_thread
+    {
+        thread::id get_id();
+    }
+
+[variablelist
+
+[[Returns:] [An instance of __thread_id__ that represents that currently executing thread.]]
+
+[[Throws:] [__thread_resource_error__ if an error occurs.]]
+
+]
+
+[endsect]
+
+[section:interruption_point Non-member function `interruption_point()`]
+
+    #include <boost/thread/thread.hpp>
+
+    namespace this_thread
+    {
+        void interruption_point();
+    }
+
+[variablelist
+
+[[Effects:] [Check to see if the current thread has been interrupted.]]
+
+[[Throws:] [__thread_interrupted__ if __interruption_enabled__ and __interruption_requested__ both return `true`.]]
+
+]
+
+[endsect]
+
+[section:interruption_requested Non-member function `interruption_requested()`]
+
+    #include <boost/thread/thread.hpp>
+
+    namespace this_thread
+    {
+        bool interruption_requested();
+    }
+
+[variablelist
+
+[[Returns:] [`true` if interruption has been requested for the current thread, `false` otherwise.]]
+
+[[Throws:] [Nothing.]]
+
+]
+
+[endsect]
+
+[section:interruption_enabled Non-member function `interruption_enabled()`]
+
+    #include <boost/thread/thread.hpp>
+
+    namespace this_thread
+    {
+        bool interruption_enabled();
+    }
+
+[variablelist
+
+[[Returns:] [`true` if interruption has been enabled for the current thread, `false` otherwise.]]
+
+[[Throws:] [Nothing.]]
+
+]
+
+[endsect]
+
+[section:sleep Non-member function `sleep()`]
+
+    #include <boost/thread/thread.hpp>
+
+    namespace this_thread
+    {
+        template<typename TimeDuration>
+        void sleep(TimeDuration const& rel_time);
+    }
+
+[variablelist
+
+[[Effects:] [Suspends the current thread until the specified time has elapsed.]]
+
+[[Throws:] [__thread_interrupted__ if the current thread of execution is interrupted.]]
+
+[[Notes:] [`sleep()` is one of the predefined __interruption_points__.]]
+
+]
+
+[endsect]
+
+[section:yield Non-member function `yield()`]
+
+    #include <boost/thread/thread.hpp>
+
+    namespace this_thread
+    {
+        void yield();
+    }
+
+[variablelist
+
+[[Effects:] [Gives up the remainder of the current thread's time slice, to allow other threads to run.]]
+
+[[Throws:] [Nothing.]]
+
+]
+
+[endsect]
+
+[section:disable_interruption Class `disable_interruption`]
+
+    #include <boost/thread/thread.hpp>
+
+    namespace this_thread
+    {
+        class disable_interruption
+        {
+        public:
+            disable_interruption();
+            ~disable_interruption();
+        };
+    }
+
+`boost::this_thread::disable_interruption` disables interruption for the current thread on construction, and restores the prior
+interruption state on destruction. Instances of `disable_interruption` cannot be copied or moved.
+
+[section:constructor Constructor]
+
+    disable_interruption();
+
+[variablelist
+
+[[Effects:] [Stores the current state of __interruption_enabled__ and disables interruption for the current thread.]]
+
+[[Postconditions:] [__interruption_enabled__ returns `false` for the current thread.]]
+
+[[Throws:] [Nothing.]]
+
+]
+
+[endsect]
+
+[section:destructor Destructor]
+
+    ~disable_interruption();
+
+[variablelist
+
+[[Preconditions:] [Must be called from the same thread from which `*this` was constructed.]]
+
+[[Effects:] [Restores the current state of __interruption_enabled__ for the current thread to that prior to the construction of `*this`.]]
+
+[[Postconditions:] [__interruption_enabled__ for the current thread returns the value stored in the constructor of `*this`.]]
+
+[[Throws:] [Nothing.]]
+
+]
+
+[endsect]
+
+[endsect]
+
+[section:restore_interruption Class `restore_interruption`]
+
+    #include <boost/thread/thread.hpp>
+
+    namespace this_thread
+    {
+        class restore_interruption
+        {
+        public:
+            explicit restore_interruption(disable_interruption& disabler);
+            ~restore_interruption();
+        };
+    }
+
+On construction of an instance of `boost::this_thread::restore_interruption`, the interruption state for the current thread is
+restored to the interruption state stored by the constructor of the supplied instance of __disable_interruption__. When the instance
+is destroyed, interruption is again disabled. Instances of `restore_interruption` cannot be copied or moved.
+
+[section:constructor Constructor]
+
+    explicit restore_interruption(disable_interruption& disabler);
+
+[variablelist
+
+[[Preconditions:] [Must be called from the same thread from which `disabler` was constructed.]]
+
+[[Effects:] [Restores the current state of __interruption_enabled__ for the current thread to that prior to the construction of `disabler`.]]
+
+[[Postconditions:] [__interruption_enabled__ for the current thread returns the value stored in the constructor of `disabler`.]]
+
+[[Throws:] [Nothing.]]
+
+]
+
+[endsect]
+
+[section:destructor Destructor]
+
+    ~restore_interruption();
+
+[variablelist
+
+[[Preconditions:] [Must be called from the same thread from which `*this` was constructed.]]
+
+[[Effects:] [Disables interruption for the current thread.]]
+
+[[Postconditions:] [__interruption_enabled__ for the current thread returns `false`.]]
+
+[[Throws:] [Nothing.]]
+
+]
+
+[endsect]
+
+[endsect]
+
+[section:atthreadexit Non-member function template `at_thread_exit()`]
+
+    #include <boost/thread/thread.hpp>
+
+    template<typename Callable>
+    void at_thread_exit(Callable func);
+
+[variablelist
+
+[[Effects:] [A copy of `func` is placed in
+thread-specific storage. This copy is invoked when the current thread
+exits (even if the thread has been interrupted).]]
+
+[[Postconditions:] [A copy of `func` has been saved for invocation on thread exit.]]
+
+[[Throws:] [`std::bad_alloc` if memory cannot be allocated for the copy of the function, __thread_resource_error__ if any other
+error occurs within the thread library. Any exception thrown whilst copying `func` into internal storage.]]
+
+]
+
+[endsect]
+
+[endsect]
+
+[section:threadgroup Class `thread_group`]
+
+    #include <boost/thread/thread.hpp>
+
+    class thread_group:
+        private noncopyable
+    {
+    public:
+        thread_group();
+        ~thread_group();
+
+        template<typename F>
+        thread* create_thread(F threadfunc);
+        void add_thread(thread* thrd);
+        void remove_thread(thread* thrd);
+        void join_all();
+        void interrupt_all();
+        int size() const;
+    };
+
+`thread_group` provides for a collection of threads that are related in some fashion. New threads can be added to the group with
+`add_thread` and `create_thread` member functions. `thread_group` is not copyable or movable.
+
+[section:constructor Constructor]
+
+    thread_group();
+
+[variablelist
+
+[[Effects:] [Create a new thread group with no threads.]]
+
+]
+
+[endsect]
+
+[section:destructor Destructor]
+
+    ~thread_group();
+
+[variablelist
+
+[[Effects:] [Destroy `*this` and `delete` all __thread__ objects in the group.]]
+
+]
+
+[endsect]
+
+[section:create_thread Member function `create_thread()`]
+
+    template<typename F>
+    thread* create_thread(F threadfunc);
+
+[variablelist
+
+[[Effects:] [Create a new __thread__ object as-if by `new thread(threadfunc)` and add it to the group.]]
+
+[[Postcondition:] [`this->size()` is increased by one, the new thread is running.]]
+
+[[Returns:] [A pointer to the new __thread__ object.]]
+
+]
+
+[endsect]
+
+[section:add_thread Member function `add_thread()`]
+
+    void add_thread(thread* thrd);
+
+[variablelist
+
+[[Precondition:] [The expression `delete thrd` is well-formed and will not result in undefined behaviour.]]
+
+[[Effects:] [Take ownership of the __thread__ object pointed to by `thrd` and add it to the group.]]
+
+[[Postcondition:] [`this->size()` is increased by one.]]
+
+]
+
+[endsect]
+
+[section:remove_thread Member function `remove_thread()`]
+
+    void remove_thread(thread* thrd);
+
+[variablelist
+
+[[Effects:] [If `thrd` is a member of the group, remove it without calling `delete`.]]
+
+[[Postcondition:] [If `thrd` was a member of the group, `this->size()` is decreased by one.]]
+
+]
+
+[endsect]
+
+[section:join_all Member function `join_all()`]
+
+    void join_all();
+
+[variablelist
+
+[[Effects:] [Call `join()` on each __thread__ object in the group.]]
+
+[[Postcondition:] [Every thread in the group has terminated.]]
+
+[[Note:] [Since __join__ is one of the predefined __interruption_points__, `join_all()` is also an interruption point.]]
+
+]
+
+[endsect]
+
+[section:interrupt_all Member function `interrupt_all()`]
+
+    void interrupt_all();
+
+[variablelist
+
+[[Effects:] [Call `interrupt()` on each __thread__ object in the group.]]
+
+]
+
+[endsect]
+
+[section:size Member function `size()`]
+
+    int size();
+
+[variablelist
+
+[[Returns:] [The number of threads in the group.]]
+
+[[Throws:] [Nothing.]]
+
+]
+
+[endsect]
+
+
+[endsect]
+
+[endsect]
diff --git a/deal.II/contrib/boost/libs/thread/doc/time.qbk b/deal.II/contrib/boost/libs/thread/doc/time.qbk
new file mode 100644 (file)
index 0000000..8798542
--- /dev/null
@@ -0,0 +1,75 @@
+[/
+  (C) Copyright 2007-8 Anthony Williams.
+  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).
+]
+
+[section:time Date and Time Requirements]
+
+As of Boost 1.35.0, the __boost_thread__ library uses the [link date_time Boost.Date_Time] library for all operations that require a
+time out. These include (but are not limited to):
+
+* __sleep__
+* __timed_join__
+* __cond_timed_wait__
+* __timed_lock_ref__
+
+For the overloads that accept an absolute time parameter, an object of type [link thread.time.system_time `boost::system_time`] is
+required. Typically, this will be obtained by adding a duration to the current time, obtained with a call to [link
+thread.time.get_system_time `boost::get_system_time()`]. e.g.
+
+    boost::system_time const timeout=boost::get_system_time() + boost::posix_time::milliseconds(500);
+
+    extern bool done;
+    extern boost::mutex m;
+    extern boost::condition_variable cond;
+
+    boost::unique_lock<boost::mutex> lk(m);
+    while(!done)
+    {
+        if(!cond.timed_wait(lk,timeout))
+        {
+            throw "timed out";
+        }
+    }
+
+For the overloads that accept a ['TimeDuration] parameter, an object of any type that meets the [link
+date_time.posix_time.time_duration Boost.Date_Time Time Duration requirements] can be used, e.g.
+
+    boost::this_thread::sleep(boost::posix_time::milliseconds(25));
+    
+    boost::mutex m;
+    if(m.timed_lock(boost::posix_time::nanoseconds(100)))
+    {
+        //  ...
+    }
+
+[section:system_time Typedef `system_time`]
+
+    #include <boost/thread/thread_time.hpp>
+
+    typedef boost::posix_time::ptime system_time;
+
+See the documentation for [link date_time.posix_time.ptime_class `boost::posix_time::ptime`] in the Boost.Date_Time library.
+
+[endsect]
+
+[section:get_system_time Non-member function `get_system_time()`]
+
+    #include <boost/thread/thread_time.hpp>
+
+    system_time get_system_time();
+
+[variablelist
+
+[[Returns:] [The current time.]]
+
+[[Throws:] [Nothing.]]
+
+]
+
+[endsect]
+
+
+[endsect]
\ No newline at end of file
diff --git a/deal.II/contrib/boost/libs/thread/doc/tss.qbk b/deal.II/contrib/boost/libs/thread/doc/tss.qbk
new file mode 100644 (file)
index 0000000..6a9ffc4
--- /dev/null
@@ -0,0 +1,184 @@
+[/
+  (C) Copyright 2007-8 Anthony Williams.
+  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).
+]
+
+[section Thread Local Storage]
+
+[heading Synopsis]
+
+Thread local storage allows multi-threaded applications to have a separate instance of a given data item for each thread. Where a
+single-threaded application would use static or global data, this could lead to contention, deadlock or data corruption in a
+multi-threaded application. One example is the C `errno` variable, used for storing the error code related to functions from the
+Standard C library. It is common practice (and required by POSIX) for compilers that support multi-threaded applications to provide
+a separate instance of `errno` for each thread, in order to avoid different threads competing to read or update the value.
+
+Though compilers often provide this facility in the form of extensions to the declaration syntax (such as `__declspec(thread)` or
+`__thread` annotations on `static` or namespace-scope variable declarations), such support is non-portable, and is often limited in
+some way, such as only supporting POD types.
+
+[heading Portable thread-local storage with `boost::thread_specific_ptr`]
+
+`boost::thread_specific_ptr` provides a portable mechanism for thread-local storage that works on all compilers supported by
+__boost_thread__. Each instance of `boost::thread_specific_ptr` represents a pointer to an object (such as `errno`) where each
+thread must have a distinct value. The value for the current thread can be obtained using the `get()` member function, or by using
+the `*` and `->` pointer deference operators. Initially the pointer has a value of `NULL` in each thread, but the value for the
+current thread can be set using the `reset()` member function.
+
+If the value of the pointer for the current thread is changed using `reset()`, then the previous value is destroyed by calling the
+cleanup routine. Alternatively, the stored value can be reset to `NULL` and the prior value returned by calling the `release()`
+member function, allowing the application to take back responsibility for destroying the object.
+
+[heading Cleanup at thread exit]
+
+When a thread exits, the objects associated with each `boost::thread_specific_ptr` instance are destroyed. By default, the object
+pointed to by a pointer `p` is destroyed by invoking `delete p`, but this can be overridden for a specific instance of
+`boost::thread_specific_ptr` by providing a cleanup routine to the constructor. In this case, the object is destroyed by invoking
+`func(p)` where `func` is the cleanup routine supplied to the constructor. The cleanup functions are called in an unspecified
+order. If a cleanup routine sets the value of associated with an instance of `boost::thread_specific_ptr` that has already been
+cleaned up, that value is added to the cleanup list. Cleanup finishes when there are no outstanding instances of
+`boost::thread_specific_ptr` with values.
+
+
+[section:thread_specific_ptr Class `thread_specific_ptr`]
+
+    #include <boost/thread/tss.hpp>
+
+    template <typename T>
+    class thread_specific_ptr
+    {
+    public:
+        thread_specific_ptr();
+        explicit thread_specific_ptr(void (*cleanup_function)(T*));
+        ~thread_specific_ptr();
+
+        T* get() const;
+        T* operator->() const;
+        T& operator*() const;
+
+        T* release();
+        void reset(T* new_value=0);
+    };
+
+[section:default_constructor `thread_specific_ptr();`]
+
+[variablelist
+
+[[Requires:] [`delete this->get()` is well-formed.]]
+
+[[Effects:] [Construct a `thread_specific_ptr` object for storing a pointer to an object of type `T` specific to each thread. The
+default `delete`-based cleanup function will be used to destroy any thread-local objects when `reset()` is called, or the thread
+exits.]]
+
+[[Throws:] [`boost::thread_resource_error` if an error occurs.]]
+
+]
+
+[endsect]
+
+[section:constructor_with_custom_cleanup `explicit thread_specific_ptr(void (*cleanup_function)(T*));`]
+
+[variablelist
+
+[[Requires:] [`cleanup_function(this->get())` does not throw any exceptions.]]
+
+[[Effects:] [Construct a `thread_specific_ptr` object for storing a pointer to an object of type `T` specific to each thread. The
+supplied `cleanup_function` will be used to destroy any thread-local objects when `reset()` is called, or the thread exits.]]
+
+[[Throws:] [`boost::thread_resource_error` if an error occurs.]]
+
+]
+
+[endsect]
+
+[section:destructor `~thread_specific_ptr();`]
+
+[variablelist
+
+[[Effects:] [Calls `this->reset()` to clean up the associated value for the current thread, and destroys `*this`.]]
+
+[[Throws:] [Nothing.]]
+
+]
+
+[note Care needs to be taken to ensure that any threads still running after an instance of `boost::thread_specific_ptr` has been
+destroyed do not call any member functions on that instance.]
+
+[endsect]
+
+[section:get `T* get() const;`]
+
+[variablelist
+
+[[Returns:] [The pointer associated with the current thread.]]
+
+[[Throws:] [Nothing.]]
+
+]
+
+[note The initial value associated with an instance of `boost::thread_specific_ptr` is `NULL` for each thread.]
+
+[endsect]
+
+[section:operator_arrow `T* operator->() const;`]
+
+[variablelist
+
+[[Returns:] [`this->get()`]]
+
+[[Throws:] [Nothing.]]
+
+]
+
+[endsect]
+
+[section:operator_star `T& operator*() const;`]
+
+[variablelist
+
+[[Requires:] [`this->get` is not `NULL`.]]
+
+[[Returns:] [`*(this->get())`]]
+
+[[Throws:] [Nothing.]]
+
+]
+
+[endsect]
+
+[section:reset `void reset(T* new_value=0);`]
+
+[variablelist
+
+[[Effects:] [If `this->get()!=new_value` and `this->get()` is non-`NULL`, invoke `delete this->get()` or
+`cleanup_function(this->get())` as appropriate. Store `new_value` as the pointer associated with the current thread.]]
+
+[[Postcondition:] [`this->get()==new_value`]]
+
+[[Throws:] [`boost::thread_resource_error` if an error occurs.]]
+
+]
+
+[endsect]
+
+[section:release `T* release();`]
+
+[variablelist
+
+[[Effects:] [Return `this->get()` and store `NULL` as the pointer associated with the current thread without invoking the cleanup
+function.]]
+
+[[Postcondition:] [`this->get()==0`]]
+
+[[Throws:] [Nothing.]]
+
+]
+
+[endsect]
+
+
+[endsect]
+
+[endsect]
diff --git a/deal.II/contrib/boost/libs/thread/example/Jamfile.v2 b/deal.II/contrib/boost/libs/thread/example/Jamfile.v2
new file mode 100644 (file)
index 0000000..bfc8a59
--- /dev/null
@@ -0,0 +1,23 @@
+# Copyright (C) 2001-2003
+# William E. Kempf
+#
+#  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)
+
+project boost/thread/example 
+    : requirements <library>../build//boost_thread <threading>multi
+    ;
+       
+
+exe monitor : monitor.cpp ;
+exe starvephil : starvephil.cpp ;
+exe tennis : tennis.cpp ;
+exe condition : condition.cpp ;
+exe mutex : mutex.cpp ;
+exe once : once.cpp ;
+exe recursive_mutex : recursive_mutex.cpp ;
+exe thread : thread.cpp ;
+exe thread_group : thread_group.cpp ;
+exe tss : tss.cpp ;
+exe xtime : xtime.cpp ;
+
diff --git a/deal.II/contrib/boost/libs/thread/example/condition.cpp b/deal.II/contrib/boost/libs/thread/example/condition.cpp
new file mode 100644 (file)
index 0000000..096c35d
--- /dev/null
@@ -0,0 +1,82 @@
+// Copyright (C) 2001-2003
+// William E. Kempf
+//
+//  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 <iostream>
+#include <vector>
+#include <boost/utility.hpp>
+#include <boost/thread/condition.hpp>
+#include <boost/thread/thread.hpp>
+
+class bounded_buffer : private boost::noncopyable
+{
+public:
+    typedef boost::mutex::scoped_lock lock;
+
+    bounded_buffer(int n) : begin(0), end(0), buffered(0), circular_buf(n) { }
+
+    void send (int m) {
+        lock lk(monitor);
+        while (buffered == circular_buf.size())
+            buffer_not_full.wait(lk);
+        circular_buf[end] = m;
+        end = (end+1) % circular_buf.size();
+        ++buffered;
+        buffer_not_empty.notify_one();
+    }
+    int receive() {
+        lock lk(monitor);
+        while (buffered == 0)
+            buffer_not_empty.wait(lk);
+        int i = circular_buf[begin];
+        begin = (begin+1) % circular_buf.size();
+        --buffered;
+        buffer_not_full.notify_one();
+        return i;
+    }
+
+private:
+    int begin, end, buffered;
+    std::vector<int> circular_buf;
+    boost::condition buffer_not_full, buffer_not_empty;
+    boost::mutex monitor;
+};
+
+bounded_buffer buf(2);
+
+boost::mutex io_mutex;
+
+void sender() {
+    int n = 0;
+    while (n < 100) {
+        buf.send(n);
+        {
+            boost::mutex::scoped_lock io_lock(io_mutex);
+            std::cout << "sent: " << n << std::endl;
+        }
+        ++n;
+    }
+    buf.send(-1);
+}
+
+void receiver() {
+    int n;
+    do {
+        n = buf.receive();
+        {
+            boost::mutex::scoped_lock io_lock(io_mutex);
+            std::cout << "received: " << n << std::endl;
+        }
+    } while (n != -1); // -1 indicates end of buffer
+}
+
+int main(int, char*[])
+{
+    boost::thread thrd1(&sender);
+    boost::thread thrd2(&receiver);
+    thrd1.join();
+    thrd2.join();
+    return 0;
+}
diff --git a/deal.II/contrib/boost/libs/thread/example/monitor.cpp b/deal.II/contrib/boost/libs/thread/example/monitor.cpp
new file mode 100644 (file)
index 0000000..0a7383f
--- /dev/null
@@ -0,0 +1,112 @@
+// Copyright (C) 2001-2003
+// William E. Kempf
+//
+//  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 <vector>
+#include <iostream>
+#include <boost/thread/condition.hpp>
+#include <boost/thread/mutex.hpp>
+#include <boost/thread/recursive_mutex.hpp>
+#include <boost/thread/thread.hpp>
+
+namespace {
+const int ITERS = 100;
+boost::mutex io_mutex;
+} // namespace
+
+template <typename M>
+class buffer_t
+{
+public:
+    typedef typename M::scoped_lock scoped_lock;
+
+    buffer_t(int n)
+        : p(0), c(0), full(0), buf(n)
+    {
+    }
+
+    void send(int m)
+    {
+        scoped_lock lk(mutex);
+        while (full == buf.size())
+            cond.wait(lk);
+        buf[p] = m;
+        p = (p+1) % buf.size();
+        ++full;
+        cond.notify_one();
+    }
+    int receive()
+    {
+        scoped_lock lk(mutex);
+        while (full == 0)
+            cond.wait(lk);
+        int i = buf[c];
+        c = (c+1) % buf.size();
+        --full;
+        cond.notify_one();
+        return i;
+    }
+
+    static buffer_t& get_buffer()
+    {
+        static buffer_t buf(2);
+        return buf;
+    }
+
+    static void do_sender_thread()
+    {
+        for (int n = 0; n < ITERS; ++n)
+        {
+            {
+                boost::mutex::scoped_lock lock(io_mutex);
+                std::cout << "sending: " << n << std::endl;
+            }
+            get_buffer().send(n);
+        }
+    }
+
+    static void do_receiver_thread()
+    {
+        for (int x=0; x < (ITERS/2); ++x)
+        {
+            int n = get_buffer().receive();
+            {
+                boost::mutex::scoped_lock lock(io_mutex);
+                std::cout << "received: " << n << std::endl;
+            }
+        }
+    }
+
+private:
+    M mutex;
+    boost::condition cond;
+    unsigned int p, c, full;
+    std::vector<int> buf;
+};
+
+template <typename M>
+void do_test(M* dummy=0)
+{
+    typedef buffer_t<M> buffer_type;
+    buffer_type::get_buffer();
+    boost::thread thrd1(&buffer_type::do_receiver_thread);
+    boost::thread thrd2(&buffer_type::do_receiver_thread);
+    boost::thread thrd3(&buffer_type::do_sender_thread);
+    thrd1.join();
+    thrd2.join();
+    thrd3.join();
+}
+
+void test_buffer()
+{
+    do_test<boost::mutex>();
+    do_test<boost::recursive_mutex>();
+}
+
+int main()
+{
+    test_buffer();
+    return 0;
+}
diff --git a/deal.II/contrib/boost/libs/thread/example/mutex.cpp b/deal.II/contrib/boost/libs/thread/example/mutex.cpp
new file mode 100644 (file)
index 0000000..b276d54
--- /dev/null
@@ -0,0 +1,47 @@
+// Copyright (C) 2001-2003
+// William E. Kempf
+//
+//  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/thread/mutex.hpp>
+#include <boost/thread/thread.hpp>
+#include <iostream>
+
+boost::mutex io_mutex; // The iostreams are not guaranteed to be thread-safe!
+
+class counter
+{
+public:
+    counter() : count(0) { }
+
+    int increment() {
+        boost::mutex::scoped_lock scoped_lock(mutex);
+        return ++count;
+    }
+
+private:
+    boost::mutex mutex;
+    int count;
+};
+
+counter c;
+
+void change_count()
+{
+    int i = c.increment();
+    boost::mutex::scoped_lock scoped_lock(io_mutex);
+    std::cout << "count == " << i << std::endl;
+}
+
+int main(int, char*[])
+{
+    const int num_threads = 4;
+    boost::thread_group thrds;
+    for (int i=0; i < num_threads; ++i)
+        thrds.create_thread(&change_count);
+
+    thrds.join_all();
+
+    return 0;
+}
diff --git a/deal.II/contrib/boost/libs/thread/example/once.cpp b/deal.II/contrib/boost/libs/thread/example/once.cpp
new file mode 100644 (file)
index 0000000..5a5b6f5
--- /dev/null
@@ -0,0 +1,31 @@
+// Copyright (C) 2001-2003
+// William E. Kempf
+//
+//  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/thread/thread.hpp>
+#include <boost/thread/once.hpp>
+#include <cassert>
+
+int value=0;
+boost::once_flag once = BOOST_ONCE_INIT;
+
+void init()
+{
+    ++value;
+}
+
+void thread_proc()
+{
+    boost::call_once(&init, once);
+}
+
+int main(int argc, char* argv[])
+{
+    boost::thread_group threads;
+    for (int i=0; i<5; ++i)
+        threads.create_thread(&thread_proc);
+    threads.join_all();
+    assert(value == 1);
+}
diff --git a/deal.II/contrib/boost/libs/thread/example/recursive_mutex.cpp b/deal.II/contrib/boost/libs/thread/example/recursive_mutex.cpp
new file mode 100644 (file)
index 0000000..c519954
--- /dev/null
@@ -0,0 +1,49 @@
+// Copyright (C) 2001-2003
+// William E. Kempf
+//
+//  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/thread/recursive_mutex.hpp>
+#include <boost/thread/thread.hpp>
+#include <iostream>
+
+class counter
+{
+public:
+    counter() : count(0) { }
+
+    int add(int val) {
+        boost::recursive_mutex::scoped_lock scoped_lock(mutex);
+        count += val;
+        return count;
+    }
+    int increment() {
+        boost::recursive_mutex::scoped_lock scoped_lock(mutex);
+        return add(1);
+    }
+
+private:
+    boost::recursive_mutex mutex;
+    int count;
+};
+
+counter c;
+
+void change_count()
+{
+    std::cout << "count == " << c.increment() << std::endl;
+}
+
+int main(int, char*[])
+{
+    const int num_threads=4;
+
+    boost::thread_group threads;
+    for (int i=0; i < num_threads; ++i)
+        threads.create_thread(&change_count);
+
+    threads.join_all();
+
+    return 0;
+}
diff --git a/deal.II/contrib/boost/libs/thread/example/starvephil.cpp b/deal.II/contrib/boost/libs/thread/example/starvephil.cpp
new file mode 100644 (file)
index 0000000..0ef2e0d
--- /dev/null
@@ -0,0 +1,185 @@
+// Copyright (C) 2001-2003
+// William E. Kempf
+//
+//  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/thread/mutex.hpp>
+#include <boost/thread/condition.hpp>
+#include <boost/thread/thread.hpp>
+#include <boost/thread/xtime.hpp>
+#include <iostream>
+#include <time.h>
+
+namespace
+{
+boost::mutex iomx;
+} // namespace
+
+class canteen
+{
+public:
+    canteen() : m_chickens(0) { }
+
+    void get(int id)
+    {
+        boost::mutex::scoped_lock lock(m_mutex);
+        while (m_chickens == 0)
+        {
+            {
+                boost::mutex::scoped_lock lock(iomx);
+                std::cout << "(" << clock() << ") Phil" << id <<
+                    ": wot, no chickens?  I'll WAIT ..." << std::endl;
+            }
+            m_condition.wait(lock);
+        }
+        {
+            boost::mutex::scoped_lock lock(iomx);
+            std::cout << "(" << clock() << ") Phil" << id <<
+                ": those chickens look good ... one please ..." << std::endl;
+        }
+        m_chickens--;
+    }
+    void put(int value)
+    {
+        boost::mutex::scoped_lock lock(m_mutex);
+        {
+            boost::mutex::scoped_lock lock(iomx);
+            std::cout << "(" << clock()
+                      << ") Chef: ouch ... make room ... this dish is "
+                      << "very hot ..." << std::endl;
+        }
+        boost::xtime xt;
+        boost::xtime_get(&xt, boost::TIME_UTC);
+        xt.sec += 3;
+        boost::thread::sleep(xt);
+        m_chickens += value;
+        {
+            boost::mutex::scoped_lock lock(iomx);
+            std::cout << "(" << clock() <<
+                ") Chef: more chickens ... " << m_chickens <<
+                " now available ... NOTIFYING ..." << std::endl;
+        }
+        m_condition.notify_all();
+    }
+
+private:
+    boost::mutex m_mutex;
+    boost::condition m_condition;
+    int m_chickens;
+};
+
+canteen g_canteen;
+
+void chef()
+{
+    const int chickens = 4;
+    {
+        boost::mutex::scoped_lock lock(iomx);
+        std::cout << "(" << clock() << ") Chef: starting ..." << std::endl;
+    }
+    for (;;)
+    {
+        {
+            boost::mutex::scoped_lock lock(iomx);
+            std::cout << "(" << clock() << ") Chef: cooking ..." << std::endl;
+        }
+        boost::xtime xt;
+        boost::xtime_get(&xt, boost::TIME_UTC);
+        xt.sec += 2;
+        boost::thread::sleep(xt);
+        {
+            boost::mutex::scoped_lock lock(iomx);
+            std::cout << "(" << clock() << ") Chef: " << chickens
+                      << " chickens, ready-to-go ..." << std::endl;
+        }
+        g_canteen.put(chickens);
+    }
+}
+
+struct phil
+{
+    phil(int id) : m_id(id) { }
+    void run() {
+        {
+            boost::mutex::scoped_lock lock(iomx);
+            std::cout << "(" << clock() << ") Phil" << m_id
+                      << ": starting ..." << std::endl;
+        }
+        for (;;)
+        {
+            if (m_id > 0)
+            {
+                boost::xtime xt;
+                boost::xtime_get(&xt, boost::TIME_UTC);
+                xt.sec += 3;
+                boost::thread::sleep(xt);
+            }
+            {
+                boost::mutex::scoped_lock lock(iomx);
+                std::cout << "(" << clock() << ") Phil" << m_id
+                          << ": gotta eat ..." << std::endl;
+            }
+            g_canteen.get(m_id);
+            {
+                boost::mutex::scoped_lock lock(iomx);
+                std::cout << "(" << clock() << ") Phil" << m_id
+                          << ": mmm ... that's good ..." << std::endl;
+            }
+        }
+    }
+    static void do_thread(void* param) {
+        static_cast<phil*>(param)->run();
+    }
+
+    int m_id;
+};
+
+struct thread_adapt
+{
+    thread_adapt(void (*func)(void*), void* param)
+        : _func(func), _param(param)
+    {
+    }
+    int operator()() const
+    {
+        _func(_param);
+        return 0;
+    }
+
+    void (*_func)(void*);
+    void* _param;
+};
+
+class thread_adapter
+{
+public:
+    thread_adapter(void (*func)(void*), void* param)
+        : _func(func), _param(param)
+    {
+    }
+    void operator()() const { _func(_param); }
+private:
+    void (*_func)(void*);
+    void* _param;
+};
+
+int main(int argc, char* argv[])
+{
+    boost::thread thrd_chef(&chef);
+    phil p[] = { phil(0), phil(1), phil(2), phil(3), phil(4) };
+    boost::thread thrd_phil0(thread_adapter(&phil::do_thread, &p[0]));
+    boost::thread thrd_phil1(thread_adapter(&phil::do_thread, &p[1]));
+    boost::thread thrd_phil2(thread_adapter(&phil::do_thread, &p[2]));
+    boost::thread thrd_phil3(thread_adapter(&phil::do_thread, &p[3]));
+    boost::thread thrd_phil4(thread_adapter(&phil::do_thread, &p[4]));
+
+    thrd_chef.join();
+    thrd_phil0.join();
+    thrd_phil1.join();
+    thrd_phil2.join();
+    thrd_phil3.join();
+    thrd_phil4.join();
+
+    return 0;
+}
diff --git a/deal.II/contrib/boost/libs/thread/example/tennis.cpp b/deal.II/contrib/boost/libs/thread/example/tennis.cpp
new file mode 100644 (file)
index 0000000..e222871
--- /dev/null
@@ -0,0 +1,135 @@
+// Copyright (C) 2001-2003
+// William E. Kempf
+//
+//  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/thread/mutex.hpp>
+#include <boost/thread/condition.hpp>
+#include <boost/thread/thread.hpp>
+#include <boost/thread/xtime.hpp>
+#include <iostream>
+
+#if defined(BOOST_HAS_WINTHREADS)
+#   include <windows.h>
+#   include <process.h>
+#endif
+
+enum game_state
+{
+    START,
+    PLAYER_A,
+    PLAYER_B,
+    GAME_OVER,
+    ONE_PLAYER_GONE,
+    BOTH_PLAYERS_GONE
+};
+
+int state;
+boost::mutex mutex;
+boost::condition cond;
+
+char* player_name(int state)
+{
+    if (state == PLAYER_A)
+        return "PLAYER-A";
+    if (state == PLAYER_B)
+        return "PLAYER-B";
+    throw "bad player";
+    return 0;
+}
+
+void player(void* param)
+{
+    boost::mutex::scoped_lock lock(mutex);
+
+    int active = (int)param;
+    int other = active == PLAYER_A ? PLAYER_B : PLAYER_A;
+
+    while (state < GAME_OVER)
+    {
+        std::cout << player_name(active) << ": Play." << std::endl;
+        state = other;
+        cond.notify_all();
+        do
+        {
+            cond.wait(lock);
+            if (state == other)
+            {
+                std::cout << "---" << player_name(active)
+                          << ": Spurious wakeup!" << std::endl;
+            }
+        } while (state == other);
+    }
+
+    ++state;
+    std::cout << player_name(active) << ": Gone." << std::endl;
+    cond.notify_all();
+}
+
+struct thread_adapt
+{
+    thread_adapt(void (*func)(void*), void* param)
+        : _func(func), _param(param)
+    {
+    }
+    int operator()() const
+    {
+        _func(_param);
+        return 0;
+    }
+
+    void (*_func)(void*);
+    void* _param;
+};
+
+class thread_adapter
+{
+public:
+    thread_adapter(void (*func)(void*), void* param)
+        : _func(func), _param(param)
+    {
+    }
+    void operator()() const { _func(_param); }
+private:
+    void (*_func)(void*);
+    void* _param;
+};
+
+int main(int argc, char* argv[])
+{
+    state = START;
+
+    boost::thread thrda(thread_adapter(&player, (void*)PLAYER_A));
+    boost::thread thrdb(thread_adapter(&player, (void*)PLAYER_B));
+
+    boost::xtime xt;
+    boost::xtime_get(&xt, boost::TIME_UTC);
+    xt.sec += 1;
+    boost::thread::sleep(xt);
+    {
+        boost::mutex::scoped_lock lock(mutex);
+        std::cout << "---Noise ON..." << std::endl;
+    }
+
+    for (int i = 0; i < 1000000; ++i)
+        cond.notify_all();
+
+    {
+        boost::mutex::scoped_lock lock(mutex);
+        std::cout << "---Noise OFF..." << std::endl;
+        state = GAME_OVER;
+        cond.notify_all();
+        do
+        {
+            cond.wait(lock);
+        } while (state != BOTH_PLAYERS_GONE);
+    }
+
+    std::cout << "GAME OVER" << std::endl;
+
+    thrda.join();
+    thrdb.join();
+
+    return 0;
+}
diff --git a/deal.II/contrib/boost/libs/thread/example/thread.cpp b/deal.II/contrib/boost/libs/thread/example/thread.cpp
new file mode 100644 (file)
index 0000000..c21a3b5
--- /dev/null
@@ -0,0 +1,35 @@
+// Copyright (C) 2001-2003
+// William E. Kempf
+//
+//  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/thread/thread.hpp>
+#include <boost/thread/xtime.hpp>
+#include <iostream>
+
+struct thread_alarm
+{
+    thread_alarm(int secs) : m_secs(secs) { }
+    void operator()()
+    {
+        boost::xtime xt;
+        boost::xtime_get(&xt, boost::TIME_UTC);
+        xt.sec += m_secs;
+
+        boost::thread::sleep(xt);
+
+        std::cout << "alarm sounded..." << std::endl;
+    }
+
+    int m_secs;
+};
+
+int main(int argc, char* argv[])
+{
+    int secs = 5;
+    std::cout << "setting alarm for 5 seconds..." << std::endl;
+    thread_alarm alarm(secs);
+    boost::thread thrd(alarm);
+    thrd.join();
+}
diff --git a/deal.II/contrib/boost/libs/thread/example/thread_group.cpp b/deal.II/contrib/boost/libs/thread/example/thread_group.cpp
new file mode 100644 (file)
index 0000000..232776d
--- /dev/null
@@ -0,0 +1,25 @@
+// Copyright (C) 2001-2003
+// William E. Kempf
+//
+//  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/thread/thread.hpp>
+#include <iostream>
+
+int count = 0;
+boost::mutex mutex;
+
+void increment_count()
+{
+    boost::mutex::scoped_lock lock(mutex);
+    std::cout << "count = " << ++count << std::endl;
+}
+
+int main(int argc, char* argv[])
+{
+    boost::thread_group threads;
+    for (int i = 0; i < 10; ++i)
+        threads.create_thread(&increment_count);
+    threads.join_all();
+}
diff --git a/deal.II/contrib/boost/libs/thread/example/tss.cpp b/deal.II/contrib/boost/libs/thread/example/tss.cpp
new file mode 100644 (file)
index 0000000..f867a91
--- /dev/null
@@ -0,0 +1,36 @@
+// Copyright (C) 2001-2003
+// William E. Kempf
+//
+//  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/thread/thread.hpp>
+#include <boost/thread/tss.hpp>
+#include <cassert>
+
+boost::thread_specific_ptr<int> value;
+
+void increment()
+{
+    int* p = value.get();
+    ++*p;
+}
+
+void thread_proc()
+{
+    value.reset(new int(0)); // initialize the thread's storage
+    for (int i=0; i<10; ++i)
+    {
+        increment();
+        int* p = value.get();
+        assert(*p == i+1);
+    }
+}
+
+int main(int argc, char* argv[])
+{
+    boost::thread_group threads;
+    for (int i=0; i<5; ++i)
+        threads.create_thread(&thread_proc);
+    threads.join_all();
+}
diff --git a/deal.II/contrib/boost/libs/thread/example/xtime.cpp b/deal.II/contrib/boost/libs/thread/example/xtime.cpp
new file mode 100644 (file)
index 0000000..a9b1933
--- /dev/null
@@ -0,0 +1,16 @@
+// Copyright (C) 2001-2003
+// William E. Kempf
+//
+//  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/thread/thread.hpp>
+#include <boost/thread/xtime.hpp>
+
+int main(int argc, char* argv[])
+{
+    boost::xtime xt;
+    boost::xtime_get(&xt, boost::TIME_UTC);
+    xt.sec += 1;
+    boost::thread::sleep(xt); // Sleep for 1 second
+}
diff --git a/deal.II/contrib/boost/libs/thread/index.html b/deal.II/contrib/boost/libs/thread/index.html
new file mode 100644 (file)
index 0000000..f54e21e
--- /dev/null
@@ -0,0 +1,13 @@
+<!-- Copyright (c) 2002-2003 William E. Kempf.
+     Subject to the Boost Software License, Version 1.0. 
+     (See accompanying file LICENSE_1_0.txt or  http://www.boost.org/LICENSE_1_0.txt)
+-->
+
+<html>
+<head>
+<meta http-equiv="refresh" content="0; URL=doc/index.html">
+</head>
+<body>
+Automatic redirection failed, please go to <a href="doc/index.html">doc/index.html</a>
+</body>
+</html>
diff --git a/deal.II/contrib/boost/libs/thread/src/pthread/exceptions.cpp b/deal.II/contrib/boost/libs/thread/src/pthread/exceptions.cpp
new file mode 100644 (file)
index 0000000..8881303
--- /dev/null
@@ -0,0 +1,124 @@
+// Copyright (C) 2001-2003
+// William E. Kempf
+//
+//  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/thread/detail/config.hpp>
+
+#include <boost/thread/exceptions.hpp>
+#include <cstring>
+#include <string>
+
+namespace boost {
+
+thread_exception::thread_exception()
+    : m_sys_err(0)
+{
+}
+
+thread_exception::thread_exception(int sys_err_code)
+    : m_sys_err(sys_err_code)
+{
+}
+
+thread_exception::~thread_exception() throw()
+{
+}
+
+int thread_exception::native_error() const
+{
+    return m_sys_err; 
+}
+
+lock_error::lock_error()
+{
+}
+
+lock_error::lock_error(int sys_err_code)
+    : thread_exception(sys_err_code)
+{
+}
+
+lock_error::~lock_error() throw()
+{
+}
+
+const char* lock_error::what() const throw()
+{
+    return "boost::lock_error";
+}
+
+thread_resource_error::thread_resource_error()
+{
+}
+
+thread_resource_error::thread_resource_error(int sys_err_code)
+    : thread_exception(sys_err_code)
+{
+}
+
+thread_resource_error::~thread_resource_error() throw()
+{
+}
+
+const char* thread_resource_error::what() const throw()
+{
+    return "boost::thread_resource_error";
+}
+
+unsupported_thread_option::unsupported_thread_option()
+{
+}
+
+unsupported_thread_option::unsupported_thread_option(int sys_err_code)
+    : thread_exception(sys_err_code)
+{
+}
+
+unsupported_thread_option::~unsupported_thread_option() throw()
+{
+}
+
+const char* unsupported_thread_option::what() const throw()
+{
+    return "boost::unsupported_thread_option";
+}
+
+invalid_thread_argument::invalid_thread_argument()
+{
+}
+
+invalid_thread_argument::invalid_thread_argument(int sys_err_code)
+    : thread_exception(sys_err_code)
+{
+}
+
+invalid_thread_argument::~invalid_thread_argument() throw()
+{
+}
+
+const char* invalid_thread_argument::what() const throw()
+{
+    return "boost::invalid_thread_argument";
+}
+
+thread_permission_error::thread_permission_error()
+{
+}
+
+thread_permission_error::thread_permission_error(int sys_err_code)
+    : thread_exception(sys_err_code)
+{
+}
+
+thread_permission_error::~thread_permission_error() throw()
+{
+}
+
+const char* thread_permission_error::what() const throw()
+{
+    return "boost::thread_permission_error";
+}
+
+} // namespace boost
diff --git a/deal.II/contrib/boost/libs/thread/src/pthread/once.cpp b/deal.II/contrib/boost/libs/thread/src/pthread/once.cpp
new file mode 100644 (file)
index 0000000..6e3722a
--- /dev/null
@@ -0,0 +1,51 @@
+// Copyright (C) 2007 Anthony Williams
+//
+//  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)
+
+#define __STDC_CONSTANT_MACROS
+#include <boost/thread/once.hpp>
+#include <boost/assert.hpp>
+#include <pthread.h>
+#include <stdlib.h>
+
+namespace boost
+{
+    namespace detail
+    {
+        BOOST_THREAD_DECL boost::uintmax_t once_global_epoch=UINTMAX_C(~0);
+        BOOST_THREAD_DECL pthread_mutex_t once_epoch_mutex=PTHREAD_MUTEX_INITIALIZER;
+        BOOST_THREAD_DECL pthread_cond_t once_epoch_cv = PTHREAD_COND_INITIALIZER;
+
+        namespace
+        {
+            pthread_key_t epoch_tss_key;
+            pthread_once_t epoch_tss_key_flag=PTHREAD_ONCE_INIT;
+            
+            extern "C" void delete_epoch_tss_data(void* data)
+            {
+                free(data);
+            }
+
+            extern "C" void create_epoch_tss_key()
+            {
+                BOOST_VERIFY(!pthread_key_create(&epoch_tss_key,delete_epoch_tss_data));
+            }
+            
+        }
+        
+        boost::uintmax_t& get_once_per_thread_epoch()
+        {
+            BOOST_VERIFY(!pthread_once(&epoch_tss_key_flag,create_epoch_tss_key));
+            void* data=pthread_getspecific(epoch_tss_key);
+            if(!data)
+            {
+                data=malloc(sizeof(boost::uintmax_t));
+                BOOST_VERIFY(!pthread_setspecific(epoch_tss_key,data));
+                *static_cast<boost::uintmax_t*>(data)=UINTMAX_C(~0);
+            }
+            return *static_cast<boost::uintmax_t*>(data);
+        }
+    }
+    
+}
diff --git a/deal.II/contrib/boost/libs/thread/src/pthread/thread.cpp b/deal.II/contrib/boost/libs/thread/src/pthread/thread.cpp
new file mode 100644 (file)
index 0000000..83f053e
--- /dev/null
@@ -0,0 +1,677 @@
+// Copyright (C) 2001-2003
+// William E. Kempf
+// Copyright (C) 2007-8 Anthony Williams
+//
+//  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/thread/detail/config.hpp>
+
+#include <boost/thread/thread.hpp>
+#include <boost/thread/xtime.hpp>
+#include <boost/thread/condition.hpp>
+#include <boost/thread/locks.hpp>
+#include <boost/thread/once.hpp>
+#include <boost/thread/tss.hpp>
+#ifdef __linux__
+#include <sys/sysinfo.h>
+#elif defined(__APPLE__) || defined(__FreeBSD__)
+#include <sys/types.h>
+#include <sys/sysctl.h>
+#elif defined BOOST_HAS_UNISTD_H
+#include <unistd.h>
+#endif
+
+#include "timeconv.inl"
+
+namespace boost
+{
+    namespace detail
+    {
+        thread_data_base::~thread_data_base()
+        {}
+
+        struct thread_exit_callback_node
+        {
+            boost::detail::thread_exit_function_base* func;
+            thread_exit_callback_node* next;
+
+            thread_exit_callback_node(boost::detail::thread_exit_function_base* func_,
+                                      thread_exit_callback_node* next_):
+                func(func_),next(next_)
+            {}
+        };
+
+        struct tss_data_node
+        {
+            void const* key;
+            boost::shared_ptr<boost::detail::tss_cleanup_function> func;
+            void* value;
+            tss_data_node* next;
+
+            tss_data_node(void const* key_,boost::shared_ptr<boost::detail::tss_cleanup_function> func_,void* value_,
+                          tss_data_node* next_):
+                key(key_),func(func_),value(value_),next(next_)
+            {}
+        };
+
+        namespace
+        {
+            boost::once_flag current_thread_tls_init_flag=BOOST_ONCE_INIT;
+            pthread_key_t current_thread_tls_key;
+
+            extern "C"
+            {
+                void tls_destructor(void* data)
+                {
+                    boost::detail::thread_data_base* thread_info=static_cast<boost::detail::thread_data_base*>(data);
+                    if(thread_info)
+                    {
+                        while(thread_info->tss_data || thread_info->thread_exit_callbacks)
+                        {
+                            while(thread_info->thread_exit_callbacks)
+                            {
+                                detail::thread_exit_callback_node* const current_node=thread_info->thread_exit_callbacks;
+                                thread_info->thread_exit_callbacks=current_node->next;
+                                if(current_node->func)
+                                {
+                                    (*current_node->func)();
+                                    delete current_node->func;
+                                }
+                                delete current_node;
+                            }
+                            while(thread_info->tss_data)
+                            {
+                                detail::tss_data_node* const current_node=thread_info->tss_data;
+                                thread_info->tss_data=current_node->next;
+                                if(current_node->func)
+                                {
+                                    (*current_node->func)(current_node->value);
+                                }
+                                delete current_node;
+                            }
+                        }
+                        thread_info->self.reset();
+                    }
+                }
+            }
+    
+
+            void create_current_thread_tls_key()
+            {
+                BOOST_VERIFY(!pthread_key_create(&current_thread_tls_key,&tls_destructor));
+            }
+        }
+        
+        boost::detail::thread_data_base* get_current_thread_data()
+        {
+            boost::call_once(current_thread_tls_init_flag,create_current_thread_tls_key);
+            return (boost::detail::thread_data_base*)pthread_getspecific(current_thread_tls_key);
+        }
+
+        void set_current_thread_data(detail::thread_data_base* new_data)
+        {
+            boost::call_once(current_thread_tls_init_flag,create_current_thread_tls_key);
+            BOOST_VERIFY(!pthread_setspecific(current_thread_tls_key,new_data));
+        }
+    }
+    
+    namespace
+    {
+        extern "C"
+        {
+            void* thread_proxy(void* param)
+            {
+                boost::detail::thread_data_ptr thread_info = static_cast<boost::detail::thread_data_base*>(param)->self;
+                thread_info->self.reset();
+                detail::set_current_thread_data(thread_info.get());
+                try
+                {
+                    thread_info->run();
+                }
+                catch(thread_interrupted const&)
+                {
+                }
+                catch(...)
+                {
+                    std::terminate();
+                }
+
+                detail::tls_destructor(thread_info.get());
+                detail::set_current_thread_data(0);
+                boost::lock_guard<boost::mutex> lock(thread_info->data_mutex);
+                thread_info->done=true;
+                thread_info->done_condition.notify_all();
+                return 0;
+            }
+        }
+
+        struct externally_launched_thread:
+            detail::thread_data_base
+        {
+            externally_launched_thread()
+            {
+                interrupt_enabled=false;
+            }
+            
+            void run()
+            {}
+
+        private:
+            externally_launched_thread(externally_launched_thread&);
+            void operator=(externally_launched_thread&);
+        };
+
+        detail::thread_data_base* make_external_thread_data()
+        {
+            detail::thread_data_base* const me(new externally_launched_thread());
+            me->self.reset(me);
+            set_current_thread_data(me);
+            return me;
+        }
+
+
+        detail::thread_data_base* get_or_make_current_thread_data()
+        {
+            detail::thread_data_base* current_thread_data(detail::get_current_thread_data());
+            if(!current_thread_data)
+            {
+                current_thread_data=make_external_thread_data();
+            }
+            return current_thread_data;
+        }
+
+    }
+
+
+    thread::thread()
+    {}
+
+    void thread::start_thread()
+    {
+        thread_info->self=thread_info;
+        int const res = pthread_create(&thread_info->thread_handle, 0, &thread_proxy, thread_info.get());
+        if (res != 0)
+        {
+            thread_info->self.reset();
+            throw thread_resource_error();
+        }
+    }
+
+    thread::~thread()
+    {
+        detach();
+    }
+
+    detail::thread_data_ptr thread::get_thread_info() const
+    {
+        lock_guard<mutex> l(thread_info_mutex);
+        return thread_info;
+    }
+
+    void thread::join()
+    {
+        detail::thread_data_ptr const local_thread_info=get_thread_info();
+        if(local_thread_info)
+        {
+            bool do_join=false;
+            
+            {
+                unique_lock<mutex> lock(local_thread_info->data_mutex);
+                while(!local_thread_info->done)
+                {
+                    local_thread_info->done_condition.wait(lock);
+                }
+                do_join=!local_thread_info->join_started;
+                
+                if(do_join)
+                {
+                    local_thread_info->join_started=true;
+                }
+                else
+                {
+                    while(!local_thread_info->joined)
+                    {
+                        local_thread_info->done_condition.wait(lock);
+                    }
+                }
+            }
+            if(do_join)
+            {
+                void* result=0;
+                BOOST_VERIFY(!pthread_join(local_thread_info->thread_handle,&result));
+                lock_guard<mutex> lock(local_thread_info->data_mutex);
+                local_thread_info->joined=true;
+                local_thread_info->done_condition.notify_all();
+            }
+            
+            lock_guard<mutex> l1(thread_info_mutex);
+            if(thread_info==local_thread_info)
+            {
+                thread_info.reset();
+            }
+        }
+    }
+
+    bool thread::timed_join(system_time const& wait_until)
+    {
+        detail::thread_data_ptr const local_thread_info=get_thread_info();
+        if(local_thread_info)
+        {
+            bool do_join=false;
+            
+            {
+                unique_lock<mutex> lock(local_thread_info->data_mutex);
+                while(!local_thread_info->done)
+                {
+                    if(!local_thread_info->done_condition.timed_wait(lock,wait_until))
+                    {
+                        return false;
+                    }
+                }
+                do_join=!local_thread_info->join_started;
+                
+                if(do_join)
+                {
+                    local_thread_info->join_started=true;
+                }
+                else
+                {
+                    while(!local_thread_info->joined)
+                    {
+                        local_thread_info->done_condition.wait(lock);
+                    }
+                }
+            }
+            if(do_join)
+            {
+                void* result=0;
+                BOOST_VERIFY(!pthread_join(local_thread_info->thread_handle,&result));
+                lock_guard<mutex> lock(local_thread_info->data_mutex);
+                local_thread_info->joined=true;
+                local_thread_info->done_condition.notify_all();
+            }
+            
+            lock_guard<mutex> l1(thread_info_mutex);
+            if(thread_info==local_thread_info)
+            {
+                thread_info.reset();
+            }
+        }
+        return true;
+    }
+
+    bool thread::joinable() const
+    {
+        return get_thread_info();
+    }
+
+
+    void thread::detach()
+    {
+        detail::thread_data_ptr local_thread_info;
+        {
+            lock_guard<mutex> l1(thread_info_mutex);
+            thread_info.swap(local_thread_info);
+        }
+        
+        if(local_thread_info)
+        {
+            lock_guard<mutex> lock(local_thread_info->data_mutex);
+            if(!local_thread_info->join_started)
+            {
+                BOOST_VERIFY(!pthread_detach(local_thread_info->thread_handle));
+                local_thread_info->join_started=true;
+                local_thread_info->joined=true;
+            }
+        }
+    }
+
+    namespace this_thread
+    {
+        
+        void sleep(const system_time& st)
+        {
+            detail::thread_data_base* const thread_info=detail::get_current_thread_data();
+        
+            if(thread_info)
+            {
+                unique_lock<mutex> lk(thread_info->sleep_mutex);
+                while(thread_info->sleep_condition.timed_wait(lk,st))
+                 ;
+            }
+            else
+            {
+                xtime const xt=get_xtime(st);
+            
+                for (int foo=0; foo < 5; ++foo)
+                {
+#   if defined(BOOST_HAS_PTHREAD_DELAY_NP)
+                    timespec ts;
+                    to_timespec_duration(xt, ts);
+                    BOOST_VERIFY(!pthread_delay_np(&ts));
+#   elif defined(BOOST_HAS_NANOSLEEP)
+                    timespec ts;
+                    to_timespec_duration(xt, ts);
+                
+                    //  nanosleep takes a timespec that is an offset, not
+                    //  an absolute time.
+                    nanosleep(&ts, 0);
+#   else
+                    mutex mx;
+                    mutex::scoped_lock lock(mx);
+                    condition cond;
+                    cond.timed_wait(lock, xt);
+#   endif
+                    xtime cur;
+                    xtime_get(&cur, TIME_UTC);
+                    if (xtime_cmp(xt, cur) <= 0)
+                        return;
+                }
+            }
+        }
+
+        void yield()
+        {
+#   if defined(BOOST_HAS_SCHED_YIELD)
+            BOOST_VERIFY(!sched_yield());
+#   elif defined(BOOST_HAS_PTHREAD_YIELD)
+            BOOST_VERIFY(!pthread_yield());
+#   else
+            xtime xt;
+            xtime_get(&xt, TIME_UTC);
+            sleep(xt);
+#   endif
+        }
+    }
+
+    unsigned thread::hardware_concurrency()
+    {
+#if defined(PTW32_VERSION) || defined(__hpux)
+        return pthread_num_processors_np();
+#elif defined(__linux__)
+        return get_nprocs();
+#elif defined(__APPLE__) || defined(__FreeBSD__)
+        int count;
+        size_t size=sizeof(count);
+        return sysctlbyname("hw.ncpu",&count,&size,NULL,0)?0:count;
+#elif defined(BOOST_HAS_UNISTD_H) && defined(_SC_NPROCESSORS_ONLN)
+        int const count=sysconf(_SC_NPROCESSORS_ONLN);
+        return (count>0)?count:0;
+#else
+        return 0;
+#endif
+    }
+
+    thread::id thread::get_id() const
+    {
+        detail::thread_data_ptr const local_thread_info=get_thread_info();
+        if(local_thread_info)
+        {
+            return id(local_thread_info);
+        }
+        else
+        {
+            return id();
+        }
+    }
+
+    void thread::interrupt()
+    {
+        detail::thread_data_ptr const local_thread_info=get_thread_info();
+        if(local_thread_info)
+        {
+            lock_guard<mutex> lk(local_thread_info->data_mutex);
+            local_thread_info->interrupt_requested=true;
+            if(local_thread_info->current_cond)
+            {
+                BOOST_VERIFY(!pthread_cond_broadcast(local_thread_info->current_cond));
+            }
+        }
+    }
+
+    bool thread::interruption_requested() const
+    {
+        detail::thread_data_ptr const local_thread_info=get_thread_info();
+        if(local_thread_info)
+        {
+            lock_guard<mutex> lk(local_thread_info->data_mutex);
+            return local_thread_info->interrupt_requested;
+        }
+        else
+        {
+            return false;
+        }
+    }
+
+    thread::native_handle_type thread::native_handle()
+    {
+        detail::thread_data_ptr const local_thread_info=get_thread_info();
+        if(local_thread_info)
+        {
+            lock_guard<mutex> lk(local_thread_info->data_mutex);
+            return local_thread_info->thread_handle;
+        }
+        else
+        {
+            return pthread_t();
+        }
+    }
+    
+    
+
+    namespace this_thread
+    {
+        thread::id get_id()
+        {
+            boost::detail::thread_data_base* const thread_info=get_or_make_current_thread_data();
+            return thread::id(thread_info?thread_info->shared_from_this():detail::thread_data_ptr());
+        }
+
+        void interruption_point()
+        {
+            boost::detail::thread_data_base* const thread_info=detail::get_current_thread_data();
+            if(thread_info && thread_info->interrupt_enabled)
+            {
+                lock_guard<mutex> lg(thread_info->data_mutex);
+                if(thread_info->interrupt_requested)
+                {
+                    thread_info->interrupt_requested=false;
+                    throw thread_interrupted();
+                }
+            }
+        }
+        
+        bool interruption_enabled()
+        {
+            boost::detail::thread_data_base* const thread_info=detail::get_current_thread_data();
+            return thread_info && thread_info->interrupt_enabled;
+        }
+        
+        bool interruption_requested()
+        {
+            boost::detail::thread_data_base* const thread_info=detail::get_current_thread_data();
+            if(!thread_info)
+            {
+                return false;
+            }
+            else
+            {
+                lock_guard<mutex> lg(thread_info->data_mutex);
+                return thread_info->interrupt_requested;
+            }
+        }
+
+        disable_interruption::disable_interruption():
+            interruption_was_enabled(interruption_enabled())
+        {
+            if(interruption_was_enabled)
+            {
+                detail::get_current_thread_data()->interrupt_enabled=false;
+            }
+        }
+        
+        disable_interruption::~disable_interruption()
+        {
+            if(detail::get_current_thread_data())
+            {
+                detail::get_current_thread_data()->interrupt_enabled=interruption_was_enabled;
+            }
+        }
+
+        restore_interruption::restore_interruption(disable_interruption& d)
+        {
+            if(d.interruption_was_enabled)
+            {
+                detail::get_current_thread_data()->interrupt_enabled=true;
+            }
+        }
+        
+        restore_interruption::~restore_interruption()
+        {
+            if(detail::get_current_thread_data())
+            {
+                detail::get_current_thread_data()->interrupt_enabled=false;
+            }
+        }
+    }
+
+    namespace detail
+    {
+        void add_thread_exit_function(thread_exit_function_base* func)
+        {
+            detail::thread_data_base* const current_thread_data(get_or_make_current_thread_data());
+            thread_exit_callback_node* const new_node=
+                new thread_exit_callback_node(func,current_thread_data->thread_exit_callbacks);
+            current_thread_data->thread_exit_callbacks=new_node;
+        }
+
+        tss_data_node* find_tss_data(void const* key)
+        {
+            detail::thread_data_base* const current_thread_data(get_current_thread_data());
+            if(current_thread_data)
+            {
+                detail::tss_data_node* current_node=current_thread_data->tss_data;
+                while(current_node)
+                {
+                    if(current_node->key==key)
+                    {
+                        return current_node;
+                    }
+                    current_node=current_node->next;
+                }
+            }
+            return NULL;
+        }
+
+        void* get_tss_data(void const* key)
+        {
+            if(tss_data_node* const current_node=find_tss_data(key))
+            {
+                return current_node->value;
+            }
+            return NULL;
+        }
+        
+        void set_tss_data(void const* key,boost::shared_ptr<tss_cleanup_function> func,void* tss_data,bool cleanup_existing)
+        {
+            if(tss_data_node* const current_node=find_tss_data(key))
+            {
+                if(cleanup_existing && current_node->func)
+                {
+                    (*current_node->func)(current_node->value);
+                }
+                current_node->func=func;
+                current_node->value=tss_data;
+            }
+            else
+            {
+                detail::thread_data_base* const current_thread_data(get_or_make_current_thread_data());
+                tss_data_node* const new_node=new tss_data_node(key,func,tss_data,current_thread_data->tss_data);
+                current_thread_data->tss_data=new_node;
+            }
+        }
+    }
+
+//     thread_group::thread_group()
+//     {
+//     }
+
+//     thread_group::~thread_group()
+//     {
+//         // We shouldn't have to scoped_lock here, since referencing this object
+//         // from another thread while we're deleting it in the current thread is
+//         // going to lead to undefined behavior any way.
+//         for (std::list<thread*>::iterator it = m_threads.begin();
+//              it != m_threads.end(); ++it)
+//         {
+//             delete (*it);
+//         }
+//     }
+
+//     thread* thread_group::create_thread(const function0<void>& threadfunc)
+//     {
+//         // No scoped_lock required here since the only "shared data" that's
+//         // modified here occurs inside add_thread which does scoped_lock.
+//         std::auto_ptr<thread> thrd(new thread(threadfunc));
+//         add_thread(thrd.get());
+//         return thrd.release();
+//     }
+
+//     void thread_group::add_thread(thread* thrd)
+//     {
+//         mutex::scoped_lock scoped_lock(m_mutex);
+
+//         // For now we'll simply ignore requests to add a thread object multiple
+//         // times. Should we consider this an error and either throw or return an
+//         // error value?
+//         std::list<thread*>::iterator it = std::find(m_threads.begin(),
+//                                                     m_threads.end(), thrd);
+//         BOOST_ASSERT(it == m_threads.end());
+//         if (it == m_threads.end())
+//             m_threads.push_back(thrd);
+//     }
+
+//     void thread_group::remove_thread(thread* thrd)
+//     {
+//         mutex::scoped_lock scoped_lock(m_mutex);
+
+//         // For now we'll simply ignore requests to remove a thread object that's
+//         // not in the group. Should we consider this an error and either throw or
+//         // return an error value?
+//         std::list<thread*>::iterator it = std::find(m_threads.begin(),
+//                                                     m_threads.end(), thrd);
+//         BOOST_ASSERT(it != m_threads.end());
+//         if (it != m_threads.end())
+//             m_threads.erase(it);
+//     }
+
+//     void thread_group::join_all()
+//     {
+//         mutex::scoped_lock scoped_lock(m_mutex);
+//         for (std::list<thread*>::iterator it = m_threads.begin();
+//              it != m_threads.end(); ++it)
+//         {
+//             (*it)->join();
+//         }
+//     }
+
+//     void thread_group::interrupt_all()
+//     {
+//         boost::lock_guard<mutex> guard(m_mutex);
+            
+//         for(std::list<thread*>::iterator it=m_threads.begin(),end=m_threads.end();
+//             it!=end;
+//             ++it)
+//         {
+//             (*it)->interrupt();
+//         }
+//     }
+        
+
+//     size_t thread_group::size() const
+//     {
+//         return m_threads.size();
+//     }
+
+}
diff --git a/deal.II/contrib/boost/libs/thread/src/pthread/timeconv.inl b/deal.II/contrib/boost/libs/thread/src/pthread/timeconv.inl
new file mode 100644 (file)
index 0000000..5ec3b17
--- /dev/null
@@ -0,0 +1,130 @@
+// Copyright (C) 2001-2003
+// William E. Kempf
+//
+//  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)
+
+// boostinspect:nounnamed
+
+namespace {
+const int MILLISECONDS_PER_SECOND = 1000;
+const int NANOSECONDS_PER_SECOND = 1000000000;
+const int NANOSECONDS_PER_MILLISECOND = 1000000;
+
+const int MICROSECONDS_PER_SECOND = 1000000;
+const int NANOSECONDS_PER_MICROSECOND = 1000;
+
+inline void to_time(int milliseconds, boost::xtime& xt)
+{
+    int res = 0;
+    res = boost::xtime_get(&xt, boost::TIME_UTC);
+    assert(res == boost::TIME_UTC);
+
+    xt.sec += (milliseconds / MILLISECONDS_PER_SECOND);
+    xt.nsec += ((milliseconds % MILLISECONDS_PER_SECOND) *
+        NANOSECONDS_PER_MILLISECOND);
+
+    if (xt.nsec >= NANOSECONDS_PER_SECOND)
+    {
+        ++xt.sec;
+        xt.nsec -= NANOSECONDS_PER_SECOND;
+    }
+}
+
+#if defined(BOOST_HAS_PTHREADS)
+inline void to_timespec(const boost::xtime& xt, timespec& ts)
+{
+    ts.tv_sec = static_cast<int>(xt.sec);
+    ts.tv_nsec = static_cast<int>(xt.nsec);
+    if(ts.tv_nsec >= NANOSECONDS_PER_SECOND)
+    {
+        ts.tv_sec += ts.tv_nsec / NANOSECONDS_PER_SECOND;
+        ts.tv_nsec %= NANOSECONDS_PER_SECOND;
+    }
+}
+
+inline void to_time(int milliseconds, timespec& ts)
+{
+    boost::xtime xt;
+    to_time(milliseconds, xt);
+    to_timespec(xt, ts);
+}
+
+inline void to_timespec_duration(const boost::xtime& xt, timespec& ts)
+{
+    boost::xtime cur;
+    int res = 0;
+    res = boost::xtime_get(&cur, boost::TIME_UTC);
+    assert(res == boost::TIME_UTC);
+
+    if (boost::xtime_cmp(xt, cur) <= 0)
+    {
+        ts.tv_sec = 0;
+        ts.tv_nsec = 0;
+    }
+    else
+    {
+        ts.tv_sec = xt.sec - cur.sec;
+        ts.tv_nsec = xt.nsec - cur.nsec;
+
+        if( ts.tv_nsec < 0 )
+        {
+            ts.tv_sec -= 1;
+            ts.tv_nsec += NANOSECONDS_PER_SECOND;
+        }
+        if(ts.tv_nsec >= NANOSECONDS_PER_SECOND)
+        {
+            ts.tv_sec += ts.tv_nsec / NANOSECONDS_PER_SECOND;
+            ts.tv_nsec %= NANOSECONDS_PER_SECOND;
+        }
+    }
+}
+#endif
+
+inline void to_duration(boost::xtime xt, int& milliseconds)
+{
+    boost::xtime cur;
+    int res = 0;
+    res = boost::xtime_get(&cur, boost::TIME_UTC);
+    assert(res == boost::TIME_UTC);
+
+    if (boost::xtime_cmp(xt, cur) <= 0)
+        milliseconds = 0;
+    else
+    {
+        if (cur.nsec > xt.nsec)
+        {
+            xt.nsec += NANOSECONDS_PER_SECOND;
+            --xt.sec;
+        }
+        milliseconds = (int)((xt.sec - cur.sec) * MILLISECONDS_PER_SECOND) +
+            (((xt.nsec - cur.nsec) + (NANOSECONDS_PER_MILLISECOND/2)) /
+                NANOSECONDS_PER_MILLISECOND);
+    }
+}
+
+inline void to_microduration(boost::xtime xt, int& microseconds)
+{
+    boost::xtime cur;
+    int res = 0;
+    res = boost::xtime_get(&cur, boost::TIME_UTC);
+    assert(res == boost::TIME_UTC);
+
+    if (boost::xtime_cmp(xt, cur) <= 0)
+        microseconds = 0;
+    else
+    {
+        if (cur.nsec > xt.nsec)
+        {
+            xt.nsec += NANOSECONDS_PER_SECOND;
+            --xt.sec;
+        }
+        microseconds = (int)((xt.sec - cur.sec) * MICROSECONDS_PER_SECOND) +
+            (((xt.nsec - cur.nsec) + (NANOSECONDS_PER_MICROSECOND/2)) /
+                NANOSECONDS_PER_MICROSECOND);
+    }
+}
+}
+
+// Change Log:
+//    1 Jun 01  Initial creation.
diff --git a/deal.II/contrib/boost/libs/thread/src/tss_null.cpp b/deal.II/contrib/boost/libs/thread/src/tss_null.cpp
new file mode 100644 (file)
index 0000000..ff13b30
--- /dev/null
@@ -0,0 +1,34 @@
+// (C) Copyright Michael Glassford 2004.
+// (C) Copyright 2007 Anthony Williams
+// Use, modification and distribution are subject to 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/thread/detail/config.hpp>
+
+#if defined(BOOST_HAS_WINTHREADS) && (defined(BOOST_THREAD_BUILD_LIB) || defined(BOOST_THREAD_TEST) || defined(UNDER_CE)) && (!defined(_MSC_VER) || defined(UNDER_CE))
+
+    /*
+    This file is a "null" implementation of tss cleanup; it's
+    purpose is to to eliminate link errors in cases
+    where it is known that tss cleanup is not needed.
+    */
+
+    extern "C" void tss_cleanup_implemented(void)
+    {
+        /*
+        This function's sole purpose is to cause a link error in cases where
+        automatic tss cleanup is not implemented by Boost.Threads as a
+        reminder that user code is responsible for calling the necessary
+        functions at the appropriate times (and for implementing an a
+        tss_cleanup_implemented() function to eliminate the linker's
+        missing symbol error).
+
+        If Boost.Threads later implements automatic tss cleanup in cases
+        where it currently doesn't (which is the plan), the duplicate
+        symbol error will warn the user that their custom solution is no
+        longer needed and can be removed.
+        */
+    }
+
+#endif //defined(BOOST_HAS_WINTHREADS) && defined(BOOST_THREAD_BUILD_LIB) && !defined(_MSC_VER)
diff --git a/deal.II/contrib/boost/libs/thread/src/win32/exceptions.cpp b/deal.II/contrib/boost/libs/thread/src/win32/exceptions.cpp
new file mode 100644 (file)
index 0000000..8881303
--- /dev/null
@@ -0,0 +1,124 @@
+// Copyright (C) 2001-2003
+// William E. Kempf
+//
+//  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/thread/detail/config.hpp>
+
+#include <boost/thread/exceptions.hpp>
+#include <cstring>
+#include <string>
+
+namespace boost {
+
+thread_exception::thread_exception()
+    : m_sys_err(0)
+{
+}
+
+thread_exception::thread_exception(int sys_err_code)
+    : m_sys_err(sys_err_code)
+{
+}
+
+thread_exception::~thread_exception() throw()
+{
+}
+
+int thread_exception::native_error() const
+{
+    return m_sys_err; 
+}
+
+lock_error::lock_error()
+{
+}
+
+lock_error::lock_error(int sys_err_code)
+    : thread_exception(sys_err_code)
+{
+}
+
+lock_error::~lock_error() throw()
+{
+}
+
+const char* lock_error::what() const throw()
+{
+    return "boost::lock_error";
+}
+
+thread_resource_error::thread_resource_error()
+{
+}
+
+thread_resource_error::thread_resource_error(int sys_err_code)
+    : thread_exception(sys_err_code)
+{
+}
+
+thread_resource_error::~thread_resource_error() throw()
+{
+}
+
+const char* thread_resource_error::what() const throw()
+{
+    return "boost::thread_resource_error";
+}
+
+unsupported_thread_option::unsupported_thread_option()
+{
+}
+
+unsupported_thread_option::unsupported_thread_option(int sys_err_code)
+    : thread_exception(sys_err_code)
+{
+}
+
+unsupported_thread_option::~unsupported_thread_option() throw()
+{
+}
+
+const char* unsupported_thread_option::what() const throw()
+{
+    return "boost::unsupported_thread_option";
+}
+
+invalid_thread_argument::invalid_thread_argument()
+{
+}
+
+invalid_thread_argument::invalid_thread_argument(int sys_err_code)
+    : thread_exception(sys_err_code)
+{
+}
+
+invalid_thread_argument::~invalid_thread_argument() throw()
+{
+}
+
+const char* invalid_thread_argument::what() const throw()
+{
+    return "boost::invalid_thread_argument";
+}
+
+thread_permission_error::thread_permission_error()
+{
+}
+
+thread_permission_error::thread_permission_error(int sys_err_code)
+    : thread_exception(sys_err_code)
+{
+}
+
+thread_permission_error::~thread_permission_error() throw()
+{
+}
+
+const char* thread_permission_error::what() const throw()
+{
+    return "boost::thread_permission_error";
+}
+
+} // namespace boost
diff --git a/deal.II/contrib/boost/libs/thread/src/win32/thread.cpp b/deal.II/contrib/boost/libs/thread/src/win32/thread.cpp
new file mode 100644 (file)
index 0000000..9c4f82b
--- /dev/null
@@ -0,0 +1,595 @@
+// 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)
+// (C) Copyright 2007 Anthony Williams
+// (C) Copyright 2007 David Deakins
+
+#define _WIN32_WINNT 0x400
+#define WINVER 0x400
+
+#include <boost/thread/thread.hpp>
+#include <algorithm>
+#include <windows.h>
+#ifndef UNDER_CE
+#include <process.h>
+#endif
+#include <stdio.h>
+#include <boost/thread/once.hpp>
+#include <boost/thread/tss.hpp>
+#include <boost/assert.hpp>
+#include <boost/thread/detail/tss_hooks.hpp>
+#include <boost/date_time/posix_time/conversion.hpp>
+
+namespace boost
+{
+    namespace
+    {
+        boost::once_flag current_thread_tls_init_flag=BOOST_ONCE_INIT;
+        DWORD current_thread_tls_key=0;
+
+        void create_current_thread_tls_key()
+        {
+            tss_cleanup_implemented(); // if anyone uses TSS, we need the cleanup linked in
+            current_thread_tls_key=TlsAlloc();
+            BOOST_ASSERT(current_thread_tls_key!=TLS_OUT_OF_INDEXES);
+        }
+
+        void cleanup_tls_key()
+        {
+            if(current_thread_tls_key)
+            {
+                TlsFree(current_thread_tls_key);
+                current_thread_tls_key=0;
+            }
+        }
+
+        detail::thread_data_base* get_current_thread_data()
+        {
+            if(!current_thread_tls_key)
+            {
+                return 0;
+            }
+            return (detail::thread_data_base*)TlsGetValue(current_thread_tls_key);
+        }
+
+        void set_current_thread_data(detail::thread_data_base* new_data)
+        {
+            boost::call_once(current_thread_tls_init_flag,create_current_thread_tls_key);
+            BOOST_VERIFY(TlsSetValue(current_thread_tls_key,new_data));
+        }
+
+#ifdef BOOST_NO_THREADEX
+// Windows CE doesn't define _beginthreadex
+
+        struct ThreadProxyData
+        {
+            typedef unsigned (__stdcall* func)(void*);
+            func start_address_;
+            void* arglist_;
+            ThreadProxyData(func start_address,void* arglist) : start_address_(start_address), arglist_(arglist) {}
+        };
+
+        DWORD WINAPI ThreadProxy(LPVOID args)
+        {
+            ThreadProxyData* data=reinterpret_cast<ThreadProxyData*>(args);
+            DWORD ret=data->start_address_(data->arglist_);
+            delete data;
+            return ret;
+        }
+        
+        typedef void* uintptr_t;
+
+        inline uintptr_t const _beginthreadex(void* security, unsigned stack_size, unsigned (__stdcall* start_address)(void*),
+                                              void* arglist, unsigned initflag, unsigned* thrdaddr)
+        {
+            DWORD threadID;
+            HANDLE hthread=CreateThread(static_cast<LPSECURITY_ATTRIBUTES>(security),stack_size,ThreadProxy,
+                                        new ThreadProxyData(start_address,arglist),initflag,&threadID);
+            if (hthread!=0)
+                *thrdaddr=threadID;
+            return reinterpret_cast<uintptr_t const>(hthread);
+        }
+
+#endif
+
+    }
+
+    namespace detail
+    {
+        struct thread_exit_callback_node
+        {
+            boost::detail::thread_exit_function_base* func;
+            thread_exit_callback_node* next;
+
+            thread_exit_callback_node(boost::detail::thread_exit_function_base* func_,
+                                      thread_exit_callback_node* next_):
+                func(func_),next(next_)
+            {}
+        };
+
+        struct tss_data_node
+        {
+            void const* key;
+            boost::shared_ptr<boost::detail::tss_cleanup_function> func;
+            void* value;
+            tss_data_node* next;
+
+            tss_data_node(void const* key_,boost::shared_ptr<boost::detail::tss_cleanup_function> func_,void* value_,
+                          tss_data_node* next_):
+                key(key_),func(func_),value(value_),next(next_)
+            {}
+        };
+
+    }
+
+    namespace
+    {
+        void run_thread_exit_callbacks()
+        {
+            detail::thread_data_ptr current_thread_data(get_current_thread_data(),false);
+            if(current_thread_data)
+            {
+                while(current_thread_data->tss_data || current_thread_data->thread_exit_callbacks)
+                {
+                    while(current_thread_data->thread_exit_callbacks)
+                    {
+                        detail::thread_exit_callback_node* const current_node=current_thread_data->thread_exit_callbacks;
+                        current_thread_data->thread_exit_callbacks=current_node->next;
+                        if(current_node->func)
+                        {
+                            (*current_node->func)();
+                            boost::detail::heap_delete(current_node->func);
+                        }
+                        boost::detail::heap_delete(current_node);
+                    }
+                    while(current_thread_data->tss_data)
+                    {
+                        detail::tss_data_node* const current_node=current_thread_data->tss_data;
+                        current_thread_data->tss_data=current_node->next;
+                        if(current_node->func)
+                        {
+                            (*current_node->func)(current_node->value);
+                        }
+                        boost::detail::heap_delete(current_node);
+                    }
+                }
+                
+                set_current_thread_data(0);
+            }
+        }
+        
+        unsigned __stdcall thread_start_function(void* param)
+        {
+            detail::thread_data_base* const thread_info(reinterpret_cast<detail::thread_data_base*>(param));
+            set_current_thread_data(thread_info);
+            try
+            {
+                thread_info->run();
+            }
+            catch(thread_interrupted const&)
+            {
+            }
+            catch(...)
+            {
+                std::terminate();
+            }
+            run_thread_exit_callbacks();
+            return 0;
+        }
+    }
+
+    thread::thread()
+    {}
+
+    void thread::start_thread()
+    {
+        uintptr_t const new_thread=_beginthreadex(0,0,&thread_start_function,thread_info.get(),CREATE_SUSPENDED,&thread_info->id);
+        if(!new_thread)
+        {
+            throw thread_resource_error();
+        }
+        intrusive_ptr_add_ref(thread_info.get());
+        thread_info->thread_handle=(detail::win32::handle)(new_thread);
+        ResumeThread(thread_info->thread_handle);
+    }
+
+    thread::thread(detail::thread_data_ptr data):
+        thread_info(data)
+    {}
+
+    namespace
+    {
+        struct externally_launched_thread:
+            detail::thread_data_base
+        {
+            externally_launched_thread()
+            {
+                ++count;
+                interruption_enabled=false;
+            }
+            
+            void run()
+            {}
+        private:
+            externally_launched_thread(externally_launched_thread&);
+            void operator=(externally_launched_thread&);
+        };
+
+        void make_external_thread_data()
+        {
+            externally_launched_thread* me=detail::heap_new<externally_launched_thread>();
+            set_current_thread_data(me);
+        }
+
+        detail::thread_data_base* get_or_make_current_thread_data()
+        {
+            detail::thread_data_base* current_thread_data(get_current_thread_data());
+            if(!current_thread_data)
+            {
+                make_external_thread_data();
+                current_thread_data=get_current_thread_data();
+            }
+            return current_thread_data;
+        }
+        
+    }
+
+    thread::~thread()
+    {
+        detach();
+    }
+    
+    thread::id thread::get_id() const
+    {
+        return thread::id(get_thread_info());
+    }
+
+    bool thread::joinable() const
+    {
+        return get_thread_info();
+    }
+
+    void thread::join()
+    {
+        detail::thread_data_ptr local_thread_info=get_thread_info();
+        if(local_thread_info)
+        {
+            this_thread::interruptible_wait(local_thread_info->thread_handle,detail::timeout::sentinel());
+            release_handle();
+        }
+    }
+
+    bool thread::timed_join(boost::system_time const& wait_until)
+    {
+        detail::thread_data_ptr local_thread_info=get_thread_info();
+        if(local_thread_info)
+        {
+            if(!this_thread::interruptible_wait(local_thread_info->thread_handle,get_milliseconds_until(wait_until)))
+            {
+                return false;
+            }
+            release_handle();
+        }
+        return true;
+    }
+    
+    void thread::detach()
+    {
+        release_handle();
+    }
+
+    void thread::release_handle()
+    {
+        lock_guard<mutex> l1(thread_info_mutex);
+        thread_info=0;
+    }
+    
+    void thread::interrupt()
+    {
+        detail::thread_data_ptr local_thread_info=get_thread_info();
+        if(local_thread_info)
+        {
+            local_thread_info->interrupt();
+        }
+    }
+    
+    bool thread::interruption_requested() const
+    {
+        detail::thread_data_ptr local_thread_info=get_thread_info();
+        return local_thread_info.get() && (detail::win32::WaitForSingleObject(local_thread_info->interruption_handle,0)==0);
+    }
+    
+    unsigned thread::hardware_concurrency()
+    {
+        SYSTEM_INFO info={0};
+        GetSystemInfo(&info);
+        return info.dwNumberOfProcessors;
+    }
+    
+    thread::native_handle_type thread::native_handle()
+    {
+        detail::thread_data_ptr local_thread_info=get_thread_info();
+        return local_thread_info?(detail::win32::handle)local_thread_info->thread_handle:detail::win32::invalid_handle_value;
+    }
+
+    detail::thread_data_ptr thread::get_thread_info() const
+    {
+        boost::mutex::scoped_lock l(thread_info_mutex);
+        return thread_info;
+    }
+
+    namespace this_thread
+    {
+        namespace
+        {
+            LARGE_INTEGER get_due_time(detail::timeout const&  target_time)
+            {
+                LARGE_INTEGER due_time={0};
+                if(target_time.relative)
+                {
+                    unsigned long const elapsed_milliseconds=GetTickCount()-target_time.start;
+                    LONGLONG const remaining_milliseconds=(target_time.milliseconds-elapsed_milliseconds);
+                    LONGLONG const hundred_nanoseconds_in_one_millisecond=10000;
+
+                    if(remaining_milliseconds>0)
+                    {
+                        due_time.QuadPart=-(remaining_milliseconds*hundred_nanoseconds_in_one_millisecond);
+                    }
+                }
+                else
+                {
+                    SYSTEMTIME target_system_time={0};
+                    target_system_time.wYear=target_time.abs_time.date().year();
+                    target_system_time.wMonth=target_time.abs_time.date().month();
+                    target_system_time.wDay=target_time.abs_time.date().day();
+                    target_system_time.wHour=(WORD)target_time.abs_time.time_of_day().hours();
+                    target_system_time.wMinute=(WORD)target_time.abs_time.time_of_day().minutes();
+                    target_system_time.wSecond=(WORD)target_time.abs_time.time_of_day().seconds();
+
+                    if(!SystemTimeToFileTime(&target_system_time,((FILETIME*)&due_time)))
+                    {
+                        due_time.QuadPart=0;
+                    }
+                    else
+                    {
+                        long const hundred_nanoseconds_in_one_second=10000000;
+                        due_time.QuadPart+=target_time.abs_time.time_of_day().fractional_seconds()*(hundred_nanoseconds_in_one_second/target_time.abs_time.time_of_day().ticks_per_second());
+                    }
+                }
+                return due_time;
+            }
+        }
+        
+
+        bool interruptible_wait(detail::win32::handle handle_to_wait_for,detail::timeout target_time)
+        {
+            detail::win32::handle handles[3]={0};
+            unsigned handle_count=0;
+            unsigned wait_handle_index=~0U;
+            unsigned interruption_index=~0U;
+            unsigned timeout_index=~0U;
+            if(handle_to_wait_for!=detail::win32::invalid_handle_value)
+            {
+                wait_handle_index=handle_count;
+                handles[handle_count++]=handle_to_wait_for;
+            }
+            if(get_current_thread_data() && get_current_thread_data()->interruption_enabled)
+            {
+                interruption_index=handle_count;
+                handles[handle_count++]=get_current_thread_data()->interruption_handle;
+            }
+
+            detail::win32::handle_manager timer_handle;
+            
+#ifndef UNDER_CE
+            unsigned const min_timer_wait_period=20;
+            
+            if(!target_time.is_sentinel())
+            {
+                detail::timeout::remaining_time const time_left=target_time.remaining_milliseconds();
+                if(time_left.milliseconds > min_timer_wait_period)
+                {
+                    // for a long-enough timeout, use a waitable timer (which tracks clock changes)
+                    timer_handle=CreateWaitableTimer(NULL,false,NULL);
+                    if(timer_handle!=0)
+                    {
+                        LARGE_INTEGER due_time=get_due_time(target_time);
+                        
+                        bool const set_time_succeeded=SetWaitableTimer(timer_handle,&due_time,0,0,0,false)!=0;
+                        if(set_time_succeeded)
+                        {
+                            timeout_index=handle_count;
+                            handles[handle_count++]=timer_handle;
+                        }
+                    }
+                }
+                else if(!target_time.relative)
+                {
+                    // convert short absolute-time timeouts into relative ones, so we don't race against clock changes
+                    target_time=detail::timeout(time_left.milliseconds);
+                }
+            }
+#endif
+        
+            bool const using_timer=timeout_index!=~0u;
+            detail::timeout::remaining_time time_left(0);
+            
+            do
+            {
+                if(!using_timer)
+                {
+                    time_left=target_time.remaining_milliseconds();
+                }
+                
+                if(handle_count)
+                {
+                    unsigned long const notified_index=detail::win32::WaitForMultipleObjects(handle_count,handles,false,using_timer?INFINITE:time_left.milliseconds);
+                    if(notified_index<handle_count)
+                    {
+                        if(notified_index==wait_handle_index)
+                        {
+                            return true;
+                        }
+                        else if(notified_index==interruption_index)
+                        {
+                            detail::win32::ResetEvent(get_current_thread_data()->interruption_handle);
+                            throw thread_interrupted();
+                        }
+                        else if(notified_index==timeout_index)
+                        {
+                            return false;
+                        }
+                    }
+                }
+                else
+                {
+                    detail::win32::Sleep(time_left.milliseconds);
+                }
+                if(target_time.relative)
+                {
+                    target_time.milliseconds-=detail::timeout::max_non_infinite_wait;
+                }
+            }
+            while(time_left.more);
+            return false;
+        }
+
+        thread::id get_id()
+        {
+            return thread::id(get_or_make_current_thread_data());
+        }
+
+        void interruption_point()
+        {
+            if(interruption_enabled() && interruption_requested())
+            {
+                detail::win32::ResetEvent(get_current_thread_data()->interruption_handle);
+                throw thread_interrupted();
+            }
+        }
+        
+        bool interruption_enabled()
+        {
+            return get_current_thread_data() && get_current_thread_data()->interruption_enabled;
+        }
+        
+        bool interruption_requested()
+        {
+            return get_current_thread_data() && (detail::win32::WaitForSingleObject(get_current_thread_data()->interruption_handle,0)==0);
+        }
+
+        void yield()
+        {
+            detail::win32::Sleep(0);
+        }
+        
+        disable_interruption::disable_interruption():
+            interruption_was_enabled(interruption_enabled())
+        {
+            if(interruption_was_enabled)
+            {
+                get_current_thread_data()->interruption_enabled=false;
+            }
+        }
+        
+        disable_interruption::~disable_interruption()
+        {
+            if(get_current_thread_data())
+            {
+                get_current_thread_data()->interruption_enabled=interruption_was_enabled;
+            }
+        }
+
+        restore_interruption::restore_interruption(disable_interruption& d)
+        {
+            if(d.interruption_was_enabled)
+            {
+                get_current_thread_data()->interruption_enabled=true;
+            }
+        }
+        
+        restore_interruption::~restore_interruption()
+        {
+            if(get_current_thread_data())
+            {
+                get_current_thread_data()->interruption_enabled=false;
+            }
+        }
+    }
+
+    namespace detail
+    {
+        void add_thread_exit_function(thread_exit_function_base* func)
+        {
+            detail::thread_data_base* const current_thread_data(get_or_make_current_thread_data());
+            thread_exit_callback_node* const new_node=
+                heap_new<thread_exit_callback_node>(func,
+                                                    current_thread_data->thread_exit_callbacks);
+            current_thread_data->thread_exit_callbacks=new_node;
+        }
+
+        tss_data_node* find_tss_data(void const* key)
+        {
+            detail::thread_data_base* const current_thread_data(get_current_thread_data());
+            if(current_thread_data)
+            {
+                detail::tss_data_node* current_node=current_thread_data->tss_data;
+                while(current_node)
+                {
+                    if(current_node->key==key)
+                    {
+                        return current_node;
+                    }
+                    current_node=current_node->next;
+                }
+            }
+            return NULL;
+        }
+
+        void* get_tss_data(void const* key)
+        {
+            if(tss_data_node* const current_node=find_tss_data(key))
+            {
+                return current_node->value;
+            }
+            return NULL;
+        }
+        
+        void set_tss_data(void const* key,boost::shared_ptr<tss_cleanup_function> func,void* tss_data,bool cleanup_existing)
+        {
+            if(tss_data_node* const current_node=find_tss_data(key))
+            {
+                if(cleanup_existing && current_node->func.get())
+                {
+                    (*current_node->func)(current_node->value);
+                }
+                current_node->func=func;
+                current_node->value=tss_data;
+            }
+            else
+            {
+                detail::thread_data_base* const current_thread_data(get_or_make_current_thread_data());
+                tss_data_node* const new_node=heap_new<tss_data_node>(key,func,tss_data,current_thread_data->tss_data);
+                current_thread_data->tss_data=new_node;
+            }
+        }
+    }
+}
+
+
+extern "C" BOOST_THREAD_DECL void on_process_enter()
+{}
+
+extern "C" BOOST_THREAD_DECL void on_thread_enter()
+{}
+
+extern "C" BOOST_THREAD_DECL void on_process_exit()
+{
+    boost::cleanup_tls_key();
+}
+
+extern "C" BOOST_THREAD_DECL void on_thread_exit()
+{
+    boost::run_thread_exit_callbacks();
+}
+
diff --git a/deal.II/contrib/boost/libs/thread/src/win32/timeconv.inl b/deal.II/contrib/boost/libs/thread/src/win32/timeconv.inl
new file mode 100644 (file)
index 0000000..5ec3b17
--- /dev/null
@@ -0,0 +1,130 @@
+// Copyright (C) 2001-2003
+// William E. Kempf
+//
+//  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)
+
+// boostinspect:nounnamed
+
+namespace {
+const int MILLISECONDS_PER_SECOND = 1000;
+const int NANOSECONDS_PER_SECOND = 1000000000;
+const int NANOSECONDS_PER_MILLISECOND = 1000000;
+
+const int MICROSECONDS_PER_SECOND = 1000000;
+const int NANOSECONDS_PER_MICROSECOND = 1000;
+
+inline void to_time(int milliseconds, boost::xtime& xt)
+{
+    int res = 0;
+    res = boost::xtime_get(&xt, boost::TIME_UTC);
+    assert(res == boost::TIME_UTC);
+
+    xt.sec += (milliseconds / MILLISECONDS_PER_SECOND);
+    xt.nsec += ((milliseconds % MILLISECONDS_PER_SECOND) *
+        NANOSECONDS_PER_MILLISECOND);
+
+    if (xt.nsec >= NANOSECONDS_PER_SECOND)
+    {
+        ++xt.sec;
+        xt.nsec -= NANOSECONDS_PER_SECOND;
+    }
+}
+
+#if defined(BOOST_HAS_PTHREADS)
+inline void to_timespec(const boost::xtime& xt, timespec& ts)
+{
+    ts.tv_sec = static_cast<int>(xt.sec);
+    ts.tv_nsec = static_cast<int>(xt.nsec);
+    if(ts.tv_nsec >= NANOSECONDS_PER_SECOND)
+    {
+        ts.tv_sec += ts.tv_nsec / NANOSECONDS_PER_SECOND;
+        ts.tv_nsec %= NANOSECONDS_PER_SECOND;
+    }
+}
+
+inline void to_time(int milliseconds, timespec& ts)
+{
+    boost::xtime xt;
+    to_time(milliseconds, xt);
+    to_timespec(xt, ts);
+}
+
+inline void to_timespec_duration(const boost::xtime& xt, timespec& ts)
+{
+    boost::xtime cur;
+    int res = 0;
+    res = boost::xtime_get(&cur, boost::TIME_UTC);
+    assert(res == boost::TIME_UTC);
+
+    if (boost::xtime_cmp(xt, cur) <= 0)
+    {
+        ts.tv_sec = 0;
+        ts.tv_nsec = 0;
+    }
+    else
+    {
+        ts.tv_sec = xt.sec - cur.sec;
+        ts.tv_nsec = xt.nsec - cur.nsec;
+
+        if( ts.tv_nsec < 0 )
+        {
+            ts.tv_sec -= 1;
+            ts.tv_nsec += NANOSECONDS_PER_SECOND;
+        }
+        if(ts.tv_nsec >= NANOSECONDS_PER_SECOND)
+        {
+            ts.tv_sec += ts.tv_nsec / NANOSECONDS_PER_SECOND;
+            ts.tv_nsec %= NANOSECONDS_PER_SECOND;
+        }
+    }
+}
+#endif
+
+inline void to_duration(boost::xtime xt, int& milliseconds)
+{
+    boost::xtime cur;
+    int res = 0;
+    res = boost::xtime_get(&cur, boost::TIME_UTC);
+    assert(res == boost::TIME_UTC);
+
+    if (boost::xtime_cmp(xt, cur) <= 0)
+        milliseconds = 0;
+    else
+    {
+        if (cur.nsec > xt.nsec)
+        {
+            xt.nsec += NANOSECONDS_PER_SECOND;
+            --xt.sec;
+        }
+        milliseconds = (int)((xt.sec - cur.sec) * MILLISECONDS_PER_SECOND) +
+            (((xt.nsec - cur.nsec) + (NANOSECONDS_PER_MILLISECOND/2)) /
+                NANOSECONDS_PER_MILLISECOND);
+    }
+}
+
+inline void to_microduration(boost::xtime xt, int& microseconds)
+{
+    boost::xtime cur;
+    int res = 0;
+    res = boost::xtime_get(&cur, boost::TIME_UTC);
+    assert(res == boost::TIME_UTC);
+
+    if (boost::xtime_cmp(xt, cur) <= 0)
+        microseconds = 0;
+    else
+    {
+        if (cur.nsec > xt.nsec)
+        {
+            xt.nsec += NANOSECONDS_PER_SECOND;
+            --xt.sec;
+        }
+        microseconds = (int)((xt.sec - cur.sec) * MICROSECONDS_PER_SECOND) +
+            (((xt.nsec - cur.nsec) + (NANOSECONDS_PER_MICROSECOND/2)) /
+                NANOSECONDS_PER_MICROSECOND);
+    }
+}
+}
+
+// Change Log:
+//    1 Jun 01  Initial creation.
diff --git a/deal.II/contrib/boost/libs/thread/src/win32/tss_dll.cpp b/deal.II/contrib/boost/libs/thread/src/win32/tss_dll.cpp
new file mode 100644 (file)
index 0000000..0522a12
--- /dev/null
@@ -0,0 +1,72 @@
+// (C) Copyright Michael Glassford 2004.
+// Use, modification and distribution are subject to 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/thread/detail/config.hpp>
+
+#if defined(BOOST_HAS_WINTHREADS) && defined(BOOST_THREAD_BUILD_DLL)
+
+    #include <boost/thread/detail/tss_hooks.hpp>
+
+    #define WIN32_LEAN_AND_MEAN
+    #include <windows.h>
+
+    #if defined(__BORLANDC__)
+        extern "C" BOOL WINAPI DllEntryPoint(HINSTANCE /*hInstance*/, DWORD dwReason, LPVOID /*lpReserved*/)
+    #elif defined(_WIN32_WCE)
+        extern "C" BOOL WINAPI DllMain(HANDLE /*hInstance*/, DWORD dwReason, LPVOID /*lpReserved*/)
+    #else
+        extern "C" BOOL WINAPI DllMain(HINSTANCE /*hInstance*/, DWORD dwReason, LPVOID /*lpReserved*/)
+    #endif
+    {
+        switch(dwReason)
+        {
+            case DLL_PROCESS_ATTACH:
+            {
+                on_process_enter();
+                on_thread_enter();
+                break;
+            }
+
+            case DLL_THREAD_ATTACH:
+            {
+                on_thread_enter();
+                break;
+            }
+
+            case DLL_THREAD_DETACH:
+            {
+                on_thread_exit();
+                break;
+            }
+
+            case DLL_PROCESS_DETACH:
+            {
+                on_thread_exit();
+                on_process_exit();
+                break;
+            }
+        }
+
+        return TRUE;
+    }
+
+    extern "C" void tss_cleanup_implemented(void)
+    {
+        /*
+        This function's sole purpose is to cause a link error in cases where
+        automatic tss cleanup is not implemented by Boost.Threads as a
+        reminder that user code is responsible for calling the necessary
+        functions at the appropriate times (and for implementing an a
+        tss_cleanup_implemented() function to eliminate the linker's
+        missing symbol error).
+
+        If Boost.Threads later implements automatic tss cleanup in cases
+        where it currently doesn't (which is the plan), the duplicate
+        symbol error will warn the user that their custom solution is no
+        longer needed and can be removed.
+        */
+    }
+
+#endif //defined(BOOST_HAS_WINTHREADS) && defined(BOOST_THREAD_BUILD_DLL)
diff --git a/deal.II/contrib/boost/libs/thread/src/win32/tss_pe.cpp b/deal.II/contrib/boost/libs/thread/src/win32/tss_pe.cpp
new file mode 100644 (file)
index 0000000..ae89bc4
--- /dev/null
@@ -0,0 +1,287 @@
+// $Id: tss_pe.cpp 49324 2008-10-13 20:30:13Z anthonyw $
+// (C) Copyright Aaron W. LaFramboise, Roland Schwarz, Michael Glassford 2004.
+// (C) Copyright 2007 Roland Schwarz
+// (C) Copyright 2007 Anthony Williams
+// (C) Copyright 2007 David Deakins
+// Use, modification and distribution are subject to 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/thread/detail/config.hpp>
+
+#if defined(BOOST_HAS_WINTHREADS) && defined(BOOST_THREAD_BUILD_LIB) 
+
+#if defined(__MINGW32__) && !defined(_WIN64)
+
+#include <boost/thread/detail/tss_hooks.hpp>
+
+#include <windows.h>
+
+#include <cstdlib>
+
+extern "C" void tss_cleanup_implemented(void) {}
+
+namespace {
+    void NTAPI on_tls_callback(void* h, DWORD dwReason, PVOID pv)
+    {
+        switch (dwReason)
+        {
+        case DLL_THREAD_DETACH:
+        {
+            on_thread_exit();
+            break;
+        }
+        }
+    }
+
+    void on_after_ctors(void)
+    {
+        on_process_enter();
+    }
+    
+    void on_before_dtors(void)
+    {
+        on_thread_exit();
+    }
+    
+    void on_after_dtors(void)
+    {
+        on_process_exit();        
+    }
+}
+
+extern "C" {
+
+    void (* after_ctors )(void) __attribute__((section(".ctors")))     = on_after_ctors;
+    void (* before_dtors)(void) __attribute__((section(".dtors")))     = on_before_dtors;
+    void (* after_dtors )(void) __attribute__((section(".dtors.zzz"))) = on_after_dtors;
+
+    ULONG __tls_index__ = 0;
+    char __tls_end__ __attribute__((section(".tls$zzz"))) = 0;
+    char __tls_start__ __attribute__((section(".tls"))) = 0;
+
+
+    PIMAGE_TLS_CALLBACK __crt_xl_start__ __attribute__ ((section(".CRT$XLA"))) = 0;
+    PIMAGE_TLS_CALLBACK __crt_xl_tls_callback__ __attribute__ ((section(".CRT$XLB"))) = on_tls_callback;
+    PIMAGE_TLS_CALLBACK __crt_xl_end__ __attribute__ ((section(".CRT$XLZ"))) = 0;
+}
+
+extern "C" const IMAGE_TLS_DIRECTORY32 _tls_used __attribute__ ((section(".rdata$T"))) =
+{
+        (DWORD) &__tls_start__,
+        (DWORD) &__tls_end__,
+        (DWORD) &__tls_index__,
+        (DWORD) (&__crt_xl_start__+1),
+        (DWORD) 0,
+        (DWORD) 0
+};
+
+
+#elif  defined(_MSC_VER) && !defined(UNDER_CE)
+
+    #include <boost/thread/detail/tss_hooks.hpp>
+
+    #include <stdlib.h>
+
+    #define WIN32_LEAN_AND_MEAN
+    #include <windows.h>
+
+    //Definitions required by implementation
+
+    #if (_MSC_VER < 1300) // 1300 == VC++ 7.0
+        typedef void (__cdecl *_PVFV)(void);
+        #define INIRETSUCCESS
+        #define PVAPI void
+    #else
+        typedef int (__cdecl *_PVFV)(void);
+        #define INIRETSUCCESS 0
+        #define PVAPI int
+    #endif
+
+    typedef void (NTAPI* _TLSCB)(HINSTANCE, DWORD, PVOID);
+
+    //Symbols for connection to the runtime environment
+
+    extern "C"
+    {
+        extern DWORD _tls_used; //the tls directory (located in .rdata segment)
+        extern _TLSCB __xl_a[], __xl_z[];    //tls initializers */
+    }
+
+    namespace
+    {
+        //Forward declarations
+
+        static PVAPI on_tls_prepare(void);
+        static PVAPI on_process_init(void);
+        static PVAPI on_process_term(void);
+        static void NTAPI on_tls_callback(HINSTANCE, DWORD, PVOID);
+
+        //The .CRT$Xxx information is taken from Codeguru:
+        //http://www.codeguru.com/Cpp/misc/misc/threadsprocesses/article.php/c6945__2/
+
+#if (_MSC_VER >= 1400)
+#pragma section(".CRT$XIU",long,read)
+#pragma section(".CRT$XCU",long,read)
+#pragma section(".CRT$XTU",long,read)
+#pragma section(".CRT$XLC",long,read)
+        __declspec(allocate(".CRT$XLC")) _TLSCB __xl_ca=on_tls_callback;
+        __declspec(allocate(".CRT$XIU"))_PVFV p_tls_prepare = on_tls_prepare;
+        __declspec(allocate(".CRT$XCU"))_PVFV p_process_init = on_process_init;
+        __declspec(allocate(".CRT$XTU"))_PVFV p_process_term = on_process_term;
+#else
+        #if (_MSC_VER >= 1300) // 1300 == VC++ 7.0
+        #   pragma data_seg(push, old_seg)
+        #endif
+            //Callback to run tls glue code first.
+            //I don't think it is necessary to run it
+            //at .CRT$XIB level, since we are only
+            //interested in thread detachement. But
+            //this could be changed easily if required.
+
+            #pragma data_seg(".CRT$XIU")
+            static _PVFV p_tls_prepare = on_tls_prepare;
+            #pragma data_seg()
+
+            //Callback after all global ctors.
+
+            #pragma data_seg(".CRT$XCU")
+            static _PVFV p_process_init = on_process_init;
+            #pragma data_seg()
+
+            //Callback for tls notifications.
+
+            #pragma data_seg(".CRT$XLB")
+            _TLSCB p_thread_callback = on_tls_callback;
+            #pragma data_seg()
+            //Callback for termination.
+
+            #pragma data_seg(".CRT$XTU")
+            static _PVFV p_process_term = on_process_term;
+            #pragma data_seg()
+        #if (_MSC_VER >= 1300) // 1300 == VC++ 7.0
+        #   pragma data_seg(pop, old_seg)
+        #endif
+#endif
+
+#ifdef BOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable:4189)
+#endif
+
+        PVAPI on_tls_prepare(void)
+        {
+            //The following line has an important side effect:
+            //if the TLS directory is not already there, it will
+            //be created by the linker. In other words, it forces a tls
+            //directory to be generated by the linker even when static tls
+            //(i.e. __declspec(thread)) is not used.
+            //The volatile should prevent the optimizer
+            //from removing the reference.
+
+            DWORD volatile dw = _tls_used;
+
+            #if (_MSC_VER < 1300) // 1300 == VC++ 7.0
+                _TLSCB* pfbegin = __xl_a;
+                _TLSCB* pfend = __xl_z;
+                _TLSCB* pfdst = pfbegin;
+                //pfdst = (_TLSCB*)_tls_used.AddressOfCallBacks;
+
+                //The following loop will merge the address pointers
+                //into a contiguous area, since the tlssup code seems
+                //to require this (at least on MSVC 6)
+
+                while (pfbegin < pfend)
+                {
+                    if (*pfbegin != 0)
+                    {
+                        *pfdst = *pfbegin;
+                        ++pfdst;
+                    }
+                    ++pfbegin;
+                }
+
+                *pfdst = 0;
+            #endif
+
+            return INIRETSUCCESS;
+        }
+#ifdef BOOST_MSVC
+#pragma warning(pop)
+#endif
+
+        PVAPI on_process_init(void)
+        {
+            //Schedule on_thread_exit() to be called for the main
+            //thread before destructors of global objects have been
+            //called.
+
+            //It will not be run when 'quick' exiting the
+            //library; however, this is the standard behaviour
+            //for destructors of global objects, so that
+            //shouldn't be a problem.
+
+            atexit(on_thread_exit);
+
+            //Call Boost process entry callback here
+
+            on_process_enter();
+
+            return INIRETSUCCESS;
+        }
+
+        PVAPI on_process_term(void)
+        {
+            on_process_exit();
+            return INIRETSUCCESS;
+        }
+
+        void NTAPI on_tls_callback(HINSTANCE /*h*/, DWORD dwReason, PVOID /*pv*/)
+        {
+            switch (dwReason)
+            {
+            case DLL_THREAD_DETACH:
+                on_thread_exit();
+                break;
+            }
+        }
+
+        BOOL WINAPI dll_callback(HANDLE, DWORD dwReason, LPVOID)
+        {
+            switch (dwReason)
+            {
+            case DLL_THREAD_DETACH:
+                on_thread_exit();
+                break;
+            case DLL_PROCESS_DETACH:
+                on_process_exit();
+                break;
+            }
+            return true;
+        }
+    } //namespace
+
+extern "C"
+{
+    extern BOOL (WINAPI * const _pRawDllMain)(HANDLE, DWORD, LPVOID)=&dll_callback;
+}
+
+    extern "C" void tss_cleanup_implemented(void)
+    {
+        /*
+        This function's sole purpose is to cause a link error in cases where
+        automatic tss cleanup is not implemented by Boost.Threads as a
+        reminder that user code is responsible for calling the necessary
+        functions at the appropriate times (and for implementing an a
+        tss_cleanup_implemented() function to eliminate the linker's
+        missing symbol error).
+
+        If Boost.Threads later implements automatic tss cleanup in cases
+        where it currently doesn't (which is the plan), the duplicate
+        symbol error will warn the user that their custom solution is no
+        longer needed and can be removed.
+        */
+    }
+#endif //defined(_MSC_VER) && !defined(UNDER_CE)
+
+#endif //defined(BOOST_HAS_WINTHREADS) && defined(BOOST_THREAD_BUILD_LIB)
diff --git a/deal.II/contrib/boost/libs/thread/test/Carbon.r b/deal.II/contrib/boost/libs/thread/test/Carbon.r
new file mode 100644 (file)
index 0000000..e0ac5b4
--- /dev/null
@@ -0,0 +1,18 @@
+/*
+ *  Permit this Carbon application to launch on OS X
+ *
+ *  Â© 1997-2000 Metrowerks Corp.
+ *
+ *  Questions and comments to:
+ *       <mailto:support@metrowerks.com>
+ *       <http://www.metrowerks.com/>
+ */
+
+
+/*----------------------------carb Â¥ Carbon on OS X launch information --------------------------*/
+type 'carb' {
+};
+
+
+resource 'carb'(0) {
+};
diff --git a/deal.II/contrib/boost/libs/thread/test/Jamfile.v2 b/deal.II/contrib/boost/libs/thread/test/Jamfile.v2
new file mode 100644 (file)
index 0000000..a6a769c
--- /dev/null
@@ -0,0 +1,61 @@
+#  (C) Copyright William E. Kempf 2001. 
+#  (C) Copyright 2007 Anthony Williams. 
+#  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)
+#
+# Boost.Threads test Jamfile
+#
+# Additional configuration variables used:
+#   1. PTW32 may be used on Win32 platforms to specify that the pthreads-win32
+#      library should be used instead of "native" threads. This feature is
+#      mostly used for testing and it's generally recommended you use the
+#      native threading libraries instead. PTW32 should be set to be a list
+#      of two strings, the first specifying the installation path of the
+#      pthreads-win32 library and the second specifying which library
+#      variant to link against (see the pthreads-win32 documentation).
+#      Example: jam -sPTW32="c:\pthreads-win32 pthreadVCE.lib"
+
+# bring in rules for testing
+import testing ;
+
+project
+    : requirements <library>/boost/test//boost_unit_test_framework/<link>static
+                   <threading>multi
+    ;
+
+rule thread-run ( sources )
+{
+    return 
+    [ run $(sources) ../build//boost_thread ]
+    [ run $(sources) ../src/tss_null.cpp ../build//boost_thread/<link>static 
+        : : : : $(sources[1]:B)_lib ]
+    ;
+}    
+
+{
+    test-suite "threads"
+        : [ thread-run test_thread.cpp ]
+          [ thread-run test_thread_id.cpp ]
+          [ thread-run test_hardware_concurrency.cpp ]
+          [ thread-run test_thread_move.cpp ]
+          [ thread-run test_thread_launching.cpp ]
+          [ thread-run test_thread_mf.cpp ]
+          [ thread-run test_move_function.cpp ]
+          [ thread-run test_mutex.cpp ]
+          [ thread-run test_condition_notify_one.cpp ]
+          [ thread-run test_condition_timed_wait_times_out.cpp ]
+          [ thread-run test_condition_notify_all.cpp ]
+          [ thread-run test_condition.cpp ]
+          [ thread-run test_tss.cpp ]
+          [ thread-run test_once.cpp ]
+          [ thread-run test_xtime.cpp ]
+          [ thread-run test_barrier.cpp ]
+          [ thread-run test_shared_mutex.cpp ]
+          [ thread-run test_shared_mutex_part_2.cpp ]
+          [ thread-run test_shared_mutex_timed_locks.cpp ]
+          [ thread-run test_lock_concept.cpp ]
+          [ thread-run test_generic_locks.cpp ]
+          [ compile-fail no_implicit_move_from_lvalue_thread.cpp ]
+          [ compile-fail no_implicit_assign_from_lvalue_thread.cpp ]
+    ;
+}
diff --git a/deal.II/contrib/boost/libs/thread/test/condition_test_common.hpp b/deal.II/contrib/boost/libs/thread/test/condition_test_common.hpp
new file mode 100644 (file)
index 0000000..38f7790
--- /dev/null
@@ -0,0 +1,97 @@
+#ifndef CONDITION_TEST_COMMON_HPP
+#define CONDITION_TEST_COMMON_HPP
+// Copyright (C) 2007 Anthony Williams
+//
+//  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/thread/condition_variable.hpp>
+#include <boost/thread/mutex.hpp>
+#include <boost/thread/thread_time.hpp>
+
+unsigned const timeout_seconds=5;
+    
+struct wait_for_flag
+{
+    boost::mutex mutex;
+    boost::condition_variable cond_var;
+    bool flag;
+    unsigned woken;
+        
+    wait_for_flag():
+        flag(false),woken(0)
+    {}
+
+    struct check_flag
+    {
+        bool const& flag;
+            
+        check_flag(bool const& flag_):
+            flag(flag_)
+        {}
+            
+        bool operator()() const
+        {
+            return flag;
+        }
+    private:
+        void operator=(check_flag&);
+    };
+
+        
+    void wait_without_predicate()
+    {
+        boost::mutex::scoped_lock lock(mutex);
+        while(!flag)
+        {
+            cond_var.wait(lock);
+        }
+        ++woken;
+    }
+
+    void wait_with_predicate()
+    {
+        boost::mutex::scoped_lock lock(mutex);
+        cond_var.wait(lock,check_flag(flag));
+        if(flag)
+        {
+            ++woken;
+        }
+    }
+
+    void timed_wait_without_predicate()
+    {
+        boost::system_time const timeout=boost::get_system_time()+boost::posix_time::seconds(timeout_seconds);
+            
+        boost::mutex::scoped_lock lock(mutex);
+        while(!flag)
+        {
+            if(!cond_var.timed_wait(lock,timeout))
+            {
+                return;
+            }
+        }
+        ++woken;
+    }
+
+    void timed_wait_with_predicate()
+    {
+        boost::system_time const timeout=boost::get_system_time()+boost::posix_time::seconds(timeout_seconds);
+        boost::mutex::scoped_lock lock(mutex);
+        if(cond_var.timed_wait(lock,timeout,check_flag(flag)) && flag)
+        {
+            ++woken;
+        }
+    }
+    void relative_timed_wait_with_predicate()
+    {
+        boost::mutex::scoped_lock lock(mutex);
+        if(cond_var.timed_wait(lock,boost::posix_time::seconds(timeout_seconds),check_flag(flag)) && flag)
+        {
+            ++woken;
+        }
+    }
+};
+
+
+#endif
diff --git a/deal.II/contrib/boost/libs/thread/test/no_implicit_assign_from_lvalue_thread.cpp b/deal.II/contrib/boost/libs/thread/test/no_implicit_assign_from_lvalue_thread.cpp
new file mode 100644 (file)
index 0000000..02b6893
--- /dev/null
@@ -0,0 +1,15 @@
+// Copyright (C) 2008 Anthony Williams
+//
+//  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/thread/thread.hpp>
+
+void do_nothing()
+{}
+
+void test()
+{
+    boost::thread t1(do_nothing);
+    boost::thread t2;
+    t2=t1;
+}
diff --git a/deal.II/contrib/boost/libs/thread/test/no_implicit_move_from_lvalue_thread.cpp b/deal.II/contrib/boost/libs/thread/test/no_implicit_move_from_lvalue_thread.cpp
new file mode 100644 (file)
index 0000000..5c4600e
--- /dev/null
@@ -0,0 +1,14 @@
+// Copyright (C) 2008 Anthony Williams
+//
+//  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/thread/thread.hpp>
+
+void do_nothing()
+{}
+
+void test()
+{
+    boost::thread t1(do_nothing);
+    boost::thread t2(t1);
+}
diff --git a/deal.II/contrib/boost/libs/thread/test/shared_mutex_locking_thread.hpp b/deal.II/contrib/boost/libs/thread/test/shared_mutex_locking_thread.hpp
new file mode 100644 (file)
index 0000000..98a415b
--- /dev/null
@@ -0,0 +1,132 @@
+#ifndef SHARED_MUTEX_LOCKING_THREAD_HPP
+#define SHARED_MUTEX_LOCKING_THREAD_HPP
+
+//  (C) Copyright 2008 Anthony Williams
+//
+//  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/thread/mutex.hpp>
+#include <boost/thread/condition_variable.hpp>
+#include <boost/thread/shared_mutex.hpp>
+
+template<typename lock_type>
+class locking_thread
+{
+    boost::shared_mutex& rw_mutex;
+    unsigned& unblocked_count;
+    boost::condition_variable& unblocked_condition;
+    unsigned& simultaneous_running_count;
+    unsigned& max_simultaneous_running;
+    boost::mutex& unblocked_count_mutex;
+    boost::mutex& finish_mutex;
+public:
+    locking_thread(boost::shared_mutex& rw_mutex_,
+                   unsigned& unblocked_count_,
+                   boost::mutex& unblocked_count_mutex_,
+                   boost::condition_variable& unblocked_condition_,
+                   boost::mutex& finish_mutex_,
+                   unsigned& simultaneous_running_count_,
+                   unsigned& max_simultaneous_running_):
+        rw_mutex(rw_mutex_),
+        unblocked_count(unblocked_count_),
+        unblocked_condition(unblocked_condition_),
+        simultaneous_running_count(simultaneous_running_count_),
+        max_simultaneous_running(max_simultaneous_running_),
+        unblocked_count_mutex(unblocked_count_mutex_),
+        finish_mutex(finish_mutex_)
+    {}
+        
+    void operator()()
+    {
+        // acquire lock
+        lock_type lock(rw_mutex);
+            
+        // increment count to show we're unblocked
+        {
+            boost::mutex::scoped_lock ublock(unblocked_count_mutex);
+            ++unblocked_count;
+            unblocked_condition.notify_one();
+            ++simultaneous_running_count;
+            if(simultaneous_running_count>max_simultaneous_running)
+            {
+                max_simultaneous_running=simultaneous_running_count;
+            }
+        }
+            
+        // wait to finish
+        boost::mutex::scoped_lock finish_lock(finish_mutex);
+        {
+            boost::mutex::scoped_lock ublock(unblocked_count_mutex);
+            --simultaneous_running_count;
+        }
+    }
+private:
+    void operator=(locking_thread&);
+};
+
+class simple_writing_thread
+{
+    boost::shared_mutex& rwm;
+    boost::mutex& finish_mutex;
+    boost::mutex& unblocked_mutex;
+    unsigned& unblocked_count;
+        
+    void operator=(simple_writing_thread&);
+        
+public:
+    simple_writing_thread(boost::shared_mutex& rwm_,
+                          boost::mutex& finish_mutex_,
+                          boost::mutex& unblocked_mutex_,
+                          unsigned& unblocked_count_):
+        rwm(rwm_),finish_mutex(finish_mutex_),
+        unblocked_mutex(unblocked_mutex_),unblocked_count(unblocked_count_)
+    {}
+        
+    void operator()()
+    {
+        boost::unique_lock<boost::shared_mutex>  lk(rwm);
+            
+        {
+            boost::mutex::scoped_lock ulk(unblocked_mutex);
+            ++unblocked_count;
+        }
+            
+        boost::mutex::scoped_lock flk(finish_mutex);
+    }
+};
+
+class simple_reading_thread
+{
+    boost::shared_mutex& rwm;
+    boost::mutex& finish_mutex;
+    boost::mutex& unblocked_mutex;
+    unsigned& unblocked_count;
+        
+    void operator=(simple_reading_thread&);
+        
+public:
+    simple_reading_thread(boost::shared_mutex& rwm_,
+                          boost::mutex& finish_mutex_,
+                          boost::mutex& unblocked_mutex_,
+                          unsigned& unblocked_count_):
+        rwm(rwm_),finish_mutex(finish_mutex_),
+        unblocked_mutex(unblocked_mutex_),unblocked_count(unblocked_count_)
+    {}
+        
+    void operator()()
+    {
+        boost::shared_lock<boost::shared_mutex>  lk(rwm);
+            
+        {
+            boost::mutex::scoped_lock ulk(unblocked_mutex);
+            ++unblocked_count;
+        }
+            
+        boost::mutex::scoped_lock flk(finish_mutex);
+    }
+};
+
+
+#endif
diff --git a/deal.II/contrib/boost/libs/thread/test/test.mcp b/deal.II/contrib/boost/libs/thread/test/test.mcp
new file mode 100644 (file)
index 0000000..f27f0b9
Binary files /dev/null and b/deal.II/contrib/boost/libs/thread/test/test.mcp differ
diff --git a/deal.II/contrib/boost/libs/thread/test/test_barrier.cpp b/deal.II/contrib/boost/libs/thread/test/test_barrier.cpp
new file mode 100644 (file)
index 0000000..e487970
--- /dev/null
@@ -0,0 +1,66 @@
+// Copyright (C) 2001-2003
+// William E. Kempf
+//
+//  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/thread/detail/config.hpp>
+
+#include <boost/thread/thread.hpp>
+#include <boost/thread/barrier.hpp>
+
+#include <boost/test/unit_test.hpp>
+#include <vector>
+
+namespace {
+
+// Shared variables for generation barrier test
+const int N_THREADS=10;
+boost::barrier gen_barrier(N_THREADS);
+boost::mutex mutex;
+long global_parameter;
+
+void barrier_thread()
+{
+    for (int i = 0; i < 5; ++i)
+    {
+        if (gen_barrier.wait())
+        {
+            boost::mutex::scoped_lock lock(mutex);
+            global_parameter++;
+        }
+    }
+}
+
+} // namespace
+
+void test_barrier()
+{
+    boost::thread_group g;
+    global_parameter = 0;
+
+    try
+    {
+        for (int i = 0; i < N_THREADS; ++i)
+            g.create_thread(&barrier_thread);
+        g.join_all();
+    }
+    catch(...)
+    {
+        g.interrupt_all();
+        g.join_all();
+        throw;
+    }
+    
+    BOOST_CHECK_EQUAL(global_parameter,5);
+}
+
+boost::unit_test_framework::test_suite* init_unit_test_suite(int, char*[])
+{
+    boost::unit_test_framework::test_suite* test =
+        BOOST_TEST_SUITE("Boost.Threads: barrier test suite");
+
+    test->add(BOOST_TEST_CASE(&test_barrier));
+
+    return test;
+}
diff --git a/deal.II/contrib/boost/libs/thread/test/test_condition.cpp b/deal.II/contrib/boost/libs/thread/test/test_condition.cpp
new file mode 100644 (file)
index 0000000..ea008bf
--- /dev/null
@@ -0,0 +1,190 @@
+// Copyright (C) 2001-2003
+// William E. Kempf
+// Copyright (C) 2007 Anthony Williams
+//
+//  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/thread/detail/config.hpp>
+
+#include <boost/thread/condition.hpp>
+#include <boost/thread/thread.hpp>
+#include <boost/thread/xtime.hpp>
+
+#include <boost/test/unit_test.hpp>
+
+#include <libs/thread/test/util.inl>
+
+struct condition_test_data
+{
+    condition_test_data() : notified(0), awoken(0) { }
+
+    boost::mutex mutex;
+    boost::condition_variable condition;
+    int notified;
+    int awoken;
+};
+
+void condition_test_thread(condition_test_data* data)
+{
+    boost::mutex::scoped_lock lock(data->mutex);
+    BOOST_CHECK(lock ? true : false);
+    while (!(data->notified > 0))
+        data->condition.wait(lock);
+    BOOST_CHECK(lock ? true : false);
+    data->awoken++;
+}
+
+struct cond_predicate
+{
+    cond_predicate(int& var, int val) : _var(var), _val(val) { }
+
+    bool operator()() { return _var == _val; }
+
+    int& _var;
+    int _val;
+private:
+    void operator=(cond_predicate&);
+    
+};
+
+void condition_test_waits(condition_test_data* data)
+{
+    boost::mutex::scoped_lock lock(data->mutex);
+    BOOST_CHECK(lock ? true : false);
+
+    // Test wait.
+    while (data->notified != 1)
+        data->condition.wait(lock);
+    BOOST_CHECK(lock ? true : false);
+    BOOST_CHECK_EQUAL(data->notified, 1);
+    data->awoken++;
+    data->condition.notify_one();
+
+    // Test predicate wait.
+    data->condition.wait(lock, cond_predicate(data->notified, 2));
+    BOOST_CHECK(lock ? true : false);
+    BOOST_CHECK_EQUAL(data->notified, 2);
+    data->awoken++;
+    data->condition.notify_one();
+
+    // Test timed_wait.
+    boost::xtime xt = delay(10);
+    while (data->notified != 3)
+        data->condition.timed_wait(lock, xt);
+    BOOST_CHECK(lock ? true : false);
+    BOOST_CHECK_EQUAL(data->notified, 3);
+    data->awoken++;
+    data->condition.notify_one();
+
+    // Test predicate timed_wait.
+    xt = delay(10);
+    cond_predicate pred(data->notified, 4);
+    BOOST_CHECK(data->condition.timed_wait(lock, xt, pred));
+    BOOST_CHECK(lock ? true : false);
+    BOOST_CHECK(pred());
+    BOOST_CHECK_EQUAL(data->notified, 4);
+    data->awoken++;
+    data->condition.notify_one();
+
+    // Test predicate timed_wait with relative timeout
+    cond_predicate pred_rel(data->notified, 5);
+    BOOST_CHECK(data->condition.timed_wait(lock, boost::posix_time::seconds(10), pred_rel));
+    BOOST_CHECK(lock ? true : false);
+    BOOST_CHECK(pred_rel());
+    BOOST_CHECK_EQUAL(data->notified, 5);
+    data->awoken++;
+    data->condition.notify_one();
+}
+
+void do_test_condition_waits()
+{
+    condition_test_data data;
+
+    boost::thread thread(bind(&condition_test_waits, &data));
+
+    {
+        boost::mutex::scoped_lock lock(data.mutex);
+        BOOST_CHECK(lock ? true : false);
+
+        boost::thread::sleep(delay(1));
+        data.notified++;
+        data.condition.notify_one();
+        while (data.awoken != 1)
+            data.condition.wait(lock);
+        BOOST_CHECK(lock ? true : false);
+        BOOST_CHECK_EQUAL(data.awoken, 1);
+
+        boost::thread::sleep(delay(1));
+        data.notified++;
+        data.condition.notify_one();
+        while (data.awoken != 2)
+            data.condition.wait(lock);
+        BOOST_CHECK(lock ? true : false);
+        BOOST_CHECK_EQUAL(data.awoken, 2);
+
+        boost::thread::sleep(delay(1));
+        data.notified++;
+        data.condition.notify_one();
+        while (data.awoken != 3)
+            data.condition.wait(lock);
+        BOOST_CHECK(lock ? true : false);
+        BOOST_CHECK_EQUAL(data.awoken, 3);
+
+        boost::thread::sleep(delay(1));
+        data.notified++;
+        data.condition.notify_one();
+        while (data.awoken != 4)
+            data.condition.wait(lock);
+        BOOST_CHECK(lock ? true : false);
+        BOOST_CHECK_EQUAL(data.awoken, 4);
+
+
+        boost::thread::sleep(delay(1));
+        data.notified++;
+        data.condition.notify_one();
+        while (data.awoken != 5)
+            data.condition.wait(lock);
+        BOOST_CHECK(lock ? true : false);
+        BOOST_CHECK_EQUAL(data.awoken, 5);
+    }
+
+    thread.join();
+    BOOST_CHECK_EQUAL(data.awoken, 5);
+}
+
+void test_condition_waits()
+{
+    // We should have already tested notify_one here, so
+    // a timed test with the default execution_monitor::use_condition
+    // should be OK, and gives the fastest performance
+    timed_test(&do_test_condition_waits, 12);
+}
+
+void do_test_condition_wait_is_a_interruption_point()
+{
+    condition_test_data data;
+
+    boost::thread thread(bind(&condition_test_thread, &data));
+
+    thread.interrupt();
+    thread.join();
+    BOOST_CHECK_EQUAL(data.awoken,0);
+}
+
+
+void test_condition_wait_is_a_interruption_point()
+{
+    timed_test(&do_test_condition_wait_is_a_interruption_point, 1);
+}
+
+boost::unit_test_framework::test_suite* init_unit_test_suite(int, char*[])
+{
+    boost::unit_test_framework::test_suite* test =
+        BOOST_TEST_SUITE("Boost.Threads: condition test suite");
+
+    test->add(BOOST_TEST_CASE(&test_condition_waits));
+    test->add(BOOST_TEST_CASE(&test_condition_wait_is_a_interruption_point));
+
+    return test;
+}
diff --git a/deal.II/contrib/boost/libs/thread/test/test_condition_notify_all.cpp b/deal.II/contrib/boost/libs/thread/test/test_condition_notify_all.cpp
new file mode 100644 (file)
index 0000000..11a983e
--- /dev/null
@@ -0,0 +1,222 @@
+// Copyright (C) 2007 Anthony Williams
+//
+//  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/thread/detail/config.hpp>
+
+#include <boost/thread/thread.hpp>
+
+#include <boost/test/unit_test.hpp>
+
+#include <libs/thread/test/util.inl>
+#include "condition_test_common.hpp"
+
+unsigned const number_of_test_threads=5;
+
+void do_test_condition_notify_all_wakes_from_wait()
+{
+    wait_for_flag data;
+
+    boost::thread_group group;
+
+    try
+    {
+        for(unsigned i=0;i<number_of_test_threads;++i)
+        {
+            group.create_thread(bind(&wait_for_flag::wait_without_predicate, data));
+        }
+
+        {
+            boost::mutex::scoped_lock lock(data.mutex);
+            data.flag=true;
+            data.cond_var.notify_all();
+        }
+
+        group.join_all();
+        BOOST_CHECK_EQUAL(data.woken,number_of_test_threads);
+    }
+    catch(...)
+    {
+        group.join_all();
+        throw;
+    }
+}
+
+void do_test_condition_notify_all_wakes_from_wait_with_predicate()
+{
+    wait_for_flag data;
+
+    boost::thread_group group;
+
+    try
+    {
+        for(unsigned i=0;i<number_of_test_threads;++i)
+        {
+            group.create_thread(bind(&wait_for_flag::wait_with_predicate, data));
+        }
+
+        {
+            boost::mutex::scoped_lock lock(data.mutex);
+            data.flag=true;
+            data.cond_var.notify_all();
+        }
+
+        group.join_all();
+        BOOST_CHECK_EQUAL(data.woken,number_of_test_threads);
+    }
+    catch(...)
+    {
+        group.join_all();
+        throw;
+    }
+}
+
+void do_test_condition_notify_all_wakes_from_timed_wait()
+{
+    wait_for_flag data;
+
+    boost::thread_group group;
+
+    try
+    {
+        for(unsigned i=0;i<number_of_test_threads;++i)
+        {
+            group.create_thread(bind(&wait_for_flag::timed_wait_without_predicate, data));
+        }
+
+        {
+            boost::mutex::scoped_lock lock(data.mutex);
+            data.flag=true;
+            data.cond_var.notify_all();
+        }
+
+        group.join_all();
+        BOOST_CHECK_EQUAL(data.woken,number_of_test_threads);
+    }
+    catch(...)
+    {
+        group.join_all();
+        throw;
+    }
+}
+
+void do_test_condition_notify_all_wakes_from_timed_wait_with_predicate()
+{
+    wait_for_flag data;
+
+    boost::thread_group group;
+
+    try
+    {
+        for(unsigned i=0;i<number_of_test_threads;++i)
+        {
+            group.create_thread(bind(&wait_for_flag::timed_wait_with_predicate, data));
+        }
+
+        {
+            boost::mutex::scoped_lock lock(data.mutex);
+            data.flag=true;
+            data.cond_var.notify_all();
+        }
+
+        group.join_all();
+        BOOST_CHECK_EQUAL(data.woken,number_of_test_threads);
+    }
+    catch(...)
+    {
+        group.join_all();
+        throw;
+    }
+}
+
+void do_test_condition_notify_all_wakes_from_relative_timed_wait_with_predicate()
+{
+    wait_for_flag data;
+
+    boost::thread_group group;
+
+    try
+    {
+        for(unsigned i=0;i<number_of_test_threads;++i)
+        {
+            group.create_thread(bind(&wait_for_flag::relative_timed_wait_with_predicate, data));
+        }
+
+        {
+            boost::mutex::scoped_lock lock(data.mutex);
+            data.flag=true;
+            data.cond_var.notify_all();
+        }
+
+        group.join_all();
+        BOOST_CHECK_EQUAL(data.woken,number_of_test_threads);
+    }
+    catch(...)
+    {
+        group.join_all();
+        throw;
+    }
+}
+
+namespace
+{
+    boost::mutex multiple_wake_mutex;
+    boost::condition_variable multiple_wake_cond;
+    unsigned multiple_wake_count=0;
+
+    void wait_for_condvar_and_increase_count()
+    {
+        boost::mutex::scoped_lock lk(multiple_wake_mutex);
+        multiple_wake_cond.wait(lk);
+        ++multiple_wake_count;
+    }
+    
+}
+
+
+void do_test_notify_all_following_notify_one_wakes_all_threads()
+{
+    boost::thread thread1(wait_for_condvar_and_increase_count);
+    boost::thread thread2(wait_for_condvar_and_increase_count);
+
+    boost::this_thread::sleep(boost::posix_time::milliseconds(200));
+    multiple_wake_cond.notify_one();
+
+    boost::thread thread3(wait_for_condvar_and_increase_count);
+
+    boost::this_thread::sleep(boost::posix_time::milliseconds(200));
+    multiple_wake_cond.notify_one();
+    multiple_wake_cond.notify_all();
+    boost::this_thread::sleep(boost::posix_time::milliseconds(200));
+    
+    {
+        boost::mutex::scoped_lock lk(multiple_wake_mutex);
+        BOOST_CHECK(multiple_wake_count==3);
+    }
+
+    thread1.join();
+    thread2.join();
+    thread3.join();
+}
+
+void test_condition_notify_all()
+{
+    timed_test(&do_test_condition_notify_all_wakes_from_wait, timeout_seconds);
+    timed_test(&do_test_condition_notify_all_wakes_from_wait_with_predicate, timeout_seconds);
+    timed_test(&do_test_condition_notify_all_wakes_from_timed_wait, timeout_seconds);
+    timed_test(&do_test_condition_notify_all_wakes_from_timed_wait_with_predicate, timeout_seconds);
+    timed_test(&do_test_condition_notify_all_wakes_from_relative_timed_wait_with_predicate, timeout_seconds);
+    timed_test(&do_test_notify_all_following_notify_one_wakes_all_threads, timeout_seconds);
+}
+
+
+boost::unit_test_framework::test_suite* init_unit_test_suite(int, char*[])
+{
+    boost::unit_test_framework::test_suite* test =
+        BOOST_TEST_SUITE("Boost.Threads: condition test suite");
+
+    test->add(BOOST_TEST_CASE(&test_condition_notify_all));
+
+    return test;
+}
diff --git a/deal.II/contrib/boost/libs/thread/test/test_condition_notify_one.cpp b/deal.II/contrib/boost/libs/thread/test/test_condition_notify_one.cpp
new file mode 100644 (file)
index 0000000..a5d82be
--- /dev/null
@@ -0,0 +1,155 @@
+// Copyright (C) 2007 Anthony Williams
+//
+//  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/thread/detail/config.hpp>
+
+#include <boost/thread/thread.hpp>
+
+#include <boost/test/unit_test.hpp>
+
+#include <libs/thread/test/util.inl>
+#include "condition_test_common.hpp"
+
+void do_test_condition_notify_one_wakes_from_wait()
+{
+    wait_for_flag data;
+    
+    boost::thread thread(bind(&wait_for_flag::wait_without_predicate, data));
+
+    {
+        boost::mutex::scoped_lock lock(data.mutex);
+        data.flag=true;
+        data.cond_var.notify_one();
+    }
+
+    thread.join();
+    BOOST_CHECK(data.woken);
+}
+
+void do_test_condition_notify_one_wakes_from_wait_with_predicate()
+{
+    wait_for_flag data;
+    
+    boost::thread thread(bind(&wait_for_flag::wait_with_predicate, data));
+
+    {
+        boost::mutex::scoped_lock lock(data.mutex);
+        data.flag=true;
+        data.cond_var.notify_one();
+    }
+
+    thread.join();
+    BOOST_CHECK(data.woken);
+}
+
+void do_test_condition_notify_one_wakes_from_timed_wait()
+{
+    wait_for_flag data;
+    
+    boost::thread thread(bind(&wait_for_flag::timed_wait_without_predicate, data));
+
+    {
+        boost::mutex::scoped_lock lock(data.mutex);
+        data.flag=true;
+        data.cond_var.notify_one();
+    }
+
+    thread.join();
+    BOOST_CHECK(data.woken);
+}
+
+void do_test_condition_notify_one_wakes_from_timed_wait_with_predicate()
+{
+    wait_for_flag data;
+    
+    boost::thread thread(bind(&wait_for_flag::timed_wait_with_predicate, data));
+
+    {
+        boost::mutex::scoped_lock lock(data.mutex);
+        data.flag=true;
+        data.cond_var.notify_one();
+    }
+
+    thread.join();
+    BOOST_CHECK(data.woken);
+}
+
+void do_test_condition_notify_one_wakes_from_relative_timed_wait_with_predicate()
+{
+    wait_for_flag data;
+    
+    boost::thread thread(bind(&wait_for_flag::relative_timed_wait_with_predicate, data));
+
+    {
+        boost::mutex::scoped_lock lock(data.mutex);
+        data.flag=true;
+        data.cond_var.notify_one();
+    }
+
+    thread.join();
+    BOOST_CHECK(data.woken);
+}
+
+namespace
+{
+    boost::mutex multiple_wake_mutex;
+    boost::condition_variable multiple_wake_cond;
+    unsigned multiple_wake_count=0;
+
+    void wait_for_condvar_and_increase_count()
+    {
+        boost::mutex::scoped_lock lk(multiple_wake_mutex);
+        multiple_wake_cond.wait(lk);
+        ++multiple_wake_count;
+    }
+    
+}
+
+
+void do_test_multiple_notify_one_calls_wakes_multiple_threads()
+{
+    boost::thread thread1(wait_for_condvar_and_increase_count);
+    boost::thread thread2(wait_for_condvar_and_increase_count);
+
+    boost::this_thread::sleep(boost::posix_time::milliseconds(200));
+    multiple_wake_cond.notify_one();
+
+    boost::thread thread3(wait_for_condvar_and_increase_count);
+
+    boost::this_thread::sleep(boost::posix_time::milliseconds(200));
+    multiple_wake_cond.notify_one();
+    multiple_wake_cond.notify_one();
+    boost::this_thread::sleep(boost::posix_time::milliseconds(200));
+    
+    {
+        boost::mutex::scoped_lock lk(multiple_wake_mutex);
+        BOOST_CHECK(multiple_wake_count==3);
+    }
+
+    thread1.join();
+    thread2.join();
+    thread3.join();
+}
+
+void test_condition_notify_one()
+{
+    timed_test(&do_test_condition_notify_one_wakes_from_wait, timeout_seconds, execution_monitor::use_mutex);
+    timed_test(&do_test_condition_notify_one_wakes_from_wait_with_predicate, timeout_seconds, execution_monitor::use_mutex);
+    timed_test(&do_test_condition_notify_one_wakes_from_timed_wait, timeout_seconds, execution_monitor::use_mutex);
+    timed_test(&do_test_condition_notify_one_wakes_from_timed_wait_with_predicate, timeout_seconds, execution_monitor::use_mutex);
+    timed_test(&do_test_condition_notify_one_wakes_from_relative_timed_wait_with_predicate, timeout_seconds, execution_monitor::use_mutex);
+    timed_test(&do_test_multiple_notify_one_calls_wakes_multiple_threads, timeout_seconds, execution_monitor::use_mutex);
+}
+
+
+boost::unit_test_framework::test_suite* init_unit_test_suite(int, char*[])
+{
+    boost::unit_test_framework::test_suite* test =
+        BOOST_TEST_SUITE("Boost.Threads: condition test suite");
+
+    test->add(BOOST_TEST_CASE(&test_condition_notify_one));
+
+    return test;
+}
diff --git a/deal.II/contrib/boost/libs/thread/test/test_condition_timed_wait_times_out.cpp b/deal.II/contrib/boost/libs/thread/test/test_condition_timed_wait_times_out.cpp
new file mode 100644 (file)
index 0000000..9e17003
--- /dev/null
@@ -0,0 +1,173 @@
+// Copyright (C) 2007-8 Anthony Williams
+//
+//  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/thread/detail/config.hpp>
+
+#include <boost/thread/condition.hpp>
+#include <boost/thread/thread.hpp>
+
+#include <boost/test/unit_test.hpp>
+#include "util.inl"
+
+bool fake_predicate()
+{
+    return false;
+}
+
+unsigned const timeout_seconds=2;
+unsigned const timeout_grace=1;
+boost::posix_time::milliseconds const timeout_resolution(100);
+
+
+void do_test_timed_wait_times_out()
+{
+    boost::condition_variable cond;
+    boost::mutex m;
+
+    boost::posix_time::seconds const delay(timeout_seconds);
+    boost::mutex::scoped_lock lock(m);
+    boost::system_time const start=boost::get_system_time();
+    boost::system_time const timeout=start+delay;
+
+    while(cond.timed_wait(lock,timeout));
+
+    boost::system_time const end=boost::get_system_time();
+    BOOST_CHECK((delay-timeout_resolution)<=(end-start));
+}
+
+void do_test_timed_wait_with_predicate_times_out()
+{
+    boost::condition_variable cond;
+    boost::mutex m;
+
+    boost::posix_time::seconds const delay(timeout_seconds);
+    boost::mutex::scoped_lock lock(m);
+    boost::system_time const start=boost::get_system_time();
+    boost::system_time const timeout=start+delay;
+
+    bool const res=cond.timed_wait(lock,timeout,fake_predicate);
+
+    boost::system_time const end=boost::get_system_time();
+    BOOST_CHECK(!res);
+    BOOST_CHECK((delay-timeout_resolution)<=(end-start));
+}
+
+void do_test_relative_timed_wait_with_predicate_times_out()
+{
+    boost::condition_variable cond;
+    boost::mutex m;
+
+    boost::posix_time::seconds const delay(timeout_seconds);
+    boost::mutex::scoped_lock lock(m);
+    boost::system_time const start=boost::get_system_time();
+
+    bool const res=cond.timed_wait(lock,delay,fake_predicate);
+
+    boost::system_time const end=boost::get_system_time();
+    BOOST_CHECK(!res);
+    BOOST_CHECK((delay-timeout_resolution)<=(end-start));
+}
+
+void do_test_timed_wait_relative_times_out()
+{
+    boost::condition_variable cond;
+    boost::mutex m;
+
+    boost::posix_time::seconds const delay(timeout_seconds);
+    boost::mutex::scoped_lock lock(m);
+    boost::system_time const start=boost::get_system_time();
+
+    while(cond.timed_wait(lock,delay));
+
+    boost::system_time const end=boost::get_system_time();
+    BOOST_CHECK((delay-timeout_resolution)<=(end-start));
+}
+
+void do_test_cv_any_timed_wait_times_out()
+{
+    boost::condition_variable_any cond;
+    boost::mutex m;
+
+    boost::posix_time::seconds const delay(timeout_seconds);
+    boost::mutex::scoped_lock lock(m);
+    boost::system_time const start=boost::get_system_time();
+    boost::system_time const timeout=start+delay;
+
+    while(cond.timed_wait(lock,timeout));
+
+    boost::system_time const end=boost::get_system_time();
+    BOOST_CHECK((delay-timeout_resolution)<=(end-start));
+}
+
+void do_test_cv_any_timed_wait_with_predicate_times_out()
+{
+    boost::condition_variable_any cond;
+    boost::mutex m;
+
+    boost::posix_time::seconds const delay(timeout_seconds);
+    boost::mutex::scoped_lock lock(m);
+    boost::system_time const start=boost::get_system_time();
+    boost::system_time const timeout=start+delay;
+
+    bool const res=cond.timed_wait(lock,timeout,fake_predicate);
+
+    boost::system_time const end=boost::get_system_time();
+    BOOST_CHECK(!res);
+    BOOST_CHECK((delay-timeout_resolution)<=(end-start));
+}
+
+void do_test_cv_any_relative_timed_wait_with_predicate_times_out()
+{
+    boost::condition_variable_any cond;
+    boost::mutex m;
+
+    boost::posix_time::seconds const delay(timeout_seconds);
+    boost::mutex::scoped_lock lock(m);
+    boost::system_time const start=boost::get_system_time();
+
+    bool const res=cond.timed_wait(lock,delay,fake_predicate);
+
+    boost::system_time const end=boost::get_system_time();
+    BOOST_CHECK(!res);
+    BOOST_CHECK((delay-timeout_resolution)<=(end-start));
+}
+
+void do_test_cv_any_timed_wait_relative_times_out()
+{
+    boost::condition_variable_any cond;
+    boost::mutex m;
+
+    boost::posix_time::seconds const delay(timeout_seconds);
+    boost::mutex::scoped_lock lock(m);
+    boost::system_time const start=boost::get_system_time();
+
+    while(cond.timed_wait(lock,delay));
+
+    boost::system_time const end=boost::get_system_time();
+    BOOST_CHECK((delay-timeout_resolution)<=(end-start));
+}
+
+
+void test_timed_wait_times_out()
+{
+    timed_test(&do_test_timed_wait_times_out, timeout_seconds+timeout_grace, execution_monitor::use_mutex);
+    timed_test(&do_test_timed_wait_with_predicate_times_out, timeout_seconds+timeout_grace, execution_monitor::use_mutex);
+    timed_test(&do_test_relative_timed_wait_with_predicate_times_out, timeout_seconds+timeout_grace, execution_monitor::use_mutex);
+    timed_test(&do_test_timed_wait_relative_times_out, timeout_seconds+timeout_grace, execution_monitor::use_mutex);
+    timed_test(&do_test_cv_any_timed_wait_times_out, timeout_seconds+timeout_grace, execution_monitor::use_mutex);
+    timed_test(&do_test_cv_any_timed_wait_with_predicate_times_out, timeout_seconds+timeout_grace, execution_monitor::use_mutex);
+    timed_test(&do_test_cv_any_relative_timed_wait_with_predicate_times_out, timeout_seconds+timeout_grace, execution_monitor::use_mutex);
+    timed_test(&do_test_cv_any_timed_wait_relative_times_out, timeout_seconds+timeout_grace, execution_monitor::use_mutex);
+}
+
+boost::unit_test_framework::test_suite* init_unit_test_suite(int, char*[])
+{
+    boost::unit_test_framework::test_suite* test =
+        BOOST_TEST_SUITE("Boost.Threads: condition test suite");
+
+    test->add(BOOST_TEST_CASE(&test_timed_wait_times_out));
+
+    return test;
+}
diff --git a/deal.II/contrib/boost/libs/thread/test/test_generic_locks.cpp b/deal.II/contrib/boost/libs/thread/test/test_generic_locks.cpp
new file mode 100644 (file)
index 0000000..d3880d5
--- /dev/null
@@ -0,0 +1,523 @@
+// (C) Copyright 2008 Anthony Williams
+// 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/test/unit_test.hpp>
+#include <boost/thread/mutex.hpp>
+#include <boost/thread/thread.hpp>
+#include <boost/thread/locks.hpp>
+#include <boost/thread/condition_variable.hpp>
+
+void test_lock_two_uncontended()
+{
+    boost::mutex m1,m2;
+
+    boost::mutex::scoped_lock l1(m1,boost::defer_lock),
+        l2(m2,boost::defer_lock);
+
+    BOOST_CHECK(!l1.owns_lock());
+    BOOST_CHECK(!l2.owns_lock());
+    
+    boost::lock(l1,l2);
+    
+    BOOST_CHECK(l1.owns_lock());
+    BOOST_CHECK(l2.owns_lock());
+}
+
+struct wait_data
+{
+    boost::mutex m;
+    bool flag;
+    boost::condition_variable cond;
+    
+    wait_data():
+        flag(false)
+    {}
+    
+    void wait()
+    {
+        boost::mutex::scoped_lock l(m);
+        while(!flag)
+        {
+            cond.wait(l);
+        }
+    }
+
+    template<typename Duration>
+    bool timed_wait(Duration d)
+    {
+        boost::system_time const target=boost::get_system_time()+d;
+        
+        boost::mutex::scoped_lock l(m);
+        while(!flag)
+        {
+            if(!cond.timed_wait(l,target))
+            {
+                return flag;
+            }
+        }
+        return true;
+    }
+    
+    void signal()
+    {
+        boost::mutex::scoped_lock l(m);
+        flag=true;
+        cond.notify_all();
+    }
+};
+       
+
+void lock_mutexes_slowly(boost::mutex* m1,boost::mutex* m2,wait_data* locked,wait_data* quit)
+{
+    boost::lock_guard<boost::mutex> l1(*m1);
+    boost::this_thread::sleep(boost::posix_time::milliseconds(500));
+    boost::lock_guard<boost::mutex> l2(*m2);
+    locked->signal();
+    quit->wait();
+}
+
+void lock_pair(boost::mutex* m1,boost::mutex* m2)
+{
+    boost::lock(*m1,*m2);
+    boost::mutex::scoped_lock l1(*m1,boost::adopt_lock),
+        l2(*m2,boost::adopt_lock);
+}
+
+void test_lock_two_other_thread_locks_in_order()
+{
+    boost::mutex m1,m2;
+    wait_data locked;
+    wait_data release;
+    
+    boost::thread t(lock_mutexes_slowly,&m1,&m2,&locked,&release);
+    boost::this_thread::sleep(boost::posix_time::milliseconds(10));
+
+    boost::thread t2(lock_pair,&m1,&m2);
+    BOOST_CHECK(locked.timed_wait(boost::posix_time::seconds(1)));
+
+    release.signal();
+    
+    BOOST_CHECK(t2.timed_join(boost::posix_time::seconds(1)));
+
+    t.join();
+}
+
+void test_lock_two_other_thread_locks_in_opposite_order()
+{
+    boost::mutex m1,m2;
+    wait_data locked;
+    wait_data release;
+    
+    boost::thread t(lock_mutexes_slowly,&m1,&m2,&locked,&release);
+    boost::this_thread::sleep(boost::posix_time::milliseconds(10));
+
+    boost::thread t2(lock_pair,&m2,&m1);
+    BOOST_CHECK(locked.timed_wait(boost::posix_time::seconds(1)));
+
+    release.signal();
+    
+    BOOST_CHECK(t2.timed_join(boost::posix_time::seconds(1)));
+
+    t.join();
+}
+
+void test_lock_five_uncontended()
+{
+    boost::mutex m1,m2,m3,m4,m5;
+
+    boost::mutex::scoped_lock l1(m1,boost::defer_lock),
+        l2(m2,boost::defer_lock),
+        l3(m3,boost::defer_lock),
+        l4(m4,boost::defer_lock),
+        l5(m5,boost::defer_lock);
+
+    BOOST_CHECK(!l1.owns_lock());
+    BOOST_CHECK(!l2.owns_lock());
+    BOOST_CHECK(!l3.owns_lock());
+    BOOST_CHECK(!l4.owns_lock());
+    BOOST_CHECK(!l5.owns_lock());
+    
+    boost::lock(l1,l2,l3,l4,l5);
+    
+    BOOST_CHECK(l1.owns_lock());
+    BOOST_CHECK(l2.owns_lock());
+    BOOST_CHECK(l3.owns_lock());
+    BOOST_CHECK(l4.owns_lock());
+    BOOST_CHECK(l5.owns_lock());
+}
+
+void lock_five_mutexes_slowly(boost::mutex* m1,boost::mutex* m2,boost::mutex* m3,boost::mutex* m4,boost::mutex* m5,
+                              wait_data* locked,wait_data* quit)
+{
+    boost::lock_guard<boost::mutex> l1(*m1);
+    boost::this_thread::sleep(boost::posix_time::milliseconds(500));
+    boost::lock_guard<boost::mutex> l2(*m2);
+    boost::this_thread::sleep(boost::posix_time::milliseconds(500));
+    boost::lock_guard<boost::mutex> l3(*m3);
+    boost::this_thread::sleep(boost::posix_time::milliseconds(500));
+    boost::lock_guard<boost::mutex> l4(*m4);
+    boost::this_thread::sleep(boost::posix_time::milliseconds(500));
+    boost::lock_guard<boost::mutex> l5(*m5);
+    locked->signal();
+    quit->wait();
+}
+
+void lock_five(boost::mutex* m1,boost::mutex* m2,boost::mutex* m3,boost::mutex* m4,boost::mutex* m5)
+{
+    boost::lock(*m1,*m2,*m3,*m4,*m5);
+    m1->unlock();
+    m2->unlock();
+    m3->unlock();
+    m4->unlock();
+    m5->unlock();
+}
+
+void test_lock_five_other_thread_locks_in_order()
+{
+    boost::mutex m1,m2,m3,m4,m5;
+    wait_data locked;
+    wait_data release;
+    
+    boost::thread t(lock_five_mutexes_slowly,&m1,&m2,&m3,&m4,&m5,&locked,&release);
+    boost::this_thread::sleep(boost::posix_time::milliseconds(10));
+
+    boost::thread t2(lock_five,&m1,&m2,&m3,&m4,&m5);
+    BOOST_CHECK(locked.timed_wait(boost::posix_time::seconds(3)));
+
+    release.signal();
+    
+    BOOST_CHECK(t2.timed_join(boost::posix_time::seconds(3)));
+
+    t.join();
+}
+
+void test_lock_five_other_thread_locks_in_different_order()
+{
+    boost::mutex m1,m2,m3,m4,m5;
+    wait_data locked;
+    wait_data release;
+    
+    boost::thread t(lock_five_mutexes_slowly,&m1,&m2,&m3,&m4,&m5,&locked,&release);
+    boost::this_thread::sleep(boost::posix_time::milliseconds(10));
+
+    boost::thread t2(lock_five,&m5,&m1,&m4,&m2,&m3);
+    BOOST_CHECK(locked.timed_wait(boost::posix_time::seconds(3)));
+
+    release.signal();
+    
+    BOOST_CHECK(t2.timed_join(boost::posix_time::seconds(3)));
+
+    t.join();
+}
+
+void lock_n(boost::mutex* mutexes,unsigned count)
+{
+    boost::lock(mutexes,mutexes+count);
+    for(unsigned i=0;i<count;++i)
+    {
+        mutexes[i].unlock();
+    }
+}
+
+
+void test_lock_ten_other_thread_locks_in_different_order()
+{
+    unsigned const num_mutexes=10;
+    
+    boost::mutex mutexes[num_mutexes];
+    wait_data locked;
+    wait_data release;
+    
+    boost::thread t(lock_five_mutexes_slowly,&mutexes[6],&mutexes[3],&mutexes[8],&mutexes[0],&mutexes[2],&locked,&release);
+    boost::this_thread::sleep(boost::posix_time::milliseconds(10));
+
+    boost::thread t2(lock_n,mutexes,num_mutexes);
+    BOOST_CHECK(locked.timed_wait(boost::posix_time::seconds(3)));
+
+    release.signal();
+
+    BOOST_CHECK(t2.timed_join(boost::posix_time::seconds(3)));
+
+    t.join();
+}
+
+struct dummy_mutex
+{
+    bool is_locked;
+    
+    dummy_mutex():
+        is_locked(false)
+    {}
+    
+    void lock()
+    {
+        is_locked=true;
+    }
+    
+    bool try_lock()
+    {
+        if(is_locked)
+        {
+            return false;
+        }
+        is_locked=true;
+        return true;
+    }
+    
+    void unlock()
+    {
+        is_locked=false;
+    }
+};
+
+namespace boost
+{
+    template<>
+    struct is_mutex_type<dummy_mutex>
+    {
+        BOOST_STATIC_CONSTANT(bool, value = true);
+    };
+}
+
+
+
+void test_lock_five_in_range()
+{
+    unsigned const num_mutexes=5;
+    dummy_mutex mutexes[num_mutexes];
+
+    boost::lock(mutexes,mutexes+num_mutexes);
+    
+    for(unsigned i=0;i<num_mutexes;++i)
+    {
+        BOOST_CHECK(mutexes[i].is_locked);
+    }
+}
+
+void test_lock_ten_in_range()
+{
+    unsigned const num_mutexes=10;
+    dummy_mutex mutexes[num_mutexes];
+
+    boost::lock(mutexes,mutexes+num_mutexes);
+    
+    for(unsigned i=0;i<num_mutexes;++i)
+    {
+        BOOST_CHECK(mutexes[i].is_locked);
+    }
+}
+
+void test_try_lock_two_uncontended()
+{
+    dummy_mutex m1,m2;
+
+    int const res=boost::try_lock(m1,m2);
+    
+    BOOST_CHECK(res==-1);
+    BOOST_CHECK(m1.is_locked);
+    BOOST_CHECK(m2.is_locked);
+}
+void test_try_lock_two_first_locked()
+{
+    dummy_mutex m1,m2;
+    m1.lock();
+
+    boost::unique_lock<dummy_mutex> l1(m1,boost::defer_lock),
+        l2(m2,boost::defer_lock);
+
+    int const res=boost::try_lock(l1,l2);
+    
+    BOOST_CHECK(res==0);
+    BOOST_CHECK(m1.is_locked);
+    BOOST_CHECK(!m2.is_locked);
+    BOOST_CHECK(!l1.owns_lock());
+    BOOST_CHECK(!l2.owns_lock());
+}
+void test_try_lock_two_second_locked()
+{
+    dummy_mutex m1,m2;
+    m2.lock();
+
+    boost::unique_lock<dummy_mutex> l1(m1,boost::defer_lock),
+        l2(m2,boost::defer_lock);
+
+    int const res=boost::try_lock(l1,l2);
+    
+    BOOST_CHECK(res==1);
+    BOOST_CHECK(!m1.is_locked);
+    BOOST_CHECK(m2.is_locked);
+    BOOST_CHECK(!l1.owns_lock());
+    BOOST_CHECK(!l2.owns_lock());
+}
+
+void test_try_lock_three()
+{
+    int const num_mutexes=3;
+    
+    for(int i=-1;i<num_mutexes;++i)
+    {
+        dummy_mutex mutexes[num_mutexes];
+
+        if(i>=0)
+        {
+            mutexes[i].lock();
+        }
+        boost::unique_lock<dummy_mutex> l1(mutexes[0],boost::defer_lock),
+            l2(mutexes[1],boost::defer_lock),
+            l3(mutexes[2],boost::defer_lock);
+
+        int const res=boost::try_lock(l1,l2,l3);
+    
+        BOOST_CHECK(res==i);
+        for(int j=0;j<num_mutexes;++j)
+        {
+            if((i==j) || (i==-1))
+            {
+                BOOST_CHECK(mutexes[j].is_locked);
+            }
+            else
+            {
+                BOOST_CHECK(!mutexes[j].is_locked);
+            }
+        }
+        if(i==-1)
+        {
+            BOOST_CHECK(l1.owns_lock());
+            BOOST_CHECK(l2.owns_lock());
+            BOOST_CHECK(l3.owns_lock());
+        }
+        else
+        {
+            BOOST_CHECK(!l1.owns_lock());
+            BOOST_CHECK(!l2.owns_lock());
+            BOOST_CHECK(!l3.owns_lock());
+        }
+    }
+}
+
+void test_try_lock_four()
+{
+    int const num_mutexes=4;
+    
+    for(int i=-1;i<num_mutexes;++i)
+    {
+        dummy_mutex mutexes[num_mutexes];
+
+        if(i>=0)
+        {
+            mutexes[i].lock();
+        }
+        boost::unique_lock<dummy_mutex> l1(mutexes[0],boost::defer_lock),
+            l2(mutexes[1],boost::defer_lock),
+            l3(mutexes[2],boost::defer_lock),
+            l4(mutexes[3],boost::defer_lock);
+
+        int const res=boost::try_lock(l1,l2,l3,l4);
+    
+        BOOST_CHECK(res==i);
+        for(int j=0;j<num_mutexes;++j)
+        {
+            if((i==j) || (i==-1))
+            {
+                BOOST_CHECK(mutexes[j].is_locked);
+            }
+            else
+            {
+                BOOST_CHECK(!mutexes[j].is_locked);
+            }
+        }
+        if(i==-1)
+        {
+            BOOST_CHECK(l1.owns_lock());
+            BOOST_CHECK(l2.owns_lock());
+            BOOST_CHECK(l3.owns_lock());
+            BOOST_CHECK(l4.owns_lock());
+        }
+        else
+        {
+            BOOST_CHECK(!l1.owns_lock());
+            BOOST_CHECK(!l2.owns_lock());
+            BOOST_CHECK(!l3.owns_lock());
+            BOOST_CHECK(!l4.owns_lock());
+        }
+    }
+}
+
+void test_try_lock_five()
+{
+    int const num_mutexes=5;
+    
+    for(int i=-1;i<num_mutexes;++i)
+    {
+        dummy_mutex mutexes[num_mutexes];
+
+        if(i>=0)
+        {
+            mutexes[i].lock();
+        }
+        boost::unique_lock<dummy_mutex> l1(mutexes[0],boost::defer_lock),
+            l2(mutexes[1],boost::defer_lock),
+            l3(mutexes[2],boost::defer_lock),
+            l4(mutexes[3],boost::defer_lock),
+            l5(mutexes[4],boost::defer_lock);
+
+        int const res=boost::try_lock(l1,l2,l3,l4,l5);
+    
+        BOOST_CHECK(res==i);
+        for(int j=0;j<num_mutexes;++j)
+        {
+            if((i==j) || (i==-1))
+            {
+                BOOST_CHECK(mutexes[j].is_locked);
+            }
+            else
+            {
+                BOOST_CHECK(!mutexes[j].is_locked);
+            }
+        }
+        if(i==-1)
+        {
+            BOOST_CHECK(l1.owns_lock());
+            BOOST_CHECK(l2.owns_lock());
+            BOOST_CHECK(l3.owns_lock());
+            BOOST_CHECK(l4.owns_lock());
+            BOOST_CHECK(l5.owns_lock());
+        }
+        else
+        {
+            BOOST_CHECK(!l1.owns_lock());
+            BOOST_CHECK(!l2.owns_lock());
+            BOOST_CHECK(!l3.owns_lock());
+            BOOST_CHECK(!l4.owns_lock());
+            BOOST_CHECK(!l5.owns_lock());
+        }
+    }
+}
+
+
+
+boost::unit_test_framework::test_suite* init_unit_test_suite(int, char*[])
+{
+    boost::unit_test_framework::test_suite* test =
+        BOOST_TEST_SUITE("Boost.Threads: generic locks test suite");
+
+    test->add(BOOST_TEST_CASE(&test_lock_two_uncontended));
+    test->add(BOOST_TEST_CASE(&test_lock_two_other_thread_locks_in_order));
+    test->add(BOOST_TEST_CASE(&test_lock_two_other_thread_locks_in_opposite_order));
+    test->add(BOOST_TEST_CASE(&test_lock_five_uncontended));
+    test->add(BOOST_TEST_CASE(&test_lock_five_other_thread_locks_in_order));
+    test->add(BOOST_TEST_CASE(&test_lock_five_other_thread_locks_in_different_order));
+    test->add(BOOST_TEST_CASE(&test_lock_five_in_range));
+    test->add(BOOST_TEST_CASE(&test_lock_ten_in_range));
+    test->add(BOOST_TEST_CASE(&test_lock_ten_other_thread_locks_in_different_order));
+    test->add(BOOST_TEST_CASE(&test_try_lock_two_uncontended));
+    test->add(BOOST_TEST_CASE(&test_try_lock_two_first_locked));
+    test->add(BOOST_TEST_CASE(&test_try_lock_two_second_locked));
+    test->add(BOOST_TEST_CASE(&test_try_lock_three));
+    test->add(BOOST_TEST_CASE(&test_try_lock_four));
+    test->add(BOOST_TEST_CASE(&test_try_lock_five));
+
+    return test;
+}
diff --git a/deal.II/contrib/boost/libs/thread/test/test_hardware_concurrency.cpp b/deal.II/contrib/boost/libs/thread/test/test_hardware_concurrency.cpp
new file mode 100644 (file)
index 0000000..7c1c148
--- /dev/null
@@ -0,0 +1,21 @@
+// Copyright (C) 2007 Anthony Williams
+//
+//  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/thread/thread.hpp>
+#include <boost/test/unit_test.hpp>
+#include <boost/thread/mutex.hpp>
+
+void test_hardware_concurrency_is_non_zero()
+{
+    BOOST_CHECK(boost::thread::hardware_concurrency()!=0);
+}
+
+boost::unit_test_framework::test_suite* init_unit_test_suite(int, char*[])
+{
+    boost::unit_test_framework::test_suite* test =
+        BOOST_TEST_SUITE("Boost.Threads: hardware concurrency test suite");
+
+    test->add(BOOST_TEST_CASE(test_hardware_concurrency_is_non_zero));
+    return test;
+}
diff --git a/deal.II/contrib/boost/libs/thread/test/test_lock_concept.cpp b/deal.II/contrib/boost/libs/thread/test/test_lock_concept.cpp
new file mode 100644 (file)
index 0000000..06367d5
--- /dev/null
@@ -0,0 +1,571 @@
+// (C) Copyright 2006-8 Anthony Williams
+// 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/test/unit_test.hpp>
+#include <boost/test/test_case_template.hpp>
+#include <boost/mpl/vector.hpp>
+#include <boost/thread/mutex.hpp>
+#include <boost/thread/shared_mutex.hpp>
+#include <boost/thread/thread.hpp>
+#include <boost/thread/recursive_mutex.hpp>
+#include <boost/thread/condition_variable.hpp>
+
+template<typename Mutex,typename Lock>
+struct test_initially_locked
+{
+    void operator()() const
+    {
+        Mutex m;
+        Lock lock(m);
+        
+        BOOST_CHECK(lock);
+        BOOST_CHECK(lock.owns_lock());
+    }
+};
+
+template<typename Mutex,typename Lock>
+struct test_initially_unlocked_if_other_thread_has_lock
+{
+    Mutex m;
+    boost::mutex done_mutex;
+    bool done;
+    bool locked;
+    boost::condition_variable done_cond;
+    
+    test_initially_unlocked_if_other_thread_has_lock():
+        done(false),locked(false)
+    {}
+
+    void locking_thread()
+    {
+        Lock lock(m);
+
+        boost::lock_guard<boost::mutex> lk(done_mutex);
+        locked=lock.owns_lock();
+        done=true;
+        done_cond.notify_one();
+    }
+
+    bool is_done() const
+    {
+        return done;
+    }
+    
+
+    void operator()()
+    {
+        Lock lock(m);
+
+        typedef test_initially_unlocked_if_other_thread_has_lock<Mutex,Lock> this_type;
+
+        boost::thread t(&this_type::locking_thread,this);
+
+        try
+        {
+            {
+                boost::mutex::scoped_lock lk(done_mutex);
+                BOOST_CHECK(done_cond.timed_wait(lk,boost::posix_time::seconds(2),
+                                                 boost::bind(&this_type::is_done,this)));
+                BOOST_CHECK(!locked);
+            }
+            
+            lock.unlock();
+            t.join();
+        }
+        catch(...)
+        {
+            lock.unlock();
+            t.join();
+            throw;
+        }
+    }
+};
+
+template<typename Mutex,typename Lock>
+struct test_initially_unlocked_with_try_lock_if_other_thread_has_unique_lock
+{
+    Mutex m;
+    boost::mutex done_mutex;
+    bool done;
+    bool locked;
+    boost::condition_variable done_cond;
+    
+    test_initially_unlocked_with_try_lock_if_other_thread_has_unique_lock():
+        done(false),locked(false)
+    {}
+
+    void locking_thread()
+    {
+        Lock lock(m,boost::try_to_lock);
+
+        boost::lock_guard<boost::mutex> lk(done_mutex);
+        locked=lock.owns_lock();
+        done=true;
+        done_cond.notify_one();
+    }
+
+    bool is_done() const
+    {
+        return done;
+    }
+    
+
+    void operator()()
+    {
+        boost::unique_lock<Mutex> lock(m);
+
+        typedef test_initially_unlocked_with_try_lock_if_other_thread_has_unique_lock<Mutex,Lock> this_type;
+
+        boost::thread t(&this_type::locking_thread,this);
+
+        try
+        {
+            {
+                boost::mutex::scoped_lock lk(done_mutex);
+                BOOST_CHECK(done_cond.timed_wait(lk,boost::posix_time::seconds(2),
+                                                 boost::bind(&this_type::is_done,this)));
+                BOOST_CHECK(!locked);
+            }
+            
+            lock.unlock();
+            t.join();
+        }
+        catch(...)
+        {
+            lock.unlock();
+            t.join();
+            throw;
+        }
+    }
+};
+
+template<typename Mutex,typename Lock>
+struct test_initially_locked_if_other_thread_has_shared_lock
+{
+    Mutex m;
+    boost::mutex done_mutex;
+    bool done;
+    bool locked;
+    boost::condition_variable done_cond;
+    
+    test_initially_locked_if_other_thread_has_shared_lock():
+        done(false),locked(false)
+    {}
+
+    void locking_thread()
+    {
+        Lock lock(m);
+
+        boost::lock_guard<boost::mutex> lk(done_mutex);
+        locked=lock.owns_lock();
+        done=true;
+        done_cond.notify_one();
+    }
+
+    bool is_done() const
+    {
+        return done;
+    }
+    
+
+    void operator()()
+    {
+        boost::shared_lock<Mutex> lock(m);
+
+        typedef test_initially_locked_if_other_thread_has_shared_lock<Mutex,Lock> this_type;
+
+        boost::thread t(&this_type::locking_thread,this);
+
+        try
+        {
+            {
+                boost::mutex::scoped_lock lk(done_mutex);
+                BOOST_CHECK(done_cond.timed_wait(lk,boost::posix_time::seconds(2),
+                                                 boost::bind(&this_type::is_done,this)));
+                BOOST_CHECK(locked);
+            }
+            
+            lock.unlock();
+            t.join();
+        }
+        catch(...)
+        {
+            lock.unlock();
+            t.join();
+            throw;
+        }
+    }
+};
+
+template<typename Mutex,typename Lock>
+struct test_initially_unlocked_with_defer_lock_parameter
+{
+    void operator()() const
+    {
+        Mutex m;
+        Lock lock(m,boost::defer_lock);
+        
+        BOOST_CHECK(!lock);
+        BOOST_CHECK(!lock.owns_lock());
+    }
+};
+
+template<typename Mutex,typename Lock>
+struct test_initially_locked_with_adopt_lock_parameter
+{
+    void operator()() const
+    {
+        Mutex m;
+        m.lock();
+        Lock lock(m,boost::adopt_lock);
+        
+        BOOST_CHECK(lock);
+        BOOST_CHECK(lock.owns_lock());
+    }
+};
+
+
+template<typename Mutex,typename Lock>
+struct test_unlocked_after_unlock_called
+{
+    void operator()() const
+    {
+        Mutex m;
+        Lock lock(m);
+        lock.unlock();
+        BOOST_CHECK(!lock);
+        BOOST_CHECK(!lock.owns_lock());
+    }
+};
+
+template<typename Mutex,typename Lock>
+struct test_locked_after_lock_called
+{
+    void operator()() const
+    {
+        Mutex m;
+        Lock lock(m,boost::defer_lock);
+        lock.lock();
+        BOOST_CHECK(lock);
+        BOOST_CHECK(lock.owns_lock());
+    }
+};
+
+template<typename Mutex,typename Lock>
+struct test_locked_after_try_lock_called
+{
+    void operator()() const
+    {
+        Mutex m;
+        Lock lock(m,boost::defer_lock);
+        lock.try_lock();
+        BOOST_CHECK(lock);
+        BOOST_CHECK(lock.owns_lock());
+    }
+};
+
+template<typename Mutex,typename Lock>
+struct test_unlocked_after_try_lock_if_other_thread_has_lock
+{
+    Mutex m;
+    boost::mutex done_mutex;
+    bool done;
+    bool locked;
+    boost::condition_variable done_cond;
+    
+    test_unlocked_after_try_lock_if_other_thread_has_lock():
+        done(false),locked(false)
+    {}
+
+    void locking_thread()
+    {
+        Lock lock(m,boost::defer_lock);
+
+        boost::lock_guard<boost::mutex> lk(done_mutex);
+        locked=lock.owns_lock();
+        done=true;
+        done_cond.notify_one();
+    }
+
+    bool is_done() const
+    {
+        return done;
+    }
+    
+
+    void operator()()
+    {
+        Lock lock(m);
+
+        typedef test_unlocked_after_try_lock_if_other_thread_has_lock<Mutex,Lock> this_type;
+
+        boost::thread t(&this_type::locking_thread,this);
+
+        try
+        {
+            {
+                boost::mutex::scoped_lock lk(done_mutex);
+                BOOST_CHECK(done_cond.timed_wait(lk,boost::posix_time::seconds(2),
+                                                 boost::bind(&this_type::is_done,this)));
+                BOOST_CHECK(!locked);
+            }
+            
+            lock.unlock();
+            t.join();
+        }
+        catch(...)
+        {
+            lock.unlock();
+            t.join();
+            throw;
+        }
+    }
+};
+
+template<typename Mutex,typename Lock>
+struct test_throws_if_lock_called_when_already_locked
+{
+    void operator()() const
+    {
+        Mutex m;
+        Lock lock(m);
+        
+        BOOST_CHECK_THROW( lock.lock(), boost::lock_error );
+    }
+};
+
+template<typename Mutex,typename Lock>
+struct test_throws_if_try_lock_called_when_already_locked
+{
+    void operator()() const
+    {
+        Mutex m;
+        Lock lock(m);
+        
+        BOOST_CHECK_THROW( lock.try_lock(), boost::lock_error );
+    }
+};
+
+template<typename Mutex,typename Lock>
+struct test_throws_if_unlock_called_when_already_unlocked
+{
+    void operator()() const
+    {
+        Mutex m;
+        Lock lock(m);
+        lock.unlock();
+        
+        BOOST_CHECK_THROW( lock.unlock(), boost::lock_error );
+    }
+};
+template<typename Lock>
+struct test_default_constructed_has_no_mutex_and_unlocked
+{
+    void operator()() const
+    {
+        Lock l;
+        BOOST_CHECK(!l.mutex());
+        BOOST_CHECK(!l.owns_lock());
+    };
+};
+
+
+template<typename Mutex,typename Lock>
+struct test_locks_can_be_swapped
+{
+    void operator()() const
+    {
+        Mutex m1;
+        Mutex m2;
+        Mutex m3;
+
+        Lock l1(m1);
+        Lock l2(m2);
+
+        BOOST_CHECK_EQUAL(l1.mutex(),&m1);
+        BOOST_CHECK_EQUAL(l2.mutex(),&m2);
+
+        l1.swap(l2);
+        
+        BOOST_CHECK_EQUAL(l1.mutex(),&m2);
+        BOOST_CHECK_EQUAL(l2.mutex(),&m1);
+        
+        swap(l1,l2);
+
+        BOOST_CHECK_EQUAL(l1.mutex(),&m1);
+        BOOST_CHECK_EQUAL(l2.mutex(),&m2);
+
+        l1.swap(Lock(m3));
+
+        BOOST_CHECK_EQUAL(l1.mutex(),&m3);
+    }
+};
+
+template<typename Mutex,typename Lock>
+void test_lock_is_scoped_lock_concept_for_mutex()
+{
+    test_default_constructed_has_no_mutex_and_unlocked<Lock>()();
+    test_initially_locked<Mutex,Lock>()();
+    test_initially_unlocked_with_defer_lock_parameter<Mutex,Lock>()();
+    test_initially_locked_with_adopt_lock_parameter<Mutex,Lock>()();
+    test_unlocked_after_unlock_called<Mutex,Lock>()();
+    test_locked_after_lock_called<Mutex,Lock>()();
+    test_throws_if_lock_called_when_already_locked<Mutex,Lock>()();
+    test_throws_if_unlock_called_when_already_unlocked<Mutex,Lock>()();
+    test_locks_can_be_swapped<Mutex,Lock>()();
+    test_locked_after_try_lock_called<Mutex,Lock>()();
+    test_throws_if_try_lock_called_when_already_locked<Mutex,Lock>()();
+    test_unlocked_after_try_lock_if_other_thread_has_lock<Mutex,Lock>()();
+}
+
+
+BOOST_TEST_CASE_TEMPLATE_FUNCTION(test_scoped_lock_concept,Mutex)
+{
+    typedef typename Mutex::scoped_lock Lock;
+
+    test_lock_is_scoped_lock_concept_for_mutex<Mutex,Lock>();
+}
+
+BOOST_TEST_CASE_TEMPLATE_FUNCTION(test_unique_lock_is_scoped_lock,Mutex)
+{
+    typedef boost::unique_lock<Mutex> Lock;
+
+    test_lock_is_scoped_lock_concept_for_mutex<Mutex,Lock>();
+}
+
+BOOST_TEST_CASE_TEMPLATE_FUNCTION(test_scoped_try_lock_concept,Mutex)
+{
+    typedef typename Mutex::scoped_try_lock Lock;
+    
+    test_default_constructed_has_no_mutex_and_unlocked<Lock>()();
+    test_initially_locked<Mutex,Lock>()();
+    test_initially_unlocked_if_other_thread_has_lock<Mutex,Lock>()();
+    test_initially_unlocked_with_defer_lock_parameter<Mutex,Lock>()();
+    test_initially_locked_with_adopt_lock_parameter<Mutex,Lock>()();
+    test_unlocked_after_unlock_called<Mutex,Lock>()();
+    test_locked_after_lock_called<Mutex,Lock>()();
+    test_locked_after_try_lock_called<Mutex,Lock>()();
+    test_unlocked_after_try_lock_if_other_thread_has_lock<Mutex,Lock>()();
+    test_throws_if_lock_called_when_already_locked<Mutex,Lock>()();
+    test_throws_if_try_lock_called_when_already_locked<Mutex,Lock>()();
+    test_throws_if_unlock_called_when_already_unlocked<Mutex,Lock>()();
+    test_locks_can_be_swapped<Mutex,Lock>()();
+}
+
+struct dummy_shared_mutex
+{
+    bool locked;
+    bool shared_locked;
+    bool shared_unlocked;
+    bool shared_timed_locked_relative;
+    bool shared_timed_locked_absolute;
+    bool timed_locked_relative;
+    bool timed_locked_absolute;
+
+    dummy_shared_mutex():
+        locked(false),shared_locked(false),shared_unlocked(false),
+        shared_timed_locked_relative(false),
+        shared_timed_locked_absolute(false),
+        timed_locked_relative(false),
+        timed_locked_absolute(false)
+    {}
+    
+    void lock()
+    {
+        locked=true;
+    }
+    
+    void lock_shared()
+    {
+        shared_locked=true;
+    }
+    
+    void unlock()
+    {}
+    
+    void unlock_shared()
+    {
+        shared_unlocked=true;
+    }
+    
+    bool timed_lock_shared(boost::system_time)
+    {
+        shared_timed_locked_absolute=true;
+        return false;
+    }
+    template<typename Duration>
+    bool timed_lock_shared(Duration)
+    {
+        shared_timed_locked_relative=true;
+        return false;
+    }
+    bool timed_lock(boost::system_time)
+    {
+        timed_locked_absolute=true;
+        return false;
+    }
+    template<typename Duration>
+    bool timed_lock(Duration)
+    {
+        timed_locked_relative=true;
+        return false;
+    }
+    
+};
+
+
+void test_shared_lock()
+{
+    typedef boost::shared_mutex Mutex;
+    typedef boost::shared_lock<Mutex> Lock;
+    
+    test_default_constructed_has_no_mutex_and_unlocked<Lock>()();
+    test_initially_locked<Mutex,Lock>()();
+    test_initially_unlocked_with_try_lock_if_other_thread_has_unique_lock<Mutex,Lock>()();
+    test_initially_locked_if_other_thread_has_shared_lock<Mutex,Lock>()();
+    test_initially_unlocked_with_defer_lock_parameter<Mutex,Lock>()();
+    test_initially_locked_with_adopt_lock_parameter<Mutex,Lock>()();
+    test_unlocked_after_unlock_called<Mutex,Lock>()();
+    test_locked_after_lock_called<Mutex,Lock>()();
+    test_locked_after_try_lock_called<Mutex,Lock>()();
+    test_throws_if_lock_called_when_already_locked<Mutex,Lock>()();
+    test_throws_if_try_lock_called_when_already_locked<Mutex,Lock>()();
+    test_throws_if_unlock_called_when_already_unlocked<Mutex,Lock>()();
+    test_locks_can_be_swapped<Mutex,Lock>()();
+
+    dummy_shared_mutex dummy;
+    boost::shared_lock<dummy_shared_mutex> lk(dummy);
+    BOOST_CHECK(dummy.shared_locked);
+    lk.unlock();
+    BOOST_CHECK(dummy.shared_unlocked);
+    lk.timed_lock(boost::posix_time::milliseconds(5));
+    BOOST_CHECK(dummy.shared_timed_locked_relative);
+    lk.timed_lock(boost::get_system_time());
+    BOOST_CHECK(dummy.shared_timed_locked_absolute);
+}
+
+boost::unit_test_framework::test_suite* init_unit_test_suite(int, char*[])
+{
+    boost::unit_test_framework::test_suite* test =
+        BOOST_TEST_SUITE("Boost.Threads: lock concept test suite");
+
+    typedef boost::mpl::vector<boost::mutex,boost::try_mutex,boost::timed_mutex,
+        boost::recursive_mutex,boost::recursive_try_mutex,boost::recursive_timed_mutex> mutex_types_with_scoped_lock;
+    
+    test->add(BOOST_TEST_CASE_TEMPLATE(test_scoped_lock_concept,mutex_types_with_scoped_lock));
+
+    typedef boost::mpl::vector<boost::try_mutex,boost::timed_mutex,
+        boost::recursive_try_mutex,boost::recursive_timed_mutex> mutex_types_with_scoped_try_lock;
+
+    test->add(BOOST_TEST_CASE_TEMPLATE(test_scoped_try_lock_concept,mutex_types_with_scoped_try_lock));
+
+    typedef boost::mpl::vector<boost::mutex,boost::try_mutex,boost::timed_mutex,
+        boost::recursive_mutex,boost::recursive_try_mutex,boost::recursive_timed_mutex,boost::shared_mutex> all_mutex_types;
+    
+    test->add(BOOST_TEST_CASE_TEMPLATE(test_unique_lock_is_scoped_lock,all_mutex_types));
+    test->add(BOOST_TEST_CASE(&test_shared_lock));
+
+    return test;
+}
diff --git a/deal.II/contrib/boost/libs/thread/test/test_move_function.cpp b/deal.II/contrib/boost/libs/thread/test/test_move_function.cpp
new file mode 100644 (file)
index 0000000..6400ada
--- /dev/null
@@ -0,0 +1,124 @@
+// Copyright (C) 2007-8 Anthony Williams
+//
+//  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/thread/thread.hpp>
+#include <boost/test/unit_test.hpp>
+#include <boost/thread/mutex.hpp>
+#include <boost/shared_ptr.hpp>
+
+void do_nothing()
+{}
+
+void test_thread_move_from_lvalue_on_construction()
+{
+    boost::thread src(do_nothing);
+    boost::thread::id src_id=src.get_id();
+    boost::thread dest(boost::move(src));
+    boost::thread::id dest_id=dest.get_id();
+    BOOST_CHECK(src_id==dest_id);
+    BOOST_CHECK(src.get_id()==boost::thread::id());
+    dest.join();
+}
+
+void test_thread_move_from_lvalue_on_assignment()
+{
+    boost::thread src(do_nothing);
+    boost::thread::id src_id=src.get_id();
+    boost::thread dest;
+    dest=boost::move(src);
+    boost::thread::id dest_id=dest.get_id();
+    BOOST_CHECK(src_id==dest_id);
+    BOOST_CHECK(src.get_id()==boost::thread::id());
+    dest.join();
+}
+
+boost::thread start_thread()
+{
+    return boost::thread(do_nothing);
+}
+
+void test_thread_move_from_rvalue_on_construction()
+{
+    boost::thread x(start_thread());
+    BOOST_CHECK(x.get_id()!=boost::thread::id());
+    x.join();
+}
+
+void test_thread_move_from_rvalue_using_explicit_move()
+{
+    boost::thread x(boost::move(start_thread()));
+    BOOST_CHECK(x.get_id()!=boost::thread::id());
+    x.join();
+}
+
+void test_unique_lock_move_from_lvalue_on_construction()
+{
+    boost::mutex m;
+    boost::unique_lock<boost::mutex> l(m);
+    BOOST_CHECK(l.owns_lock());
+    BOOST_CHECK(l.mutex()==&m);
+
+    boost::unique_lock<boost::mutex> l2(boost::move(l));
+    BOOST_CHECK(!l.owns_lock());
+    BOOST_CHECK(!l.mutex());
+    BOOST_CHECK(l2.owns_lock());
+    BOOST_CHECK(l2.mutex()==&m);
+}
+
+boost::unique_lock<boost::mutex> get_lock(boost::mutex& m)
+{
+    return boost::unique_lock<boost::mutex>(m);
+}
+
+
+void test_unique_lock_move_from_rvalue_on_construction()
+{
+    boost::mutex m;
+    boost::unique_lock<boost::mutex> l(get_lock(m));
+    BOOST_CHECK(l.owns_lock());
+    BOOST_CHECK(l.mutex()==&m);
+}
+
+namespace user_test_ns
+{
+    template<typename T>
+    T move(T& t)
+    {
+        return t.move();
+    }
+
+    bool move_called=false;
+    
+    struct nc:
+        public boost::shared_ptr<int>
+    {
+        nc move()
+        {
+            move_called=true;
+            return nc();
+        }
+    };
+}
+
+void test_move_for_user_defined_type_unaffected()
+{
+    user_test_ns::nc src;
+    user_test_ns::nc dest=move(src);
+    BOOST_CHECK(user_test_ns::move_called);
+}
+
+boost::unit_test_framework::test_suite* init_unit_test_suite(int, char*[])
+{
+    boost::unit_test_framework::test_suite* test =
+        BOOST_TEST_SUITE("Boost.Threads: thread move test suite");
+
+    test->add(BOOST_TEST_CASE(test_thread_move_from_lvalue_on_construction));
+    test->add(BOOST_TEST_CASE(test_thread_move_from_rvalue_on_construction));
+    test->add(BOOST_TEST_CASE(test_thread_move_from_rvalue_using_explicit_move));
+    test->add(BOOST_TEST_CASE(test_thread_move_from_lvalue_on_assignment));
+    test->add(BOOST_TEST_CASE(test_unique_lock_move_from_lvalue_on_construction));
+    test->add(BOOST_TEST_CASE(test_unique_lock_move_from_rvalue_on_construction));
+    test->add(BOOST_TEST_CASE(test_move_for_user_defined_type_unaffected));
+    return test;
+}
diff --git a/deal.II/contrib/boost/libs/thread/test/test_mutex.cpp b/deal.II/contrib/boost/libs/thread/test/test_mutex.cpp
new file mode 100644 (file)
index 0000000..8725a8f
--- /dev/null
@@ -0,0 +1,347 @@
+// Copyright (C) 2001-2003
+// William E. Kempf
+//
+//  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/thread/detail/config.hpp>
+
+#include <boost/thread/mutex.hpp>
+#include <boost/thread/thread.hpp>
+#include <boost/thread/recursive_mutex.hpp>
+#include <boost/thread/thread_time.hpp>
+#include <boost/thread/condition.hpp>
+
+#include <boost/test/unit_test.hpp>
+
+#define DEFAULT_EXECUTION_MONITOR_TYPE execution_monitor::use_sleep_only
+#include <libs/thread/test/util.inl>
+
+template <typename M>
+struct test_lock
+{
+    typedef M mutex_type;
+    typedef typename M::scoped_lock lock_type;
+
+    void operator()()
+    {
+        mutex_type mutex;
+        boost::condition condition;
+
+        // Test the lock's constructors.
+        {
+            lock_type lock(mutex, boost::defer_lock);
+            BOOST_CHECK(!lock);
+        }
+        lock_type lock(mutex);
+        BOOST_CHECK(lock ? true : false);
+
+        // Construct and initialize an xtime for a fast time out.
+        boost::xtime xt = delay(0, 100);
+
+        // Test the lock and the mutex with condition variables.
+        // No one is going to notify this condition variable.  We expect to
+        // time out.
+        BOOST_CHECK(!condition.timed_wait(lock, xt));
+        BOOST_CHECK(lock ? true : false);
+
+        // Test the lock and unlock methods.
+        lock.unlock();
+        BOOST_CHECK(!lock);
+        lock.lock();
+        BOOST_CHECK(lock ? true : false);
+    }
+};
+
+template <typename M>
+struct test_trylock
+{
+    typedef M mutex_type;
+    typedef typename M::scoped_try_lock try_lock_type;
+
+    void operator()()
+    {
+        mutex_type mutex;
+        boost::condition condition;
+
+        // Test the lock's constructors.
+        {
+            try_lock_type lock(mutex);
+            BOOST_CHECK(lock ? true : false);
+        }
+        {
+            try_lock_type lock(mutex, boost::defer_lock);
+            BOOST_CHECK(!lock);
+        }
+        try_lock_type lock(mutex);
+        BOOST_CHECK(lock ? true : false);
+
+        // Construct and initialize an xtime for a fast time out.
+        boost::xtime xt = delay(0, 100);
+
+        // Test the lock and the mutex with condition variables.
+        // No one is going to notify this condition variable.  We expect to
+        // time out.
+        BOOST_CHECK(!condition.timed_wait(lock, xt));
+        BOOST_CHECK(lock ? true : false);
+
+        // Test the lock, unlock and trylock methods.
+        lock.unlock();
+        BOOST_CHECK(!lock);
+        lock.lock();
+        BOOST_CHECK(lock ? true : false);
+        lock.unlock();
+        BOOST_CHECK(!lock);
+        BOOST_CHECK(lock.try_lock());
+        BOOST_CHECK(lock ? true : false);
+    }
+};
+
+template<typename Mutex>
+struct test_lock_times_out_if_other_thread_has_lock
+{
+    typedef boost::unique_lock<Mutex> Lock;
+    
+    Mutex m;
+    boost::mutex done_mutex;
+    bool done;
+    bool locked;
+    boost::condition_variable done_cond;
+    
+    test_lock_times_out_if_other_thread_has_lock():
+        done(false),locked(false)
+    {}
+
+    void locking_thread()
+    {
+        Lock lock(m,boost::defer_lock);
+        lock.timed_lock(boost::posix_time::milliseconds(50));
+
+        boost::lock_guard<boost::mutex> lk(done_mutex);
+        locked=lock.owns_lock();
+        done=true;
+        done_cond.notify_one();
+    }
+
+    void locking_thread_through_constructor()
+    {
+        Lock lock(m,boost::posix_time::milliseconds(50));
+
+        boost::lock_guard<boost::mutex> lk(done_mutex);
+        locked=lock.owns_lock();
+        done=true;
+        done_cond.notify_one();
+    }
+
+    bool is_done() const
+    {
+        return done;
+    }
+
+    typedef test_lock_times_out_if_other_thread_has_lock<Mutex> this_type;
+    
+    void do_test(void (this_type::*test_func)())
+    {
+        Lock lock(m);
+
+        locked=false;
+        done=false;
+        
+        boost::thread t(test_func,this);
+
+        try
+        {
+            {
+                boost::mutex::scoped_lock lk(done_mutex);
+                BOOST_CHECK(done_cond.timed_wait(lk,boost::posix_time::seconds(2),
+                                                 boost::bind(&this_type::is_done,this)));
+                BOOST_CHECK(!locked);
+            }
+            
+            lock.unlock();
+            t.join();
+        }
+        catch(...)
+        {
+            lock.unlock();
+            t.join();
+            throw;
+        }
+    }
+    
+
+    void operator()()
+    {
+        do_test(&this_type::locking_thread);
+        do_test(&this_type::locking_thread_through_constructor);
+    }
+};
+
+template <typename M>
+struct test_timedlock
+{
+    typedef M mutex_type;
+    typedef typename M::scoped_timed_lock timed_lock_type;
+
+    static bool fake_predicate()
+    {
+        return false;
+    }
+
+    void operator()()
+    {
+        test_lock_times_out_if_other_thread_has_lock<mutex_type>()();
+        
+        mutex_type mutex;
+        boost::condition condition;
+
+        // Test the lock's constructors.
+        {
+            // Construct and initialize an xtime for a fast time out.
+            boost::system_time xt = boost::get_system_time()+boost::posix_time::milliseconds(100);
+
+            timed_lock_type lock(mutex, xt);
+            BOOST_CHECK(lock ? true : false);
+        }
+        {
+            timed_lock_type lock(mutex, boost::defer_lock);
+            BOOST_CHECK(!lock);
+        }
+        timed_lock_type lock(mutex);
+        BOOST_CHECK(lock ? true : false);
+
+        // Construct and initialize an xtime for a fast time out.
+        boost::system_time timeout = boost::get_system_time()+boost::posix_time::milliseconds(100);
+
+        // Test the lock and the mutex with condition variables.
+        // No one is going to notify this condition variable.  We expect to
+        // time out.
+        BOOST_CHECK(!condition.timed_wait(lock, timeout, fake_predicate));
+        BOOST_CHECK(lock ? true : false);
+
+        boost::system_time now=boost::get_system_time();
+        boost::posix_time::milliseconds const timeout_resolution(20);
+        BOOST_CHECK((timeout-timeout_resolution)<now);
+
+        // Test the lock, unlock and timedlock methods.
+        lock.unlock();
+        BOOST_CHECK(!lock);
+        lock.lock();
+        BOOST_CHECK(lock ? true : false);
+        lock.unlock();
+        BOOST_CHECK(!lock);
+        boost::system_time target = boost::get_system_time()+boost::posix_time::milliseconds(100);
+        BOOST_CHECK(lock.timed_lock(target));
+        BOOST_CHECK(lock ? true : false);
+        lock.unlock();
+        BOOST_CHECK(!lock);
+
+        BOOST_CHECK(mutex.timed_lock(boost::posix_time::milliseconds(100)));
+        mutex.unlock();
+
+        BOOST_CHECK(lock.timed_lock(boost::posix_time::milliseconds(100)));
+        BOOST_CHECK(lock ? true : false);
+        lock.unlock();
+        BOOST_CHECK(!lock);
+        
+    }
+};
+
+template <typename M>
+struct test_recursive_lock
+{
+    typedef M mutex_type;
+    typedef typename M::scoped_lock lock_type;
+
+    void operator()()
+    {
+        mutex_type mx;
+        lock_type lock1(mx);
+        lock_type lock2(mx);
+    }
+};
+
+
+void do_test_mutex()
+{
+    test_lock<boost::mutex>()();
+}
+
+void test_mutex()
+{
+    timed_test(&do_test_mutex, 3);
+}
+
+void do_test_try_mutex()
+{
+    test_lock<boost::try_mutex>()();
+    test_trylock<boost::try_mutex>()();
+}
+
+void test_try_mutex()
+{
+    timed_test(&do_test_try_mutex, 3);
+}
+
+void do_test_timed_mutex()
+{
+    test_lock<boost::timed_mutex>()();
+    test_trylock<boost::timed_mutex>()();
+    test_timedlock<boost::timed_mutex>()();
+}
+
+void test_timed_mutex()
+{
+    timed_test(&do_test_timed_mutex, 3);
+}
+
+void do_test_recursive_mutex()
+{
+    test_lock<boost::recursive_mutex>()();
+    test_recursive_lock<boost::recursive_mutex>()();
+}
+
+void test_recursive_mutex()
+{
+    timed_test(&do_test_recursive_mutex, 3);
+}
+
+void do_test_recursive_try_mutex()
+{
+    test_lock<boost::recursive_try_mutex>()();
+    test_trylock<boost::recursive_try_mutex>()();
+    test_recursive_lock<boost::recursive_try_mutex>()();
+}
+
+void test_recursive_try_mutex()
+{
+    timed_test(&do_test_recursive_try_mutex, 3);
+}
+
+void do_test_recursive_timed_mutex()
+{
+    test_lock<boost::recursive_timed_mutex>()();
+    test_trylock<boost::recursive_timed_mutex>()();
+    test_timedlock<boost::recursive_timed_mutex>()();
+    test_recursive_lock<boost::recursive_timed_mutex>()();
+}
+
+void test_recursive_timed_mutex()
+{
+    timed_test(&do_test_recursive_timed_mutex, 3);
+}
+
+boost::unit_test_framework::test_suite* init_unit_test_suite(int, char*[])
+{
+    boost::unit_test_framework::test_suite* test =
+        BOOST_TEST_SUITE("Boost.Threads: mutex test suite");
+
+    test->add(BOOST_TEST_CASE(&test_mutex));
+    test->add(BOOST_TEST_CASE(&test_try_mutex));
+    test->add(BOOST_TEST_CASE(&test_timed_mutex));
+    test->add(BOOST_TEST_CASE(&test_recursive_mutex));
+    test->add(BOOST_TEST_CASE(&test_recursive_try_mutex));
+    test->add(BOOST_TEST_CASE(&test_recursive_timed_mutex));
+
+    return test;
+}
diff --git a/deal.II/contrib/boost/libs/thread/test/test_once.cpp b/deal.II/contrib/boost/libs/thread/test/test_once.cpp
new file mode 100644 (file)
index 0000000..f0e2c1e
--- /dev/null
@@ -0,0 +1,191 @@
+// (C) Copyright 2006-7 Anthony Williams
+// 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/test/unit_test.hpp>
+#include <boost/thread/thread.hpp>
+#include <boost/thread/mutex.hpp>
+#include <boost/thread/once.hpp>
+
+boost::once_flag flag=BOOST_ONCE_INIT;
+int var_to_init=0;
+boost::mutex m;
+
+void initialize_variable()
+{
+    // ensure that if multiple threads get in here, they are serialized, so we can see the effect
+    boost::mutex::scoped_lock lock(m);
+    ++var_to_init;
+}
+
+
+void call_once_thread()
+{
+    unsigned const loop_count=100;
+    int my_once_value=0;
+    for(unsigned i=0;i<loop_count;++i)
+    {
+        boost::call_once(flag, initialize_variable);
+        my_once_value=var_to_init;
+        if(my_once_value!=1)
+        {
+            break;
+        }
+    }
+    boost::mutex::scoped_lock lock(m);
+    BOOST_CHECK_EQUAL(my_once_value, 1);
+}
+
+void test_call_once()
+{
+    unsigned const num_threads=20;
+    boost::thread_group group;
+
+    try
+    {
+        for(unsigned i=0;i<num_threads;++i)
+        {
+            group.create_thread(&call_once_thread);
+        }
+        group.join_all();
+    }
+    catch(...)
+    {
+        group.interrupt_all();
+        group.join_all();
+        throw;
+    }
+
+    BOOST_CHECK_EQUAL(var_to_init,1);
+}
+
+int var_to_init_with_functor=0;
+
+struct increment_value
+{
+    int* value;
+    explicit increment_value(int* value_):
+        value(value_)
+    {}
+    
+    void operator()() const
+    {
+        boost::mutex::scoped_lock lock(m);
+        ++(*value);
+    }
+};
+
+void call_once_with_functor()
+{
+    unsigned const loop_count=100;
+    int my_once_value=0;
+    static boost::once_flag functor_flag=BOOST_ONCE_INIT;
+    for(unsigned i=0;i<loop_count;++i)
+    {
+        boost::call_once(functor_flag, increment_value(&var_to_init_with_functor));
+        my_once_value=var_to_init_with_functor;
+        if(my_once_value!=1)
+        {
+            break;
+        }
+    }
+    boost::mutex::scoped_lock lock(m);
+    BOOST_CHECK_EQUAL(my_once_value, 1);
+}
+
+void test_call_once_arbitrary_functor()
+{
+    unsigned const num_threads=20;
+    boost::thread_group group;
+
+    try
+    {
+        for(unsigned i=0;i<num_threads;++i)
+        {
+            group.create_thread(&call_once_with_functor);
+        }
+        group.join_all();
+    }
+    catch(...)
+    {
+        group.interrupt_all();
+        group.join_all();
+        throw;
+    }
+
+    BOOST_CHECK_EQUAL(var_to_init_with_functor,1);
+}
+
+
+struct throw_before_third_pass
+{
+    struct my_exception
+    {};
+
+    static unsigned pass_counter;
+    
+    void operator()() const
+    {
+        boost::mutex::scoped_lock lock(m);
+        ++pass_counter;
+        if(pass_counter<3)
+        {
+            throw my_exception();
+        }
+    }
+};
+
+unsigned throw_before_third_pass::pass_counter=0;
+unsigned exception_counter=0;
+
+void call_once_with_exception()
+{
+    static boost::once_flag functor_flag=BOOST_ONCE_INIT;
+    try
+    {
+        boost::call_once(functor_flag, throw_before_third_pass());
+    }
+    catch(throw_before_third_pass::my_exception)
+    {
+        boost::mutex::scoped_lock lock(m);
+        ++exception_counter;
+    }
+}
+
+void test_call_once_retried_on_exception()
+{
+    unsigned const num_threads=20;
+    boost::thread_group group;
+
+    try
+    {
+        for(unsigned i=0;i<num_threads;++i)
+        {
+            group.create_thread(&call_once_with_exception);
+        }
+        group.join_all();
+    }
+    catch(...)
+    {
+        group.interrupt_all();
+        group.join_all();
+        throw;
+    }
+
+    BOOST_CHECK_EQUAL(throw_before_third_pass::pass_counter,3u);
+    BOOST_CHECK_EQUAL(exception_counter,2u);
+}
+
+
+boost::unit_test_framework::test_suite* init_unit_test_suite(int, char*[])
+{
+    boost::unit_test_framework::test_suite* test =
+        BOOST_TEST_SUITE("Boost.Threads: call_once test suite");
+
+    test->add(BOOST_TEST_CASE(test_call_once));
+    test->add(BOOST_TEST_CASE(test_call_once_arbitrary_functor));
+    test->add(BOOST_TEST_CASE(test_call_once_retried_on_exception));
+
+    return test;
+}
diff --git a/deal.II/contrib/boost/libs/thread/test/test_shared_mutex.cpp b/deal.II/contrib/boost/libs/thread/test/test_shared_mutex.cpp
new file mode 100644 (file)
index 0000000..2cd4502
--- /dev/null
@@ -0,0 +1,285 @@
+// (C) Copyright 2006-7 Anthony Williams
+// 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/test/unit_test.hpp>
+#include <boost/thread/thread.hpp>
+#include <boost/thread/xtime.hpp>
+#include "util.inl"
+#include "shared_mutex_locking_thread.hpp"
+
+#define CHECK_LOCKED_VALUE_EQUAL(mutex_name,value,expected_value)    \
+    {                                                                \
+        boost::mutex::scoped_lock lock(mutex_name);                  \
+        BOOST_CHECK_EQUAL(value,expected_value);                     \
+    }
+
+void test_multiple_readers()
+{
+    unsigned const number_of_threads=10;
+    
+    boost::thread_group pool;
+
+    boost::shared_mutex rw_mutex;
+    unsigned unblocked_count=0;
+    unsigned simultaneous_running_count=0;
+    unsigned max_simultaneous_running=0;
+    boost::mutex unblocked_count_mutex;
+    boost::condition_variable unblocked_condition;
+    boost::mutex finish_mutex;
+    boost::mutex::scoped_lock finish_lock(finish_mutex);
+
+    try
+    {
+        for(unsigned i=0;i<number_of_threads;++i)
+        {
+            pool.create_thread(locking_thread<boost::shared_lock<boost::shared_mutex> >(rw_mutex,unblocked_count,unblocked_count_mutex,unblocked_condition,
+                                                                                        finish_mutex,simultaneous_running_count,max_simultaneous_running));
+        }
+
+        {
+            boost::mutex::scoped_lock lk(unblocked_count_mutex);
+            while(unblocked_count<number_of_threads)
+            {
+                unblocked_condition.wait(lk);
+            }
+        }
+
+        CHECK_LOCKED_VALUE_EQUAL(unblocked_count_mutex,unblocked_count,number_of_threads);
+
+        finish_lock.unlock();
+
+        pool.join_all();
+    }
+    catch(...)
+    {
+        pool.interrupt_all();
+        pool.join_all();
+        throw;
+    }
+
+    CHECK_LOCKED_VALUE_EQUAL(unblocked_count_mutex,max_simultaneous_running,number_of_threads);
+}
+
+void test_only_one_writer_permitted()
+{
+    unsigned const number_of_threads=10;
+    
+    boost::thread_group pool;
+
+    boost::shared_mutex rw_mutex;
+    unsigned unblocked_count=0;
+    unsigned simultaneous_running_count=0;
+    unsigned max_simultaneous_running=0;
+    boost::mutex unblocked_count_mutex;
+    boost::condition_variable unblocked_condition;
+    boost::mutex finish_mutex;
+    boost::mutex::scoped_lock finish_lock(finish_mutex);
+    
+    try
+    {
+        for(unsigned i=0;i<number_of_threads;++i)
+        {
+            pool.create_thread(locking_thread<boost::unique_lock<boost::shared_mutex> >(rw_mutex,unblocked_count,unblocked_count_mutex,unblocked_condition,
+                                                                                        finish_mutex,simultaneous_running_count,max_simultaneous_running));
+        }
+
+        boost::thread::sleep(delay(2));
+
+        CHECK_LOCKED_VALUE_EQUAL(unblocked_count_mutex,unblocked_count,1U);
+
+        finish_lock.unlock();
+
+        pool.join_all();
+    }
+    catch(...)
+    {
+        pool.interrupt_all();
+        pool.join_all();
+        throw;
+    }
+
+    CHECK_LOCKED_VALUE_EQUAL(unblocked_count_mutex,unblocked_count,number_of_threads);
+    CHECK_LOCKED_VALUE_EQUAL(unblocked_count_mutex,max_simultaneous_running,1u);
+}
+
+void test_reader_blocks_writer()
+{
+    boost::thread_group pool;
+
+    boost::shared_mutex rw_mutex;
+    unsigned unblocked_count=0;
+    unsigned simultaneous_running_count=0;
+    unsigned max_simultaneous_running=0;
+    boost::mutex unblocked_count_mutex;
+    boost::condition_variable unblocked_condition;
+    boost::mutex finish_mutex;
+    boost::mutex::scoped_lock finish_lock(finish_mutex);
+    
+    try
+    {
+        
+        pool.create_thread(locking_thread<boost::shared_lock<boost::shared_mutex> >(rw_mutex,unblocked_count,unblocked_count_mutex,unblocked_condition,
+                                                                                    finish_mutex,simultaneous_running_count,max_simultaneous_running));
+        {
+            boost::mutex::scoped_lock lk(unblocked_count_mutex);
+            while(unblocked_count<1)
+            {
+                unblocked_condition.wait(lk);
+            }
+        }
+        CHECK_LOCKED_VALUE_EQUAL(unblocked_count_mutex,unblocked_count,1U);
+        pool.create_thread(locking_thread<boost::unique_lock<boost::shared_mutex> >(rw_mutex,unblocked_count,unblocked_count_mutex,unblocked_condition,
+                                                                                    finish_mutex,simultaneous_running_count,max_simultaneous_running));
+        boost::thread::sleep(delay(1));
+        CHECK_LOCKED_VALUE_EQUAL(unblocked_count_mutex,unblocked_count,1U);
+
+        finish_lock.unlock();
+
+        pool.join_all();
+    }
+    catch(...)
+    {
+        pool.interrupt_all();
+        pool.join_all();
+        throw;
+    }
+
+    CHECK_LOCKED_VALUE_EQUAL(unblocked_count_mutex,unblocked_count,2U);
+    CHECK_LOCKED_VALUE_EQUAL(unblocked_count_mutex,max_simultaneous_running,1u);
+}
+
+void test_unlocking_writer_unblocks_all_readers()
+{
+    boost::thread_group pool;
+
+    boost::shared_mutex rw_mutex;
+    boost::unique_lock<boost::shared_mutex>  write_lock(rw_mutex);
+    unsigned unblocked_count=0;
+    unsigned simultaneous_running_count=0;
+    unsigned max_simultaneous_running=0;
+    boost::mutex unblocked_count_mutex;
+    boost::condition_variable unblocked_condition;
+    boost::mutex finish_mutex;
+    boost::mutex::scoped_lock finish_lock(finish_mutex);
+
+    unsigned const reader_count=10;
+
+    try
+    {
+        for(unsigned i=0;i<reader_count;++i)
+        {
+            pool.create_thread(locking_thread<boost::shared_lock<boost::shared_mutex> >(rw_mutex,unblocked_count,unblocked_count_mutex,unblocked_condition,
+                                                                                        finish_mutex,simultaneous_running_count,max_simultaneous_running));
+        }
+        boost::thread::sleep(delay(1));
+        CHECK_LOCKED_VALUE_EQUAL(unblocked_count_mutex,unblocked_count,0U);
+
+        write_lock.unlock();
+    
+        {
+            boost::mutex::scoped_lock lk(unblocked_count_mutex);
+            while(unblocked_count<reader_count)
+            {
+                unblocked_condition.wait(lk);
+            }
+        }
+
+        CHECK_LOCKED_VALUE_EQUAL(unblocked_count_mutex,unblocked_count,reader_count);
+
+        finish_lock.unlock();
+        pool.join_all();
+    }
+    catch(...)
+    {
+        pool.interrupt_all();
+        pool.join_all();
+        throw;
+    }
+
+    CHECK_LOCKED_VALUE_EQUAL(unblocked_count_mutex,max_simultaneous_running,reader_count);
+}
+
+void test_unlocking_last_reader_only_unblocks_one_writer()
+{
+    boost::thread_group pool;
+
+    boost::shared_mutex rw_mutex;
+    unsigned unblocked_count=0;
+    unsigned simultaneous_running_readers=0;
+    unsigned max_simultaneous_readers=0;
+    unsigned simultaneous_running_writers=0;
+    unsigned max_simultaneous_writers=0;
+    boost::mutex unblocked_count_mutex;
+    boost::condition_variable unblocked_condition;
+    boost::mutex finish_reading_mutex;
+    boost::mutex::scoped_lock finish_reading_lock(finish_reading_mutex);
+    boost::mutex finish_writing_mutex;
+    boost::mutex::scoped_lock finish_writing_lock(finish_writing_mutex);
+
+    unsigned const reader_count=10;
+    unsigned const writer_count=10;
+
+    try
+    {
+        for(unsigned i=0;i<reader_count;++i)
+        {
+            pool.create_thread(locking_thread<boost::shared_lock<boost::shared_mutex> >(rw_mutex,unblocked_count,unblocked_count_mutex,unblocked_condition,
+                                                                                        finish_reading_mutex,simultaneous_running_readers,max_simultaneous_readers));
+        }
+        boost::thread::sleep(delay(1));
+        for(unsigned i=0;i<writer_count;++i)
+        {
+            pool.create_thread(locking_thread<boost::unique_lock<boost::shared_mutex> >(rw_mutex,unblocked_count,unblocked_count_mutex,unblocked_condition,
+                                                                                        finish_writing_mutex,simultaneous_running_writers,max_simultaneous_writers));
+        }
+        {
+            boost::mutex::scoped_lock lk(unblocked_count_mutex);
+            while(unblocked_count<reader_count)
+            {
+                unblocked_condition.wait(lk);
+            }
+        }
+        boost::thread::sleep(delay(1));
+        CHECK_LOCKED_VALUE_EQUAL(unblocked_count_mutex,unblocked_count,reader_count);
+
+        finish_reading_lock.unlock();
+
+        {
+            boost::mutex::scoped_lock lk(unblocked_count_mutex);
+            while(unblocked_count<(reader_count+1))
+            {
+                unblocked_condition.wait(lk);
+            }
+        }
+        CHECK_LOCKED_VALUE_EQUAL(unblocked_count_mutex,unblocked_count,reader_count+1);
+
+        finish_writing_lock.unlock();
+        pool.join_all();
+    }
+    catch(...)
+    {
+        pool.interrupt_all();
+        pool.join_all();
+        throw;
+    }
+
+    CHECK_LOCKED_VALUE_EQUAL(unblocked_count_mutex,unblocked_count,reader_count+writer_count);
+    CHECK_LOCKED_VALUE_EQUAL(unblocked_count_mutex,max_simultaneous_readers,reader_count);
+    CHECK_LOCKED_VALUE_EQUAL(unblocked_count_mutex,max_simultaneous_writers,1u);
+}
+
+boost::unit_test_framework::test_suite* init_unit_test_suite(int, char*[])
+{
+    boost::unit_test_framework::test_suite* test =
+        BOOST_TEST_SUITE("Boost.Threads: shared_mutex test suite");
+
+    test->add(BOOST_TEST_CASE(&test_multiple_readers));
+    test->add(BOOST_TEST_CASE(&test_only_one_writer_permitted));
+    test->add(BOOST_TEST_CASE(&test_reader_blocks_writer));
+    test->add(BOOST_TEST_CASE(&test_unlocking_writer_unblocks_all_readers));
+    test->add(BOOST_TEST_CASE(&test_unlocking_last_reader_only_unblocks_one_writer));
+
+    return test;
+}
diff --git a/deal.II/contrib/boost/libs/thread/test/test_shared_mutex_part_2.cpp b/deal.II/contrib/boost/libs/thread/test/test_shared_mutex_part_2.cpp
new file mode 100644 (file)
index 0000000..ae38838
--- /dev/null
@@ -0,0 +1,290 @@
+// (C) Copyright 2006-7 Anthony Williams
+// 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/test/unit_test.hpp>
+#include <boost/thread/thread.hpp>
+#include <boost/thread/xtime.hpp>
+#include "util.inl"
+#include "shared_mutex_locking_thread.hpp"
+
+#define CHECK_LOCKED_VALUE_EQUAL(mutex_name,value,expected_value)    \
+    {                                                                \
+        boost::mutex::scoped_lock lock(mutex_name);                  \
+        BOOST_CHECK_EQUAL(value,expected_value);                     \
+    }
+
+class simple_upgrade_thread
+{
+    boost::shared_mutex& rwm;
+    boost::mutex& finish_mutex;
+    boost::mutex& unblocked_mutex;
+    unsigned& unblocked_count;
+        
+    void operator=(simple_upgrade_thread&);
+        
+public:
+    simple_upgrade_thread(boost::shared_mutex& rwm_,
+                          boost::mutex& finish_mutex_,
+                          boost::mutex& unblocked_mutex_,
+                          unsigned& unblocked_count_):
+        rwm(rwm_),finish_mutex(finish_mutex_),
+        unblocked_mutex(unblocked_mutex_),unblocked_count(unblocked_count_)
+    {}
+        
+    void operator()()
+    {
+        boost::upgrade_lock<boost::shared_mutex> lk(rwm);
+            
+        {
+            boost::mutex::scoped_lock ulk(unblocked_mutex);
+            ++unblocked_count;
+        }
+            
+        boost::mutex::scoped_lock flk(finish_mutex);
+    }
+};
+
+
+void test_only_one_upgrade_lock_permitted()
+{
+    unsigned const number_of_threads=10;
+    
+    boost::thread_group pool;
+
+    boost::shared_mutex rw_mutex;
+    unsigned unblocked_count=0;
+    unsigned simultaneous_running_count=0;
+    unsigned max_simultaneous_running=0;
+    boost::mutex unblocked_count_mutex;
+    boost::condition_variable unblocked_condition;
+    boost::mutex finish_mutex;
+    boost::mutex::scoped_lock finish_lock(finish_mutex);
+    
+    try
+    {
+        for(unsigned i=0;i<number_of_threads;++i)
+        {
+            pool.create_thread(locking_thread<boost::upgrade_lock<boost::shared_mutex> >(rw_mutex,unblocked_count,unblocked_count_mutex,unblocked_condition,
+                                                                                         finish_mutex,simultaneous_running_count,max_simultaneous_running));
+        }
+
+        boost::thread::sleep(delay(1));
+
+        CHECK_LOCKED_VALUE_EQUAL(unblocked_count_mutex,unblocked_count,1U);
+
+        finish_lock.unlock();
+
+        pool.join_all();
+    }
+    catch(...)
+    {
+        pool.interrupt_all();
+        pool.join_all();
+        throw;
+    }
+
+    CHECK_LOCKED_VALUE_EQUAL(unblocked_count_mutex,unblocked_count,number_of_threads);
+    CHECK_LOCKED_VALUE_EQUAL(unblocked_count_mutex,max_simultaneous_running,1u);
+}
+
+void test_can_lock_upgrade_if_currently_locked_shared()
+{
+    boost::thread_group pool;
+
+    boost::shared_mutex rw_mutex;
+    unsigned unblocked_count=0;
+    unsigned simultaneous_running_count=0;
+    unsigned max_simultaneous_running=0;
+    boost::mutex unblocked_count_mutex;
+    boost::condition_variable unblocked_condition;
+    boost::mutex finish_mutex;
+    boost::mutex::scoped_lock finish_lock(finish_mutex);
+
+    unsigned const reader_count=10;
+
+    try
+    {
+        for(unsigned i=0;i<reader_count;++i)
+        {
+            pool.create_thread(locking_thread<boost::shared_lock<boost::shared_mutex> >(rw_mutex,unblocked_count,unblocked_count_mutex,unblocked_condition,
+                                                                                        finish_mutex,simultaneous_running_count,max_simultaneous_running));
+        }
+        boost::thread::sleep(delay(1));
+        pool.create_thread(locking_thread<boost::upgrade_lock<boost::shared_mutex> >(rw_mutex,unblocked_count,unblocked_count_mutex,unblocked_condition,
+                                                                                     finish_mutex,simultaneous_running_count,max_simultaneous_running));
+        {
+            boost::mutex::scoped_lock lk(unblocked_count_mutex);
+            while(unblocked_count<(reader_count+1))
+            {
+                unblocked_condition.wait(lk);
+            }
+        }
+        CHECK_LOCKED_VALUE_EQUAL(unblocked_count_mutex,unblocked_count,reader_count+1);
+
+        finish_lock.unlock();
+        pool.join_all();
+    }
+    catch(...)
+    {
+        pool.interrupt_all();
+        pool.join_all();
+        throw;
+    }
+
+
+    CHECK_LOCKED_VALUE_EQUAL(unblocked_count_mutex,unblocked_count,reader_count+1);
+    CHECK_LOCKED_VALUE_EQUAL(unblocked_count_mutex,max_simultaneous_running,reader_count+1);
+}
+
+void test_if_other_thread_has_write_lock_try_lock_shared_returns_false()
+{
+
+    boost::shared_mutex rw_mutex;
+    boost::mutex finish_mutex;
+    boost::mutex unblocked_mutex;
+    unsigned unblocked_count=0;
+    boost::mutex::scoped_lock finish_lock(finish_mutex);
+    boost::thread writer(simple_writing_thread(rw_mutex,finish_mutex,unblocked_mutex,unblocked_count));
+    boost::this_thread::sleep(boost::posix_time::seconds(1));
+    CHECK_LOCKED_VALUE_EQUAL(unblocked_mutex,unblocked_count,1u);
+
+    bool const try_succeeded=rw_mutex.try_lock_shared();
+    BOOST_CHECK(!try_succeeded);
+    if(try_succeeded)
+    {
+        rw_mutex.unlock_shared();
+    }
+
+    finish_lock.unlock();
+    writer.join();
+}
+
+void test_if_other_thread_has_write_lock_try_lock_upgrade_returns_false()
+{
+
+    boost::shared_mutex rw_mutex;
+    boost::mutex finish_mutex;
+    boost::mutex unblocked_mutex;
+    unsigned unblocked_count=0;
+    boost::mutex::scoped_lock finish_lock(finish_mutex);
+    boost::thread writer(simple_writing_thread(rw_mutex,finish_mutex,unblocked_mutex,unblocked_count));
+    boost::this_thread::sleep(boost::posix_time::seconds(1));
+    CHECK_LOCKED_VALUE_EQUAL(unblocked_mutex,unblocked_count,1u);
+
+    bool const try_succeeded=rw_mutex.try_lock_upgrade();
+    BOOST_CHECK(!try_succeeded);
+    if(try_succeeded)
+    {
+        rw_mutex.unlock_upgrade();
+    }
+
+    finish_lock.unlock();
+    writer.join();
+}
+
+void test_if_no_thread_has_lock_try_lock_shared_returns_true()
+{
+    boost::shared_mutex rw_mutex;
+    bool const try_succeeded=rw_mutex.try_lock_shared();
+    BOOST_CHECK(try_succeeded);
+    if(try_succeeded)
+    {
+        rw_mutex.unlock_shared();
+    }
+}
+
+void test_if_no_thread_has_lock_try_lock_upgrade_returns_true()
+{
+    boost::shared_mutex rw_mutex;
+    bool const try_succeeded=rw_mutex.try_lock_upgrade();
+    BOOST_CHECK(try_succeeded);
+    if(try_succeeded)
+    {
+        rw_mutex.unlock_upgrade();
+    }
+}
+
+void test_if_other_thread_has_shared_lock_try_lock_shared_returns_true()
+{
+
+    boost::shared_mutex rw_mutex;
+    boost::mutex finish_mutex;
+    boost::mutex unblocked_mutex;
+    unsigned unblocked_count=0;
+    boost::mutex::scoped_lock finish_lock(finish_mutex);
+    boost::thread writer(simple_reading_thread(rw_mutex,finish_mutex,unblocked_mutex,unblocked_count));
+    boost::thread::sleep(delay(1));
+    CHECK_LOCKED_VALUE_EQUAL(unblocked_mutex,unblocked_count,1u);
+
+    bool const try_succeeded=rw_mutex.try_lock_shared();
+    BOOST_CHECK(try_succeeded);
+    if(try_succeeded)
+    {
+        rw_mutex.unlock_shared();
+    }
+
+    finish_lock.unlock();
+    writer.join();
+}
+
+void test_if_other_thread_has_shared_lock_try_lock_upgrade_returns_true()
+{
+
+    boost::shared_mutex rw_mutex;
+    boost::mutex finish_mutex;
+    boost::mutex unblocked_mutex;
+    unsigned unblocked_count=0;
+    boost::mutex::scoped_lock finish_lock(finish_mutex);
+    boost::thread writer(simple_reading_thread(rw_mutex,finish_mutex,unblocked_mutex,unblocked_count));
+    boost::thread::sleep(delay(1));
+    CHECK_LOCKED_VALUE_EQUAL(unblocked_mutex,unblocked_count,1u);
+
+    bool const try_succeeded=rw_mutex.try_lock_upgrade();
+    BOOST_CHECK(try_succeeded);
+    if(try_succeeded)
+    {
+        rw_mutex.unlock_upgrade();
+    }
+
+    finish_lock.unlock();
+    writer.join();
+}
+
+void test_if_other_thread_has_upgrade_lock_try_lock_upgrade_returns_false()
+{
+
+    boost::shared_mutex rw_mutex;
+    boost::mutex finish_mutex;
+    boost::mutex unblocked_mutex;
+    unsigned unblocked_count=0;
+    boost::mutex::scoped_lock finish_lock(finish_mutex);
+    boost::thread writer(simple_upgrade_thread(rw_mutex,finish_mutex,unblocked_mutex,unblocked_count));
+    boost::this_thread::sleep(boost::posix_time::seconds(1));
+    CHECK_LOCKED_VALUE_EQUAL(unblocked_mutex,unblocked_count,1u);
+
+    bool const try_succeeded=rw_mutex.try_lock_upgrade();
+    BOOST_CHECK(!try_succeeded);
+    if(try_succeeded)
+    {
+        rw_mutex.unlock_upgrade();
+    }
+
+    finish_lock.unlock();
+    writer.join();
+}
+
+boost::unit_test_framework::test_suite* init_unit_test_suite(int, char*[])
+{
+    boost::unit_test_framework::test_suite* test =
+        BOOST_TEST_SUITE("Boost.Threads: shared_mutex test suite");
+
+    test->add(BOOST_TEST_CASE(&test_only_one_upgrade_lock_permitted));
+    test->add(BOOST_TEST_CASE(&test_can_lock_upgrade_if_currently_locked_shared));
+    test->add(BOOST_TEST_CASE(&test_if_other_thread_has_write_lock_try_lock_shared_returns_false));
+    test->add(BOOST_TEST_CASE(&test_if_no_thread_has_lock_try_lock_shared_returns_true));
+    test->add(BOOST_TEST_CASE(&test_if_other_thread_has_shared_lock_try_lock_shared_returns_true));
+
+    return test;
+}
diff --git a/deal.II/contrib/boost/libs/thread/test/test_shared_mutex_timed_locks.cpp b/deal.II/contrib/boost/libs/thread/test/test_shared_mutex_timed_locks.cpp
new file mode 100644 (file)
index 0000000..04efbc9
--- /dev/null
@@ -0,0 +1,268 @@
+// (C) Copyright 2006-7 Anthony Williams
+// 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/test/unit_test.hpp>
+#include <boost/thread/thread.hpp>
+#include <boost/thread/xtime.hpp>
+#include "util.inl"
+#include "shared_mutex_locking_thread.hpp"
+
+#define CHECK_LOCKED_VALUE_EQUAL(mutex_name,value,expected_value)    \
+    {                                                                \
+        boost::mutex::scoped_lock lock(mutex_name);                  \
+        BOOST_CHECK_EQUAL(value,expected_value);                     \
+    }
+
+
+void test_timed_lock_shared_times_out_if_write_lock_held()
+{
+    boost::shared_mutex rw_mutex;
+    boost::mutex finish_mutex;
+    boost::mutex unblocked_mutex;
+    unsigned unblocked_count=0;
+    boost::mutex::scoped_lock finish_lock(finish_mutex);
+    boost::thread writer(simple_writing_thread(rw_mutex,finish_mutex,unblocked_mutex,unblocked_count));
+    boost::thread::sleep(delay(1));
+    CHECK_LOCKED_VALUE_EQUAL(unblocked_mutex,unblocked_count,1u);
+
+    boost::system_time const start=boost::get_system_time();
+    boost::system_time const timeout=start+boost::posix_time::milliseconds(500);
+    boost::posix_time::milliseconds const timeout_resolution(50);
+    bool timed_lock_succeeded=rw_mutex.timed_lock_shared(timeout);
+    BOOST_CHECK((timeout-timeout_resolution)<boost::get_system_time());
+    BOOST_CHECK(!timed_lock_succeeded);
+    if(timed_lock_succeeded)
+    {
+        rw_mutex.unlock_shared();
+    }
+
+    boost::posix_time::milliseconds const wait_duration(500);
+    boost::system_time const timeout2=boost::get_system_time()+wait_duration;
+    timed_lock_succeeded=rw_mutex.timed_lock_shared(wait_duration);
+    BOOST_CHECK((timeout2-timeout_resolution)<boost::get_system_time());
+    BOOST_CHECK(!timed_lock_succeeded);
+    if(timed_lock_succeeded)
+    {
+        rw_mutex.unlock_shared();
+    }
+
+    finish_lock.unlock();
+    writer.join();
+}
+
+void test_timed_lock_shared_succeeds_if_no_lock_held()
+{
+    boost::shared_mutex rw_mutex;
+    boost::mutex finish_mutex;
+    boost::mutex unblocked_mutex;
+
+    boost::system_time const start=boost::get_system_time();
+    boost::system_time const timeout=start+boost::posix_time::milliseconds(500);
+    boost::posix_time::milliseconds const timeout_resolution(50);
+    bool timed_lock_succeeded=rw_mutex.timed_lock_shared(timeout);
+    BOOST_CHECK(boost::get_system_time()<timeout);
+    BOOST_CHECK(timed_lock_succeeded);
+    if(timed_lock_succeeded)
+    {
+        rw_mutex.unlock_shared();
+    }
+
+    boost::posix_time::milliseconds const wait_duration(500);
+    boost::system_time const timeout2=boost::get_system_time()+wait_duration;
+    timed_lock_succeeded=rw_mutex.timed_lock_shared(wait_duration);
+    BOOST_CHECK(boost::get_system_time()<timeout2);
+    BOOST_CHECK(timed_lock_succeeded);
+    if(timed_lock_succeeded)
+    {
+        rw_mutex.unlock_shared();
+    }
+
+}
+
+void test_timed_lock_shared_succeeds_if_read_lock_held()
+{
+    boost::shared_mutex rw_mutex;
+    boost::mutex finish_mutex;
+    boost::mutex unblocked_mutex;
+    unsigned unblocked_count=0;
+    boost::mutex::scoped_lock finish_lock(finish_mutex);
+    boost::thread reader(simple_reading_thread(rw_mutex,finish_mutex,unblocked_mutex,unblocked_count));
+    boost::thread::sleep(delay(1));
+    CHECK_LOCKED_VALUE_EQUAL(unblocked_mutex,unblocked_count,1u);
+
+    boost::system_time const start=boost::get_system_time();
+    boost::system_time const timeout=start+boost::posix_time::milliseconds(500);
+    boost::posix_time::milliseconds const timeout_resolution(50);
+    bool timed_lock_succeeded=rw_mutex.timed_lock_shared(timeout);
+    BOOST_CHECK(boost::get_system_time()<timeout);
+    BOOST_CHECK(timed_lock_succeeded);
+    if(timed_lock_succeeded)
+    {
+        rw_mutex.unlock_shared();
+    }
+
+    boost::posix_time::milliseconds const wait_duration(500);
+    boost::system_time const timeout2=boost::get_system_time()+wait_duration;
+    timed_lock_succeeded=rw_mutex.timed_lock_shared(wait_duration);
+    BOOST_CHECK(boost::get_system_time()<timeout2);
+    BOOST_CHECK(timed_lock_succeeded);
+    if(timed_lock_succeeded)
+    {
+        rw_mutex.unlock_shared();
+    }
+
+    finish_lock.unlock();
+    reader.join();
+}
+
+void test_timed_lock_times_out_if_write_lock_held()
+{
+    boost::shared_mutex rw_mutex;
+    boost::mutex finish_mutex;
+    boost::mutex unblocked_mutex;
+    unsigned unblocked_count=0;
+    boost::mutex::scoped_lock finish_lock(finish_mutex);
+    boost::thread writer(simple_writing_thread(rw_mutex,finish_mutex,unblocked_mutex,unblocked_count));
+    boost::thread::sleep(delay(1));
+    CHECK_LOCKED_VALUE_EQUAL(unblocked_mutex,unblocked_count,1u);
+
+    boost::system_time const start=boost::get_system_time();
+    boost::system_time const timeout=start+boost::posix_time::milliseconds(500);
+    boost::posix_time::milliseconds const timeout_resolution(50);
+    bool timed_lock_succeeded=rw_mutex.timed_lock(timeout);
+    BOOST_CHECK((timeout-timeout_resolution)<boost::get_system_time());
+    BOOST_CHECK(!timed_lock_succeeded);
+    if(timed_lock_succeeded)
+    {
+        rw_mutex.unlock();
+    }
+
+    boost::posix_time::milliseconds const wait_duration(500);
+    boost::system_time const timeout2=boost::get_system_time()+wait_duration;
+    timed_lock_succeeded=rw_mutex.timed_lock(wait_duration);
+    BOOST_CHECK((timeout2-timeout_resolution)<boost::get_system_time());
+    BOOST_CHECK(!timed_lock_succeeded);
+    if(timed_lock_succeeded)
+    {
+        rw_mutex.unlock();
+    }
+
+    finish_lock.unlock();
+    writer.join();
+}
+
+void test_timed_lock_succeeds_if_no_lock_held()
+{
+    boost::shared_mutex rw_mutex;
+    boost::mutex finish_mutex;
+    boost::mutex unblocked_mutex;
+
+    boost::system_time const start=boost::get_system_time();
+    boost::system_time const timeout=start+boost::posix_time::milliseconds(500);
+    boost::posix_time::milliseconds const timeout_resolution(50);
+    bool timed_lock_succeeded=rw_mutex.timed_lock(timeout);
+    BOOST_CHECK(boost::get_system_time()<timeout);
+    BOOST_CHECK(timed_lock_succeeded);
+    if(timed_lock_succeeded)
+    {
+        rw_mutex.unlock();
+    }
+
+    boost::posix_time::milliseconds const wait_duration(500);
+    boost::system_time const timeout2=boost::get_system_time()+wait_duration;
+    timed_lock_succeeded=rw_mutex.timed_lock(wait_duration);
+    BOOST_CHECK(boost::get_system_time()<timeout2);
+    BOOST_CHECK(timed_lock_succeeded);
+    if(timed_lock_succeeded)
+    {
+        rw_mutex.unlock();
+    }
+
+}
+
+void test_timed_lock_times_out_if_read_lock_held()
+{
+    boost::shared_mutex rw_mutex;
+    boost::mutex finish_mutex;
+    boost::mutex unblocked_mutex;
+    unsigned unblocked_count=0;
+    boost::mutex::scoped_lock finish_lock(finish_mutex);
+    boost::thread reader(simple_reading_thread(rw_mutex,finish_mutex,unblocked_mutex,unblocked_count));
+    boost::thread::sleep(delay(1));
+    CHECK_LOCKED_VALUE_EQUAL(unblocked_mutex,unblocked_count,1u);
+
+    boost::system_time const start=boost::get_system_time();
+    boost::system_time const timeout=start+boost::posix_time::milliseconds(500);
+    boost::posix_time::milliseconds const timeout_resolution(50);
+    bool timed_lock_succeeded=rw_mutex.timed_lock(timeout);
+    BOOST_CHECK((timeout-timeout_resolution)<boost::get_system_time());
+    BOOST_CHECK(!timed_lock_succeeded);
+    if(timed_lock_succeeded)
+    {
+        rw_mutex.unlock();
+    }
+
+    boost::posix_time::milliseconds const wait_duration(500);
+    boost::system_time const timeout2=boost::get_system_time()+wait_duration;
+    timed_lock_succeeded=rw_mutex.timed_lock(wait_duration);
+    BOOST_CHECK((timeout2-timeout_resolution)<boost::get_system_time());
+    BOOST_CHECK(!timed_lock_succeeded);
+    if(timed_lock_succeeded)
+    {
+        rw_mutex.unlock();
+    }
+
+    finish_lock.unlock();
+    reader.join();
+}
+
+void test_timed_lock_times_out_but_read_lock_succeeds_if_read_lock_held()
+{
+    boost::shared_mutex rw_mutex;
+    boost::mutex finish_mutex;
+    boost::mutex unblocked_mutex;
+    unsigned unblocked_count=0;
+    boost::mutex::scoped_lock finish_lock(finish_mutex);
+    boost::thread reader(simple_reading_thread(rw_mutex,finish_mutex,unblocked_mutex,unblocked_count));
+    boost::this_thread::sleep(boost::posix_time::seconds(1));
+    CHECK_LOCKED_VALUE_EQUAL(unblocked_mutex,unblocked_count,1u);
+
+    boost::system_time const start=boost::get_system_time();
+    boost::system_time const timeout=start+boost::posix_time::milliseconds(500);
+    bool timed_lock_succeeded=rw_mutex.timed_lock(timeout);
+    BOOST_CHECK(!timed_lock_succeeded);
+    if(timed_lock_succeeded)
+    {
+        rw_mutex.unlock();
+    }
+    
+    boost::posix_time::milliseconds const wait_duration(500);
+    timed_lock_succeeded=rw_mutex.timed_lock_shared(wait_duration);
+    BOOST_CHECK(timed_lock_succeeded);
+    if(timed_lock_succeeded)
+    {
+        rw_mutex.unlock_shared();
+    }
+
+    finish_lock.unlock();
+    reader.join();
+}
+
+
+boost::unit_test_framework::test_suite* init_unit_test_suite(int, char*[])
+{
+    boost::unit_test_framework::test_suite* test =
+        BOOST_TEST_SUITE("Boost.Threads: shared_mutex test suite");
+
+    test->add(BOOST_TEST_CASE(&test_timed_lock_shared_times_out_if_write_lock_held));
+    test->add(BOOST_TEST_CASE(&test_timed_lock_shared_succeeds_if_no_lock_held));
+    test->add(BOOST_TEST_CASE(&test_timed_lock_shared_succeeds_if_read_lock_held));
+    test->add(BOOST_TEST_CASE(&test_timed_lock_times_out_if_write_lock_held));
+    test->add(BOOST_TEST_CASE(&test_timed_lock_times_out_if_read_lock_held));
+    test->add(BOOST_TEST_CASE(&test_timed_lock_succeeds_if_no_lock_held));
+    test->add(BOOST_TEST_CASE(&test_timed_lock_times_out_but_read_lock_succeeds_if_read_lock_held));
+
+    return test;
+}
diff --git a/deal.II/contrib/boost/libs/thread/test/test_thread.cpp b/deal.II/contrib/boost/libs/thread/test/test_thread.cpp
new file mode 100644 (file)
index 0000000..480e258
--- /dev/null
@@ -0,0 +1,234 @@
+// Copyright (C) 2001-2003
+// William E. Kempf
+// Copyright (C) 2008 Anthony Williams
+//
+//  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/thread/detail/config.hpp>
+
+#include <boost/thread/thread.hpp>
+#include <boost/thread/xtime.hpp>
+#include <boost/bind.hpp>
+#include <boost/ref.hpp>
+#include <boost/utility.hpp>
+
+#include <boost/test/unit_test.hpp>
+
+#define DEFAULT_EXECUTION_MONITOR_TYPE execution_monitor::use_sleep_only
+#include <libs/thread/test/util.inl>
+
+int test_value;
+
+void simple_thread()
+{
+    test_value = 999;
+}
+
+void comparison_thread(boost::thread::id parent)
+{
+    boost::thread::id const my_id=boost::this_thread::get_id();
+    
+    BOOST_CHECK(my_id != parent);
+    boost::thread::id const my_id2=boost::this_thread::get_id();
+    BOOST_CHECK(my_id == my_id2);
+
+    boost::thread::id const no_thread_id=boost::thread::id();
+    BOOST_CHECK(my_id != no_thread_id);
+}
+
+void test_sleep()
+{
+    boost::xtime xt = delay(3);
+    boost::thread::sleep(xt);
+
+    // Ensure it's in a range instead of checking actual equality due to time
+    // lapse
+    BOOST_CHECK(in_range(xt, 2));
+}
+
+void do_test_creation()
+{
+    test_value = 0;
+    boost::thread thrd(&simple_thread);
+    thrd.join();
+    BOOST_CHECK_EQUAL(test_value, 999);
+}
+
+void test_creation()
+{
+    timed_test(&do_test_creation, 1);
+}
+
+void do_test_id_comparison()
+{
+    boost::thread::id const self=boost::this_thread::get_id();
+    boost::thread thrd(boost::bind(&comparison_thread, self));
+    thrd.join();
+}
+
+void test_id_comparison()
+{
+    timed_test(&do_test_id_comparison, 1);
+}
+
+void interruption_point_thread(boost::mutex* m,bool* failed)
+{
+    boost::mutex::scoped_lock lk(*m);
+    boost::this_thread::interruption_point();
+    *failed=true;
+}
+
+void do_test_thread_interrupts_at_interruption_point()
+{
+    boost::mutex m;
+    bool failed=false;
+    boost::mutex::scoped_lock lk(m);
+    boost::thread thrd(boost::bind(&interruption_point_thread,&m,&failed));
+    thrd.interrupt();
+    lk.unlock();
+    thrd.join();
+    BOOST_CHECK(!failed);
+}
+
+void test_thread_interrupts_at_interruption_point()
+{
+    timed_test(&do_test_thread_interrupts_at_interruption_point, 1);
+}
+
+void disabled_interruption_point_thread(boost::mutex* m,bool* failed)
+{
+    boost::mutex::scoped_lock lk(*m);
+    boost::this_thread::disable_interruption dc;
+    boost::this_thread::interruption_point();
+    *failed=false;
+}
+
+void do_test_thread_no_interrupt_if_interrupts_disabled_at_interruption_point()
+{
+    boost::mutex m;
+    bool failed=true;
+    boost::mutex::scoped_lock lk(m);
+    boost::thread thrd(boost::bind(&disabled_interruption_point_thread,&m,&failed));
+    thrd.interrupt();
+    lk.unlock();
+    thrd.join();
+    BOOST_CHECK(!failed);
+}
+
+void test_thread_no_interrupt_if_interrupts_disabled_at_interruption_point()
+{
+    timed_test(&do_test_thread_no_interrupt_if_interrupts_disabled_at_interruption_point, 1);
+}
+
+struct non_copyable_functor:
+    boost::noncopyable
+{
+    unsigned value;
+    
+    non_copyable_functor():
+        value(0)
+    {}
+    
+    void operator()()
+    {
+        value=999;
+    }
+};
+
+void do_test_creation_through_reference_wrapper()
+{
+    non_copyable_functor f;
+    
+    boost::thread thrd(boost::ref(f));
+    thrd.join();
+    BOOST_CHECK_EQUAL(f.value, 999u);
+}
+
+void test_creation_through_reference_wrapper()
+{
+    timed_test(&do_test_creation_through_reference_wrapper, 1);
+}
+
+struct long_running_thread
+{
+    boost::condition_variable cond;
+    boost::mutex mut;
+    bool done;
+    
+    long_running_thread():
+        done(false)
+    {}
+    
+    void operator()()
+    {
+        boost::mutex::scoped_lock lk(mut);
+        while(!done)
+        {
+            cond.wait(lk);
+        }
+    }
+};
+
+void do_test_timed_join()
+{
+    long_running_thread f;
+    boost::thread thrd(boost::ref(f));
+    BOOST_CHECK(thrd.joinable());
+    boost::system_time xt=delay(3);
+    bool const joined=thrd.timed_join(xt);
+    BOOST_CHECK(in_range(boost::get_xtime(xt), 2));
+    BOOST_CHECK(!joined);
+    BOOST_CHECK(thrd.joinable());
+    {
+        boost::mutex::scoped_lock lk(f.mut);
+        f.done=true;
+        f.cond.notify_one();
+    }
+    
+    xt=delay(3);
+    bool const joined2=thrd.timed_join(xt);
+    boost::system_time const now=boost::get_system_time();
+    BOOST_CHECK(xt>now);
+    BOOST_CHECK(joined2);
+    BOOST_CHECK(!thrd.joinable());
+}
+
+void test_timed_join()
+{
+    timed_test(&do_test_timed_join, 10);
+}
+
+void test_swap()
+{
+    boost::thread t(simple_thread);
+    boost::thread t2(simple_thread);
+    boost::thread::id id1=t.get_id();
+    boost::thread::id id2=t2.get_id();
+
+    t.swap(t2);
+    BOOST_CHECK(t.get_id()==id2);
+    BOOST_CHECK(t2.get_id()==id1);
+    
+    swap(t,t2);
+    BOOST_CHECK(t.get_id()==id1);
+    BOOST_CHECK(t2.get_id()==id2);
+}
+
+
+boost::unit_test_framework::test_suite* init_unit_test_suite(int, char*[])
+{
+    boost::unit_test_framework::test_suite* test =
+        BOOST_TEST_SUITE("Boost.Threads: thread test suite");
+
+    test->add(BOOST_TEST_CASE(test_sleep));
+    test->add(BOOST_TEST_CASE(test_creation));
+    test->add(BOOST_TEST_CASE(test_id_comparison));
+    test->add(BOOST_TEST_CASE(test_thread_interrupts_at_interruption_point));
+    test->add(BOOST_TEST_CASE(test_thread_no_interrupt_if_interrupts_disabled_at_interruption_point));
+    test->add(BOOST_TEST_CASE(test_creation_through_reference_wrapper));
+    test->add(BOOST_TEST_CASE(test_timed_join));
+    test->add(BOOST_TEST_CASE(test_swap));
+
+    return test;
+}
diff --git a/deal.II/contrib/boost/libs/thread/test/test_thread_id.cpp b/deal.II/contrib/boost/libs/thread/test/test_thread_id.cpp
new file mode 100644 (file)
index 0000000..777bc71
--- /dev/null
@@ -0,0 +1,149 @@
+// Copyright (C) 2007 Anthony Williams
+//
+//  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/thread/thread.hpp>
+#include <boost/test/unit_test.hpp>
+#include <boost/bind.hpp>
+
+void do_nothing()
+{}
+
+void test_thread_id_for_default_constructed_thread_is_default_constructed_id()
+{
+    boost::thread t;
+    BOOST_CHECK(t.get_id()==boost::thread::id());
+}
+
+void test_thread_id_for_running_thread_is_not_default_constructed_id()
+{
+    boost::thread t(do_nothing);
+    BOOST_CHECK(t.get_id()!=boost::thread::id());
+    t.join();
+}
+
+void test_different_threads_have_different_ids()
+{
+    boost::thread t(do_nothing);
+    boost::thread t2(do_nothing);
+    BOOST_CHECK(t.get_id()!=t2.get_id());
+    t.join();
+    t2.join();
+}
+
+void test_thread_ids_have_a_total_order()
+{
+    boost::thread t(do_nothing);
+    boost::thread t2(do_nothing);
+    boost::thread t3(do_nothing);
+    BOOST_CHECK(t.get_id()!=t2.get_id());
+    BOOST_CHECK(t.get_id()!=t3.get_id());
+    BOOST_CHECK(t2.get_id()!=t3.get_id());
+
+    BOOST_CHECK((t.get_id()<t2.get_id()) != (t2.get_id()<t.get_id()));
+    BOOST_CHECK((t.get_id()<t3.get_id()) != (t3.get_id()<t.get_id()));
+    BOOST_CHECK((t2.get_id()<t3.get_id()) != (t3.get_id()<t2.get_id()));
+
+    BOOST_CHECK((t.get_id()>t2.get_id()) != (t2.get_id()>t.get_id()));
+    BOOST_CHECK((t.get_id()>t3.get_id()) != (t3.get_id()>t.get_id()));
+    BOOST_CHECK((t2.get_id()>t3.get_id()) != (t3.get_id()>t2.get_id()));
+
+    BOOST_CHECK((t.get_id()<t2.get_id()) == (t2.get_id()>t.get_id()));
+    BOOST_CHECK((t2.get_id()<t.get_id()) == (t.get_id()>t2.get_id()));
+    BOOST_CHECK((t.get_id()<t3.get_id()) == (t3.get_id()>t.get_id()));
+    BOOST_CHECK((t3.get_id()<t.get_id()) == (t.get_id()>t3.get_id()));
+    BOOST_CHECK((t2.get_id()<t3.get_id()) == (t3.get_id()>t2.get_id()));
+    BOOST_CHECK((t3.get_id()<t2.get_id()) == (t2.get_id()>t3.get_id()));
+
+    BOOST_CHECK((t.get_id()<t2.get_id()) == (t2.get_id()>=t.get_id()));
+    BOOST_CHECK((t2.get_id()<t.get_id()) == (t.get_id()>=t2.get_id()));
+    BOOST_CHECK((t.get_id()<t3.get_id()) == (t3.get_id()>=t.get_id()));
+    BOOST_CHECK((t3.get_id()<t.get_id()) == (t.get_id()>=t3.get_id()));
+    BOOST_CHECK((t2.get_id()<t3.get_id()) == (t3.get_id()>=t2.get_id()));
+    BOOST_CHECK((t3.get_id()<t2.get_id()) == (t2.get_id()>=t3.get_id()));
+    
+    BOOST_CHECK((t.get_id()<=t2.get_id()) == (t2.get_id()>t.get_id()));
+    BOOST_CHECK((t2.get_id()<=t.get_id()) == (t.get_id()>t2.get_id()));
+    BOOST_CHECK((t.get_id()<=t3.get_id()) == (t3.get_id()>t.get_id()));
+    BOOST_CHECK((t3.get_id()<=t.get_id()) == (t.get_id()>t3.get_id()));
+    BOOST_CHECK((t2.get_id()<=t3.get_id()) == (t3.get_id()>t2.get_id()));
+    BOOST_CHECK((t3.get_id()<=t2.get_id()) == (t2.get_id()>t3.get_id()));
+
+    if((t.get_id()<t2.get_id()) && (t2.get_id()<t3.get_id()))
+    {
+        BOOST_CHECK(t.get_id()<t3.get_id());
+    }
+    else if((t.get_id()<t3.get_id()) && (t3.get_id()<t2.get_id()))
+    {
+        BOOST_CHECK(t.get_id()<t2.get_id());
+    }
+    else if((t2.get_id()<t3.get_id()) && (t3.get_id()<t.get_id()))
+    {
+        BOOST_CHECK(t2.get_id()<t.get_id());
+    }
+    else if((t2.get_id()<t.get_id()) && (t.get_id()<t3.get_id()))
+    {
+        BOOST_CHECK(t2.get_id()<t3.get_id());
+    }
+    else if((t3.get_id()<t.get_id()) && (t.get_id()<t2.get_id()))
+    {
+        BOOST_CHECK(t3.get_id()<t2.get_id());
+    }
+    else if((t3.get_id()<t2.get_id()) && (t2.get_id()<t.get_id()))
+    {
+        BOOST_CHECK(t3.get_id()<t.get_id());
+    }
+    else
+    {
+        BOOST_CHECK(false);
+    }
+
+    boost::thread::id default_id;
+
+    BOOST_CHECK(default_id < t.get_id());
+    BOOST_CHECK(default_id < t2.get_id());
+    BOOST_CHECK(default_id < t3.get_id());
+
+    BOOST_CHECK(default_id <= t.get_id());
+    BOOST_CHECK(default_id <= t2.get_id());
+    BOOST_CHECK(default_id <= t3.get_id());
+
+    BOOST_CHECK(!(default_id > t.get_id()));
+    BOOST_CHECK(!(default_id > t2.get_id()));
+    BOOST_CHECK(!(default_id > t3.get_id()));
+    
+    BOOST_CHECK(!(default_id >= t.get_id()));
+    BOOST_CHECK(!(default_id >= t2.get_id()));
+    BOOST_CHECK(!(default_id >= t3.get_id()));
+
+    t.join();
+    t2.join();
+    t3.join();
+}
+    
+void get_thread_id(boost::thread::id* id)
+{
+    *id=boost::this_thread::get_id();
+}
+
+void test_thread_id_of_running_thread_returned_by_this_thread_get_id()
+{
+    boost::thread::id id;
+    boost::thread t(boost::bind(get_thread_id,&id));
+    boost::thread::id t_id=t.get_id();
+    t.join();
+    BOOST_CHECK(id==t_id);
+}
+
+boost::unit_test_framework::test_suite* init_unit_test_suite(int, char*[])
+{
+    boost::unit_test_framework::test_suite* test =
+        BOOST_TEST_SUITE("Boost.Threads: thread move test suite");
+
+    test->add(BOOST_TEST_CASE(test_thread_id_for_default_constructed_thread_is_default_constructed_id));
+    test->add(BOOST_TEST_CASE(test_thread_id_for_running_thread_is_not_default_constructed_id));
+    test->add(BOOST_TEST_CASE(test_different_threads_have_different_ids));
+    test->add(BOOST_TEST_CASE(test_thread_ids_have_a_total_order));
+    test->add(BOOST_TEST_CASE(test_thread_id_of_running_thread_returned_by_this_thread_get_id));
+    return test;
+}
diff --git a/deal.II/contrib/boost/libs/thread/test/test_thread_launching.cpp b/deal.II/contrib/boost/libs/thread/test/test_thread_launching.cpp
new file mode 100644 (file)
index 0000000..4582e65
--- /dev/null
@@ -0,0 +1,226 @@
+// Copyright (C) 2007-8 Anthony Williams
+//
+//  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/thread/thread.hpp>
+#include <boost/test/unit_test.hpp>
+#include <boost/ref.hpp>
+#include <boost/utility.hpp>
+#include <string>
+#include <vector>
+
+bool normal_function_called=false;
+
+void normal_function()
+{
+    normal_function_called=true;
+}
+
+void test_thread_function_no_arguments()
+{
+    boost::thread function(normal_function);
+    function.join();
+    BOOST_CHECK(normal_function_called);
+}
+
+int nfoa_res=0;
+
+void normal_function_one_arg(int i)
+{
+    nfoa_res=i;
+}
+
+void test_thread_function_one_argument()
+{
+    boost::thread function(normal_function_one_arg,42);
+    function.join();
+    BOOST_CHECK_EQUAL(42,nfoa_res);
+}
+
+struct callable_no_args
+{
+    static bool called;
+    
+    void operator()() const
+    {
+        called=true;
+    }
+};
+
+bool callable_no_args::called=false;
+
+void test_thread_callable_object_no_arguments()
+{
+    callable_no_args func;
+    boost::thread callable(func);
+    callable.join();
+    BOOST_CHECK(callable_no_args::called);
+}
+
+struct callable_noncopyable_no_args:
+    boost::noncopyable
+{
+    static bool called;
+    
+    void operator()() const
+    {
+        called=true;
+    }
+};
+
+bool callable_noncopyable_no_args::called=false;
+
+void test_thread_callable_object_ref_no_arguments()
+{
+    callable_noncopyable_no_args func;
+    
+    boost::thread callable(boost::ref(func));
+    callable.join();
+    BOOST_CHECK(callable_noncopyable_no_args::called);
+}
+
+struct callable_one_arg
+{
+    static bool called;
+    static int called_arg;
+    
+    void operator()(int arg) const
+    {
+        called=true;
+        called_arg=arg;
+    }
+};
+
+bool callable_one_arg::called=false;
+int callable_one_arg::called_arg=0;
+
+void test_thread_callable_object_one_argument()
+{
+    callable_one_arg func;
+    boost::thread callable(func,42);
+    callable.join();
+    BOOST_CHECK(callable_one_arg::called);
+    BOOST_CHECK_EQUAL(callable_one_arg::called_arg,42);
+}
+
+struct callable_multiple_arg
+{
+    static bool called_two;
+    static int called_two_arg1;
+    static double called_two_arg2;
+    static bool called_three;
+    static std::string called_three_arg1;
+    static std::vector<int> called_three_arg2;
+    static int called_three_arg3;
+    
+    void operator()(int arg1,double arg2) const
+    {
+        called_two=true;
+        called_two_arg1=arg1;
+        called_two_arg2=arg2;
+    }
+    void operator()(std::string const& arg1,std::vector<int> const& arg2,int arg3) const
+    {
+        called_three=true;
+        called_three_arg1=arg1;
+        called_three_arg2=arg2;
+        called_three_arg3=arg3;
+    }
+};
+
+bool callable_multiple_arg::called_two=false;
+bool callable_multiple_arg::called_three=false;
+int callable_multiple_arg::called_two_arg1;
+double callable_multiple_arg::called_two_arg2;
+std::string callable_multiple_arg::called_three_arg1;
+std::vector<int> callable_multiple_arg::called_three_arg2;
+int callable_multiple_arg::called_three_arg3;
+
+void test_thread_callable_object_multiple_arguments()
+{
+    std::vector<int> x;
+    for(unsigned i=0;i<7;++i)
+    {
+        x.push_back(i*i);
+    }
+
+    callable_multiple_arg func;
+    
+    boost::thread callable3(func,"hello",x,1.2);
+    callable3.join();
+    BOOST_CHECK(callable_multiple_arg::called_three);
+    BOOST_CHECK_EQUAL(callable_multiple_arg::called_three_arg1,"hello");
+    BOOST_CHECK_EQUAL(callable_multiple_arg::called_three_arg2.size(),x.size());
+    for(unsigned j=0;j<x.size();++j)
+    {
+        BOOST_CHECK_EQUAL(callable_multiple_arg::called_three_arg2.at(j),x[j]);
+    }
+    
+    BOOST_CHECK_EQUAL(callable_multiple_arg::called_three_arg3,1);
+
+    double const dbl=1.234;
+    
+    boost::thread callable2(func,19,dbl);
+    callable2.join();
+    BOOST_CHECK(callable_multiple_arg::called_two);
+    BOOST_CHECK_EQUAL(callable_multiple_arg::called_two_arg1,19);
+    BOOST_CHECK_EQUAL(callable_multiple_arg::called_two_arg2,dbl);
+}
+
+struct X
+{
+    bool function_called;
+    int arg_value;
+
+    X():
+        function_called(false),
+        arg_value(0)
+    {}
+    
+
+    void f0()
+    {
+        function_called=true;
+    }
+
+    void f1(int i)
+    {
+        arg_value=i;
+    }
+
+};
+
+void test_thread_member_function_no_arguments()
+{
+    X x;
+    
+    boost::thread function(&X::f0,&x);
+    function.join();
+    BOOST_CHECK(x.function_called);
+}
+
+
+void test_thread_member_function_one_argument()
+{
+    X x;
+    boost::thread function(&X::f1,&x,42);
+    function.join();
+    BOOST_CHECK_EQUAL(42,x.arg_value);
+}
+
+
+boost::unit_test_framework::test_suite* init_unit_test_suite(int, char*[])
+{
+    boost::unit_test_framework::test_suite* test =
+        BOOST_TEST_SUITE("Boost.Threads: thread launching test suite");
+
+    test->add(BOOST_TEST_CASE(test_thread_function_no_arguments));
+    test->add(BOOST_TEST_CASE(test_thread_function_one_argument));
+    test->add(BOOST_TEST_CASE(test_thread_callable_object_no_arguments));
+    test->add(BOOST_TEST_CASE(test_thread_callable_object_ref_no_arguments));
+    test->add(BOOST_TEST_CASE(test_thread_callable_object_one_argument));
+    test->add(BOOST_TEST_CASE(test_thread_callable_object_multiple_arguments));
+    test->add(BOOST_TEST_CASE(test_thread_member_function_no_arguments));
+    test->add(BOOST_TEST_CASE(test_thread_member_function_one_argument));
+    return test;
+}
diff --git a/deal.II/contrib/boost/libs/thread/test/test_thread_mf.cpp b/deal.II/contrib/boost/libs/thread/test/test_thread_mf.cpp
new file mode 100644 (file)
index 0000000..aa5a5dc
--- /dev/null
@@ -0,0 +1,134 @@
+//
+//  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/thread/thread.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+struct X
+{
+    mutable unsigned int hash;
+
+    X(): hash(0) {}
+
+    int f0() { f1(17); return 0; }
+    int g0() const { g1(17); return 0; }
+
+    int f1(int a1) { hash = (hash * 17041 + a1) % 32768; return 0; }
+    int g1(int a1) const { hash = (hash * 17041 + a1 * 2) % 32768; return 0; }
+
+    int f2(int a1, int a2) { f1(a1); f1(a2); return 0; }
+    int g2(int a1, int a2) const { g1(a1); g1(a2); return 0; }
+
+    int f3(int a1, int a2, int a3) { f2(a1, a2); f1(a3); return 0; }
+    int g3(int a1, int a2, int a3) const { g2(a1, a2); g1(a3); return 0; }
+
+    int f4(int a1, int a2, int a3, int a4) { f3(a1, a2, a3); f1(a4); return 0; }
+    int g4(int a1, int a2, int a3, int a4) const { g3(a1, a2, a3); g1(a4); return 0; }
+
+    int f5(int a1, int a2, int a3, int a4, int a5) { f4(a1, a2, a3, a4); f1(a5); return 0; }
+    int g5(int a1, int a2, int a3, int a4, int a5) const { g4(a1, a2, a3, a4); g1(a5); return 0; }
+
+    int f6(int a1, int a2, int a3, int a4, int a5, int a6) { f5(a1, a2, a3, a4, a5); f1(a6); return 0; }
+    int g6(int a1, int a2, int a3, int a4, int a5, int a6) const { g5(a1, a2, a3, a4, a5); g1(a6); return 0; }
+
+    int f7(int a1, int a2, int a3, int a4, int a5, int a6, int a7) { f6(a1, a2, a3, a4, a5, a6); f1(a7); return 0; }
+    int g7(int a1, int a2, int a3, int a4, int a5, int a6, int a7) const { g6(a1, a2, a3, a4, a5, a6); g1(a7); return 0; }
+
+    int f8(int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8) { f7(a1, a2, a3, a4, a5, a6, a7); f1(a8); return 0; }
+    int g8(int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8) const { g7(a1, a2, a3, a4, a5, a6, a7); g1(a8); return 0; }
+};
+
+int main()
+{
+    X x;
+
+    // 0
+
+    boost::thread( &X::f0, &x ).join();
+    boost::thread( &X::f0, boost::ref(x) ).join();
+
+    boost::thread( &X::g0, &x ).join();
+    boost::thread( &X::g0, x ).join();
+    boost::thread( &X::g0, boost::ref(x) ).join();
+
+    // 1
+
+    boost::thread( &X::f1, &x, 1 ).join();
+    boost::thread( &X::f1, boost::ref(x), 1 ).join();
+
+    boost::thread( &X::g1, &x, 1 ).join();
+    boost::thread( &X::g1, x, 1 ).join();
+    boost::thread( &X::g1, boost::ref(x), 1 ).join();
+
+    // 2
+
+    boost::thread( &X::f2, &x, 1, 2 ).join();
+    boost::thread( &X::f2, boost::ref(x), 1, 2 ).join();
+
+    boost::thread( &X::g2, &x, 1, 2 ).join();
+    boost::thread( &X::g2, x, 1, 2 ).join();
+    boost::thread( &X::g2, boost::ref(x), 1, 2 ).join();
+
+    // 3
+
+    boost::thread( &X::f3, &x, 1, 2, 3 ).join();
+    boost::thread( &X::f3, boost::ref(x), 1, 2, 3 ).join();
+
+    boost::thread( &X::g3, &x, 1, 2, 3 ).join();
+    boost::thread( &X::g3, x, 1, 2, 3 ).join();
+    boost::thread( &X::g3, boost::ref(x), 1, 2, 3 ).join();
+
+    // 4
+
+    boost::thread( &X::f4, &x, 1, 2, 3, 4 ).join();
+    boost::thread( &X::f4, boost::ref(x), 1, 2, 3, 4 ).join();
+
+    boost::thread( &X::g4, &x, 1, 2, 3, 4 ).join();
+    boost::thread( &X::g4, x, 1, 2, 3, 4 ).join();
+    boost::thread( &X::g4, boost::ref(x), 1, 2, 3, 4 ).join();
+
+    // 5
+
+    boost::thread( &X::f5, &x, 1, 2, 3, 4, 5 ).join();
+    boost::thread( &X::f5, boost::ref(x), 1, 2, 3, 4, 5 ).join();
+
+    boost::thread( &X::g5, &x, 1, 2, 3, 4, 5 ).join();
+    boost::thread( &X::g5, x, 1, 2, 3, 4, 5 ).join();
+    boost::thread( &X::g5, boost::ref(x), 1, 2, 3, 4, 5 ).join();
+
+    // 6
+
+    boost::thread( &X::f6, &x, 1, 2, 3, 4, 5, 6 ).join();
+    boost::thread( &X::f6, boost::ref(x), 1, 2, 3, 4, 5, 6 ).join();
+
+    boost::thread( &X::g6, &x, 1, 2, 3, 4, 5, 6 ).join();
+    boost::thread( &X::g6, x, 1, 2, 3, 4, 5, 6 ).join();
+    boost::thread( &X::g6, boost::ref(x), 1, 2, 3, 4, 5, 6 ).join();
+
+    // 7
+
+    boost::thread( &X::f7, &x, 1, 2, 3, 4, 5, 6, 7).join();
+    boost::thread( &X::f7, boost::ref(x), 1, 2, 3, 4, 5, 6, 7).join();
+
+    boost::thread( &X::g7, &x, 1, 2, 3, 4, 5, 6, 7).join();
+    boost::thread( &X::g7, x, 1, 2, 3, 4, 5, 6, 7).join();
+    boost::thread( &X::g7, boost::ref(x), 1, 2, 3, 4, 5, 6, 7).join();
+
+    // 8
+
+    boost::thread( &X::f8, &x, 1, 2, 3, 4, 5, 6, 7, 8 ).join();
+    boost::thread( &X::f8, boost::ref(x), 1, 2, 3, 4, 5, 6, 7, 8 ).join();
+
+    boost::thread( &X::g8, &x, 1, 2, 3, 4, 5, 6, 7, 8 ).join();
+    boost::thread( &X::g8, x, 1, 2, 3, 4, 5, 6, 7, 8 ).join();
+    boost::thread( &X::g8, boost::ref(x), 1, 2, 3, 4, 5, 6, 7, 8 ).join();
+
+    BOOST_TEST( x.hash == 23558 );
+
+    return boost::report_errors();
+}
diff --git a/deal.II/contrib/boost/libs/thread/test/test_thread_move.cpp b/deal.II/contrib/boost/libs/thread/test/test_thread_move.cpp
new file mode 100644 (file)
index 0000000..550b62d
--- /dev/null
@@ -0,0 +1,72 @@
+// Copyright (C) 2007 Anthony Williams
+//
+//  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/thread/thread.hpp>
+#include <boost/test/unit_test.hpp>
+
+void do_nothing(boost::thread::id* my_id)
+{
+    *my_id=boost::this_thread::get_id();
+}
+
+void test_move_on_construction()
+{
+    boost::thread::id the_id;
+    boost::thread x=boost::thread(do_nothing,&the_id);
+    boost::thread::id x_id=x.get_id();
+    x.join();
+    BOOST_CHECK_EQUAL(the_id,x_id);
+}
+
+boost::thread make_thread(boost::thread::id* the_id)
+{
+    return boost::thread(do_nothing,the_id);
+}
+
+void test_move_from_function_return()
+{
+    boost::thread::id the_id;
+    boost::thread x=make_thread(&the_id);
+    boost::thread::id x_id=x.get_id();
+    x.join();
+    BOOST_CHECK_EQUAL(the_id,x_id);
+}
+
+boost::thread make_thread_return_lvalue(boost::thread::id* the_id)
+{
+    boost::thread t(do_nothing,the_id);
+    return boost::move(t);
+}
+
+void test_move_from_function_return_lvalue()
+{
+    boost::thread::id the_id;
+    boost::thread x=make_thread_return_lvalue(&the_id);
+    boost::thread::id x_id=x.get_id();
+    x.join();
+    BOOST_CHECK_EQUAL(the_id,x_id);
+}
+
+void test_move_assign()
+{
+    boost::thread::id the_id;
+    boost::thread x(do_nothing,&the_id);
+    boost::thread y;
+    y=boost::move(x);
+    boost::thread::id y_id=y.get_id();
+    y.join();
+    BOOST_CHECK_EQUAL(the_id,y_id);
+}
+
+boost::unit_test_framework::test_suite* init_unit_test_suite(int, char*[])
+{
+    boost::unit_test_framework::test_suite* test =
+        BOOST_TEST_SUITE("Boost.Threads: thread move test suite");
+
+    test->add(BOOST_TEST_CASE(test_move_on_construction));
+    test->add(BOOST_TEST_CASE(test_move_from_function_return));
+    test->add(BOOST_TEST_CASE(test_move_from_function_return_lvalue));
+    test->add(BOOST_TEST_CASE(test_move_assign));
+    return test;
+}
diff --git a/deal.II/contrib/boost/libs/thread/test/test_tss.cpp b/deal.II/contrib/boost/libs/thread/test/test_tss.cpp
new file mode 100644 (file)
index 0000000..8a6545c
--- /dev/null
@@ -0,0 +1,324 @@
+// Copyright (C) 2001-2003
+// William E. Kempf
+// Copyright (C) 2007 Anthony Williams
+//
+//  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/thread/detail/config.hpp>
+
+#include <boost/thread/tss.hpp>
+#include <boost/thread/mutex.hpp>
+#include <boost/thread/thread.hpp>
+
+#include <boost/test/unit_test.hpp>
+
+#include <libs/thread/test/util.inl>
+
+#include <iostream>
+
+#if defined(BOOST_HAS_WINTHREADS)
+    #define WIN32_LEAN_AND_MEAN
+    #include <windows.h>    
+#endif
+
+boost::mutex check_mutex;
+boost::mutex tss_mutex;
+int tss_instances = 0;
+int tss_total = 0;
+
+struct tss_value_t
+{
+    tss_value_t()
+    {
+        boost::mutex::scoped_lock lock(tss_mutex);
+        ++tss_instances;
+        ++tss_total;
+        value = 0;
+    }
+    ~tss_value_t()
+    {
+        boost::mutex::scoped_lock lock(tss_mutex);
+        --tss_instances;
+    }
+    int value;
+};
+
+boost::thread_specific_ptr<tss_value_t> tss_value;
+
+void test_tss_thread()
+{
+    tss_value.reset(new tss_value_t());
+    for (int i=0; i<1000; ++i)
+    {
+        int& n = tss_value->value;
+        // Don't call BOOST_CHECK_EQUAL directly, as it doesn't appear to
+        // be thread safe. Must evaluate further.
+        if (n != i)
+        {
+            boost::mutex::scoped_lock lock(check_mutex);
+            BOOST_CHECK_EQUAL(n, i);
+        }
+        ++n;
+    }
+}
+
+#if defined(BOOST_THREAD_PLATFORM_WIN32)
+    typedef HANDLE native_thread_t;
+
+    DWORD WINAPI test_tss_thread_native(LPVOID /*lpParameter*/)
+    {
+        test_tss_thread();
+        return 0;
+    }
+
+    native_thread_t create_native_thread(void)
+    {
+        native_thread_t const res=CreateThread(
+            0, //security attributes (0 = not inheritable)
+            0, //stack size (0 = default) 
+            &test_tss_thread_native, //function to execute
+            0, //parameter to pass to function
+            0, //creation flags (0 = run immediately)
+            0  //thread id (0 = thread id not returned)
+            );
+        BOOST_CHECK(res!=0);
+        return res;
+    }
+
+    void join_native_thread(native_thread_t thread)
+    {
+        DWORD res = WaitForSingleObject(thread, INFINITE);
+        BOOST_CHECK(res == WAIT_OBJECT_0);
+
+        res = CloseHandle(thread);
+        BOOST_CHECK(SUCCEEDED(res));
+    }
+#elif defined(BOOST_THREAD_PLATFORM_PTHREAD)
+    typedef pthread_t native_thread_t;
+
+extern "C"
+{
+    void* test_tss_thread_native(void* lpParameter)
+    {
+        test_tss_thread();
+        return 0;
+    }
+}
+
+    native_thread_t create_native_thread()
+    {
+        native_thread_t thread_handle;
+        
+        int const res = pthread_create(&thread_handle, 0, &test_tss_thread_native, 0);
+        BOOST_CHECK(!res);
+        return thread_handle;
+    }
+
+    void join_native_thread(native_thread_t thread)
+    {
+        void* result=0;
+        int const res=pthread_join(thread,&result);
+        BOOST_CHECK(!res);
+    }
+#endif
+
+void do_test_tss()
+{
+    tss_instances = 0;
+    tss_total = 0;
+
+    const int NUMTHREADS=5;
+    boost::thread_group threads;
+    try
+    {
+        for (int i=0; i<NUMTHREADS; ++i)
+            threads.create_thread(&test_tss_thread);
+        threads.join_all();
+    }
+    catch(...)
+    {
+        threads.interrupt_all();
+        threads.join_all();
+        throw;
+    }
+
+
+    std::cout
+        << "tss_instances = " << tss_instances
+        << "; tss_total = " << tss_total
+        << "\n";
+    std::cout.flush();
+
+    BOOST_CHECK_EQUAL(tss_instances, 0);
+    BOOST_CHECK_EQUAL(tss_total, 5);
+
+    tss_instances = 0;
+    tss_total = 0;
+
+    native_thread_t thread1 = create_native_thread();
+    native_thread_t thread2 = create_native_thread();
+    native_thread_t thread3 = create_native_thread();
+    native_thread_t thread4 = create_native_thread();
+    native_thread_t thread5 = create_native_thread();
+
+    join_native_thread(thread5);
+    join_native_thread(thread4);
+    join_native_thread(thread3);
+    join_native_thread(thread2);
+    join_native_thread(thread1);
+
+    std::cout
+        << "tss_instances = " << tss_instances
+        << "; tss_total = " << tss_total
+        << "\n";
+    std::cout.flush();
+
+    // The following is not really an error. TSS cleanup support still is available for boost threads.
+    // Also this usually will be triggered only when bound to the static version of thread lib.
+    // 2006-10-02 Roland Schwarz
+    //BOOST_CHECK_EQUAL(tss_instances, 0);
+    BOOST_CHECK_MESSAGE(tss_instances == 0, "Support of automatic tss cleanup for native threading API not available");
+    BOOST_CHECK_EQUAL(tss_total, 5);
+}
+
+void test_tss()
+{
+    timed_test(&do_test_tss, 2);
+}
+
+bool tss_cleanup_called=false;
+
+struct Dummy
+{};
+
+void tss_custom_cleanup(Dummy* d)
+{
+    delete d;
+    tss_cleanup_called=true;
+}
+
+boost::thread_specific_ptr<Dummy> tss_with_cleanup(tss_custom_cleanup);
+
+void tss_thread_with_custom_cleanup()
+{
+    tss_with_cleanup.reset(new Dummy);
+}
+
+void do_test_tss_with_custom_cleanup()
+{
+    boost::thread t(tss_thread_with_custom_cleanup);
+    try
+    {
+        t.join();
+    }
+    catch(...)
+    {
+        t.interrupt();
+        t.join();
+        throw;
+    }
+
+    BOOST_CHECK(tss_cleanup_called);
+}
+
+
+void test_tss_with_custom_cleanup()
+{
+    timed_test(&do_test_tss_with_custom_cleanup, 2);
+}
+
+Dummy* tss_object=new Dummy;
+
+void tss_thread_with_custom_cleanup_and_release()
+{
+    tss_with_cleanup.reset(tss_object);
+    tss_with_cleanup.release();
+}
+
+void do_test_tss_does_no_cleanup_after_release()
+{
+    tss_cleanup_called=false;
+    boost::thread t(tss_thread_with_custom_cleanup_and_release);
+    try
+    {
+        t.join();
+    }
+    catch(...)
+    {
+        t.interrupt();
+        t.join();
+        throw;
+    }
+
+    BOOST_CHECK(!tss_cleanup_called);
+    if(!tss_cleanup_called)
+    {
+        delete tss_object;
+    }
+}
+
+struct dummy_class_tracks_deletions
+{
+    static unsigned deletions;
+    
+    ~dummy_class_tracks_deletions()
+    {
+        ++deletions;
+    }
+    
+};
+
+unsigned dummy_class_tracks_deletions::deletions=0;
+
+boost::thread_specific_ptr<dummy_class_tracks_deletions> tss_with_null_cleanup(NULL);
+
+void tss_thread_with_null_cleanup(dummy_class_tracks_deletions* delete_tracker)
+{
+    tss_with_null_cleanup.reset(delete_tracker);
+}
+
+void do_test_tss_does_no_cleanup_with_null_cleanup_function()
+{
+    dummy_class_tracks_deletions* delete_tracker=new dummy_class_tracks_deletions;
+    boost::thread t(tss_thread_with_null_cleanup,delete_tracker);
+    try
+    {
+        t.join();
+    }
+    catch(...)
+    {
+        t.interrupt();
+        t.join();
+        throw;
+    }
+
+    BOOST_CHECK(!dummy_class_tracks_deletions::deletions);
+    if(!dummy_class_tracks_deletions::deletions)
+    {
+        delete delete_tracker;
+    }
+}
+
+void test_tss_does_no_cleanup_after_release()
+{
+    timed_test(&do_test_tss_does_no_cleanup_after_release, 2);
+}
+
+void test_tss_does_no_cleanup_with_null_cleanup_function()
+{
+    timed_test(&do_test_tss_does_no_cleanup_with_null_cleanup_function, 2);
+}
+
+boost::unit_test_framework::test_suite* init_unit_test_suite(int, char*[])
+{
+    boost::unit_test_framework::test_suite* test =
+        BOOST_TEST_SUITE("Boost.Threads: tss test suite");
+
+    test->add(BOOST_TEST_CASE(test_tss));
+    test->add(BOOST_TEST_CASE(test_tss_with_custom_cleanup));
+    test->add(BOOST_TEST_CASE(test_tss_does_no_cleanup_after_release));
+    test->add(BOOST_TEST_CASE(test_tss_does_no_cleanup_with_null_cleanup_function));
+
+    return test;
+}
diff --git a/deal.II/contrib/boost/libs/thread/test/test_xtime.cpp b/deal.II/contrib/boost/libs/thread/test/test_xtime.cpp
new file mode 100644 (file)
index 0000000..efdfd3c
--- /dev/null
@@ -0,0 +1,109 @@
+// Copyright (C) 2001-2003
+// William E. Kempf
+// Copyright (C) 2008 Anthony Williams
+//
+//  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/thread/detail/config.hpp>
+
+#include <boost/thread/xtime.hpp>
+
+#include <boost/test/unit_test.hpp>
+#include <boost/thread/mutex.hpp>
+#include <boost/thread/condition.hpp>
+
+void test_xtime_cmp()
+{
+    boost::xtime xt1, xt2, cur;
+    BOOST_CHECK_EQUAL(
+        boost::xtime_get(&cur, boost::TIME_UTC),
+        static_cast<int>(boost::TIME_UTC));
+
+    xt1 = xt2 = cur;
+    xt1.nsec -= 1;
+    xt2.nsec += 1;
+
+    BOOST_CHECK(boost::xtime_cmp(xt1, cur) < 0);
+    BOOST_CHECK(boost::xtime_cmp(xt2, cur) > 0);
+    BOOST_CHECK(boost::xtime_cmp(cur, cur) == 0);
+
+    xt1 = xt2 = cur;
+    xt1.sec -= 1;
+    xt2.sec += 1;
+
+    BOOST_CHECK(boost::xtime_cmp(xt1, cur) < 0);
+    BOOST_CHECK(boost::xtime_cmp(xt2, cur) > 0);
+    BOOST_CHECK(boost::xtime_cmp(cur, cur) == 0);
+}
+
+void test_xtime_get()
+{
+    boost::xtime orig, cur, old;
+    BOOST_CHECK_EQUAL(
+        boost::xtime_get(&orig,
+            boost::TIME_UTC), static_cast<int>(boost::TIME_UTC));
+    old = orig;
+
+    for (int x=0; x < 100; ++x)
+    {
+        BOOST_CHECK_EQUAL(
+            boost::xtime_get(&cur, boost::TIME_UTC),
+            static_cast<int>(boost::TIME_UTC));
+        BOOST_CHECK(boost::xtime_cmp(cur, orig) >= 0);
+        BOOST_CHECK(boost::xtime_cmp(cur, old) >= 0);
+        old = cur;
+    }
+}
+
+void test_xtime_mutex_backwards_compatibility()
+{
+    boost::timed_mutex m;
+    BOOST_CHECK(m.timed_lock(boost::get_xtime(boost::get_system_time()+boost::posix_time::milliseconds(10))));
+    m.unlock();
+    boost::timed_mutex::scoped_timed_lock lk(m,boost::get_xtime(boost::get_system_time()+boost::posix_time::milliseconds(10)));
+    BOOST_CHECK(lk.owns_lock());
+    if(lk.owns_lock())
+    {
+        lk.unlock();
+    }
+    BOOST_CHECK(lk.timed_lock(boost::get_xtime(boost::get_system_time()+boost::posix_time::milliseconds(10))));
+    if(lk.owns_lock())
+    {
+        lk.unlock();
+    }
+}
+
+bool predicate()
+{
+    return false;
+}
+
+
+void test_xtime_condvar_backwards_compatibility()
+{
+    boost::condition_variable cond;
+    boost::condition_variable_any cond_any;
+    boost::mutex m;
+    
+    boost::mutex::scoped_lock lk(m);
+    cond.timed_wait(lk,boost::get_xtime(boost::get_system_time()+boost::posix_time::milliseconds(10)));
+    cond.timed_wait(lk,boost::get_xtime(boost::get_system_time()+boost::posix_time::milliseconds(10)),predicate);
+    cond_any.timed_wait(lk,boost::get_xtime(boost::get_system_time()+boost::posix_time::milliseconds(10)));
+    cond_any.timed_wait(lk,boost::get_xtime(boost::get_system_time()+boost::posix_time::milliseconds(10)),predicate);
+}
+
+
+
+boost::unit_test_framework::test_suite* init_unit_test_suite(int, char*[])
+{
+    boost::unit_test_framework::test_suite* test =
+        BOOST_TEST_SUITE("Boost.Threads: xtime test suite");
+
+    test->add(BOOST_TEST_CASE(&test_xtime_cmp));
+    test->add(BOOST_TEST_CASE(&test_xtime_get));
+    test->add(BOOST_TEST_CASE(&test_xtime_mutex_backwards_compatibility));
+    test->add(BOOST_TEST_CASE(&test_xtime_condvar_backwards_compatibility));
+
+    return test;
+}
diff --git a/deal.II/contrib/boost/libs/thread/test/util.inl b/deal.II/contrib/boost/libs/thread/test/util.inl
new file mode 100644 (file)
index 0000000..60f88e0
--- /dev/null
@@ -0,0 +1,183 @@
+// Copyright (C) 2001-2003\r
+// William E. Kempf\r
+// Copyright (C) 2007-8 Anthony Williams\r
+//\r
+//  Distributed under the Boost Software License, Version 1.0. (See accompanying \r
+//  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\r
+\r
+#if !defined(UTIL_INL_WEK01242003)\r
+#define UTIL_INL_WEK01242003\r
+\r
+#include <boost/thread/xtime.hpp>\r
+#include <boost/thread/mutex.hpp>\r
+#include <boost/thread/condition.hpp>\r
+#include <boost/thread/thread.hpp>\r
+\r
+#ifndef DEFAULT_EXECUTION_MONITOR_TYPE\r
+#   define DEFAULT_EXECUTION_MONITOR_TYPE execution_monitor::use_condition\r
+#endif\r
+\r
+// boostinspect:nounnamed\r
+\r
+namespace\r
+{\r
+inline boost::xtime delay(int secs, int msecs=0, int nsecs=0)\r
+{\r
+    const int MILLISECONDS_PER_SECOND = 1000;\r
+    const int NANOSECONDS_PER_SECOND = 1000000000;\r
+    const int NANOSECONDS_PER_MILLISECOND = 1000000;\r
+\r
+    boost::xtime xt;\r
+    if (boost::TIME_UTC != boost::xtime_get (&xt, boost::TIME_UTC))\r
+        BOOST_ERROR ("boost::xtime_get != boost::TIME_UTC");\r
+\r
+    nsecs += xt.nsec;\r
+    msecs += nsecs / NANOSECONDS_PER_MILLISECOND;\r
+    secs += msecs / MILLISECONDS_PER_SECOND;\r
+    nsecs += (msecs % MILLISECONDS_PER_SECOND) * NANOSECONDS_PER_MILLISECOND;\r
+    xt.nsec = nsecs % NANOSECONDS_PER_SECOND;\r
+    xt.sec += secs + (nsecs / NANOSECONDS_PER_SECOND);\r
+\r
+    return xt;\r
+}\r
+\r
+inline bool in_range(const boost::xtime& xt, int secs=1)\r
+{\r
+    boost::xtime min = delay(-secs);\r
+    boost::xtime max = delay(0);\r
+    return (boost::xtime_cmp(xt, min) >= 0) &&\r
+        (boost::xtime_cmp(xt, max) <= 0);\r
+}\r
+\r
+class execution_monitor\r
+{\r
+public:\r
+    enum wait_type { use_sleep_only, use_mutex, use_condition };\r
+\r
+    execution_monitor(wait_type type, int secs)\r
+        : done(false), type(type), secs(secs) { }\r
+    void start()\r
+    {\r
+        if (type != use_sleep_only) {\r
+            boost::mutex::scoped_lock lock(mutex); done = false;\r
+        } else {\r
+            done = false;\r
+        }\r
+    }\r
+    void finish()\r
+    {\r
+        if (type != use_sleep_only) {\r
+            boost::mutex::scoped_lock lock(mutex);\r
+            done = true;\r
+            if (type == use_condition)\r
+                cond.notify_one();\r
+        } else {\r
+            done = true;\r
+        }\r
+    }\r
+    bool wait()\r
+    {\r
+        boost::xtime xt = delay(secs);\r
+        if (type != use_condition)\r
+            boost::thread::sleep(xt);\r
+        if (type != use_sleep_only) {\r
+            boost::mutex::scoped_lock lock(mutex);\r
+            while (type == use_condition && !done) {\r
+                if (!cond.timed_wait(lock, xt))\r
+                    break;\r
+            }\r
+            return done;\r
+        }\r
+        return done;\r
+    }\r
+\r
+private:\r
+    boost::mutex mutex;\r
+    boost::condition cond;\r
+    bool done;\r
+    wait_type type;\r
+    int secs;\r
+};\r
+\r
+template <typename F>\r
+class indirect_adapter\r
+{\r
+public:\r
+    indirect_adapter(F func, execution_monitor& monitor)\r
+        : func(func), monitor(monitor) { }\r
+    void operator()() const\r
+    {\r
+        try\r
+        {\r
+            boost::thread thrd(func);\r
+            thrd.join();\r
+        }\r
+        catch (...)\r
+        {\r
+            monitor.finish();\r
+            throw;\r
+        }\r
+        monitor.finish();\r
+    }\r
+\r
+private:\r
+    F func;\r
+    execution_monitor& monitor;\r
+    void operator=(indirect_adapter&);\r
+};\r
+\r
+template <typename F>\r
+void timed_test(F func, int secs,\r
+    execution_monitor::wait_type type=DEFAULT_EXECUTION_MONITOR_TYPE)\r
+{\r
+    execution_monitor monitor(type, secs);\r
+    indirect_adapter<F> ifunc(func, monitor);\r
+    monitor.start();\r
+    boost::thread thrd(ifunc);\r
+    BOOST_REQUIRE_MESSAGE(monitor.wait(),\r
+        "Timed test didn't complete in time, possible deadlock.");\r
+}\r
+\r
+template <typename F, typename T>\r
+class thread_binder\r
+{\r
+public:\r
+    thread_binder(const F& func, const T& param)\r
+        : func(func), param(param) { }\r
+    void operator()() const { func(param); }\r
+\r
+private:\r
+    F func;\r
+    T param;\r
+};\r
+\r
+template <typename F, typename T>\r
+thread_binder<F, T> bind(const F& func, const T& param)\r
+{\r
+    return thread_binder<F, T>(func, param);\r
+}\r
+\r
+template <typename R, typename T>\r
+class thread_member_binder\r
+{\r
+public:\r
+    thread_member_binder(R (T::*func)(), T& param)\r
+        : func(func), param(param) { }\r
+    void operator()() const { (param.*func)(); }\r
+\r
+private:\r
+    void operator=(thread_member_binder&);\r
+    \r
+    R (T::*func)();\r
+    T& param;\r
+};\r
+\r
+\r
+template <typename R, typename T>\r
+thread_member_binder<R, T> bind(R (T::*func)(), T& param)\r
+{\r
+    return thread_member_binder<R, T>(func, param);\r
+}\r
+} // namespace\r
+\r
+#endif\r
diff --git a/deal.II/contrib/boost/libs/thread/tutorial/bounded_buffer.cpp b/deal.II/contrib/boost/libs/thread/tutorial/bounded_buffer.cpp
new file mode 100644 (file)
index 0000000..276aaeb
--- /dev/null
@@ -0,0 +1,69 @@
+// Copyright (C) 2001-2003
+// William E. Kempf
+//
+//  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/thread/condition.hpp>
+#include <boost/thread/mutex.hpp>
+#include <boost/thread/thread.hpp>
+#include <iostream>
+#include <vector>
+
+class bounded_buffer : private boost::noncopyable
+{
+public:
+    typedef boost::mutex::scoped_lock lock;
+    bounded_buffer(int n) : begin(0), end(0), buffered(0), circular_buf(n) { }
+    void send (int m) {
+        lock lk(monitor);
+        while (buffered == circular_buf.size())
+            buffer_not_full.wait(lk);
+        circular_buf[end] = m;
+        end = (end+1) % circular_buf.size();
+        ++buffered;
+        buffer_not_empty.notify_one();
+    }
+    int receive() {
+        lock lk(monitor);
+        while (buffered == 0)
+            buffer_not_empty.wait(lk);
+        int i = circular_buf[begin];
+        begin = (begin+1) % circular_buf.size();
+        --buffered;
+        buffer_not_full.notify_one();
+        return i;
+    }
+private:
+    int begin, end, buffered;
+    std::vector<int> circular_buf;
+    boost::condition buffer_not_full, buffer_not_empty;
+    boost::mutex monitor;
+};
+bounded_buffer buf(2);
+
+void sender() {
+    int n = 0;
+    while (n < 100) {
+        buf.send(n);
+        std::cout << "sent: " << n << std::endl;
+        ++n;
+    }
+    buf.send(-1);
+}
+
+void receiver() {
+    int n;
+    do {
+        n = buf.receive();
+        std::cout << "received: " << n << std::endl;
+    } while (n != -1); // -1 indicates end of buffer
+}
+
+int main()
+{
+    boost::thread thrd1(&sender);
+    boost::thread thrd2(&receiver);
+    thrd1.join();
+    thrd2.join();
+}
diff --git a/deal.II/contrib/boost/libs/thread/tutorial/counter.cpp b/deal.II/contrib/boost/libs/thread/tutorial/counter.cpp
new file mode 100644 (file)
index 0000000..a5ca0b4
--- /dev/null
@@ -0,0 +1,28 @@
+// Copyright (C) 2001-2003
+// William E. Kempf
+//
+//  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/thread/mutex.hpp>
+#include <boost/thread/thread.hpp>
+#include <iostream>
+
+boost::mutex mutex;
+int counter=0;
+
+void change_count()
+{
+    boost::mutex::scoped_lock lock(mutex);
+    int i = ++counter;
+    std::cout << "count == " << i << std::endl;
+}
+
+int main()
+{
+    const int num_threads = 4;
+    boost::thread_group thrds;
+    for (int i=0; i < num_threads; ++i)
+        thrds.create_thread(&change_count);
+    thrds.join_all();
+}
diff --git a/deal.II/contrib/boost/libs/thread/tutorial/factorial.cpp b/deal.II/contrib/boost/libs/thread/tutorial/factorial.cpp
new file mode 100644 (file)
index 0000000..9dd1001
--- /dev/null
@@ -0,0 +1,32 @@
+// Copyright (C) 2001-2003
+// William E. Kempf
+//
+//  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/thread/thread.hpp>
+#include <iostream>
+
+class factorial
+{
+public:
+    factorial(int x, int& res) : x(x), res(res) { }
+    void operator()() { res = calculate(x); }
+    int result() const { return res; }
+
+private:
+    int calculate(int x) { return x <= 1 ? 1 : x * calculate(x-1); }
+
+private:
+    int x;
+    int& res;
+};
+
+int main()
+{
+    int result;
+    factorial f(10, result);
+    boost::thread thrd(f);
+    thrd.join();
+    std::cout << "10! = " << result << std::endl;
+}
diff --git a/deal.II/contrib/boost/libs/thread/tutorial/factorial2.cpp b/deal.II/contrib/boost/libs/thread/tutorial/factorial2.cpp
new file mode 100644 (file)
index 0000000..c30421b
--- /dev/null
@@ -0,0 +1,32 @@
+// Copyright (C) 2001-2003
+// William E. Kempf
+//
+//  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/thread/thread.hpp>
+#include <boost/ref.hpp>
+#include <iostream>
+
+class factorial
+{
+public:
+    factorial(int x) : x(x), res(0) { }
+    void operator()() { res = calculate(x); }
+    int result() const { return res; }
+
+private:
+    int calculate(int x) { return x <= 1 ? 1 : x * calculate(x-1); }
+
+private:
+    int x;
+    int res;
+};
+
+int main()
+{
+    factorial f(10);
+    boost::thread thrd(boost::ref(f));
+    thrd.join();
+    std::cout << "10! = " << f.result() << std::endl;
+}
diff --git a/deal.II/contrib/boost/libs/thread/tutorial/factorial3.cpp b/deal.II/contrib/boost/libs/thread/tutorial/factorial3.cpp
new file mode 100644 (file)
index 0000000..2515bfe
--- /dev/null
@@ -0,0 +1,36 @@
+// Copyright (C) 2001-2003
+// William E. Kempf
+//
+//  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/thread/thread.hpp>
+#include <iostream>
+
+const int NUM_CALCS=5;
+
+class factorial
+{
+public:
+    factorial(int x, int& res) : x(x), res(res) { }
+    void operator()() { res = calculate(x); }
+    int result() const { return res; }
+
+private:
+    int calculate(int x) { return x <= 1 ? 1 : x * calculate(x-1); }
+
+private:
+    int x;
+    int& res;
+};
+
+int main()
+{
+    int results[NUM_CALCS];
+    boost::thread_group thrds;
+    for (int i=0; i < NUM_CALCS; ++i)
+        thrds.create_thread(factorial(i*10, results[i]));
+    thrds.join_all();
+    for (int j=0; j < NUM_CALCS; ++j)
+        std::cout << j*10 << "! = " << results[j] << std::endl;
+}
diff --git a/deal.II/contrib/boost/libs/thread/tutorial/helloworld.cpp b/deal.II/contrib/boost/libs/thread/tutorial/helloworld.cpp
new file mode 100644 (file)
index 0000000..5003108
--- /dev/null
@@ -0,0 +1,19 @@
+// Copyright (C) 2001-2003
+// William E. Kempf
+//
+//  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/thread/thread.hpp>
+#include <iostream>
+
+void helloworld()
+{
+    std::cout << "Hello World!" << std::endl;
+}
+
+int main()
+{
+    boost::thread thrd(&helloworld);
+    thrd.join();
+}
diff --git a/deal.II/contrib/boost/libs/thread/tutorial/helloworld2.cpp b/deal.II/contrib/boost/libs/thread/tutorial/helloworld2.cpp
new file mode 100644 (file)
index 0000000..dc7a698
--- /dev/null
@@ -0,0 +1,24 @@
+// Copyright (C) 2001-2003
+// William E. Kempf
+//
+//  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/thread/thread.hpp>
+#include <iostream>
+
+struct helloworld
+{
+    helloworld(const char* who) : m_who(who) { }
+    void operator()()
+    {
+        std::cout << m_who << "says, \"Hello World.\"" << std::endl;
+    }
+    const char* m_who;
+};
+
+int main()
+{
+    boost::thread thrd(helloworld("Bob"));
+    thrd.join();
+}
diff --git a/deal.II/contrib/boost/libs/thread/tutorial/helloworld3.cpp b/deal.II/contrib/boost/libs/thread/tutorial/helloworld3.cpp
new file mode 100644 (file)
index 0000000..cd43987
--- /dev/null
@@ -0,0 +1,20 @@
+// Copyright (C) 2001-2003
+// William E. Kempf
+//
+//  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/thread/thread.hpp>
+#include <boost/bind.hpp>
+#include <iostream>
+
+void helloworld(const char* who)
+{
+    std::cout << who << "says, \"Hello World.\"" << std::endl;
+}
+
+int main()
+{
+    boost::thread thrd(boost::bind(&helloworld, "Bob"));
+    thrd.join();
+}
diff --git a/deal.II/contrib/boost/libs/thread/tutorial/helloworld4.cpp b/deal.II/contrib/boost/libs/thread/tutorial/helloworld4.cpp
new file mode 100644 (file)
index 0000000..cd43987
--- /dev/null
@@ -0,0 +1,20 @@
+// Copyright (C) 2001-2003
+// William E. Kempf
+//
+//  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/thread/thread.hpp>
+#include <boost/bind.hpp>
+#include <iostream>
+
+void helloworld(const char* who)
+{
+    std::cout << who << "says, \"Hello World.\"" << std::endl;
+}
+
+int main()
+{
+    boost::thread thrd(boost::bind(&helloworld, "Bob"));
+    thrd.join();
+}
diff --git a/deal.II/contrib/boost/libs/thread/tutorial/once.cpp b/deal.II/contrib/boost/libs/thread/tutorial/once.cpp
new file mode 100644 (file)
index 0000000..5a5b6f5
--- /dev/null
@@ -0,0 +1,31 @@
+// Copyright (C) 2001-2003
+// William E. Kempf
+//
+//  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/thread/thread.hpp>
+#include <boost/thread/once.hpp>
+#include <cassert>
+
+int value=0;
+boost::once_flag once = BOOST_ONCE_INIT;
+
+void init()
+{
+    ++value;
+}
+
+void thread_proc()
+{
+    boost::call_once(&init, once);
+}
+
+int main(int argc, char* argv[])
+{
+    boost::thread_group threads;
+    for (int i=0; i<5; ++i)
+        threads.create_thread(&thread_proc);
+    threads.join_all();
+    assert(value == 1);
+}
diff --git a/deal.II/contrib/boost/libs/thread/tutorial/tss.cpp b/deal.II/contrib/boost/libs/thread/tutorial/tss.cpp
new file mode 100644 (file)
index 0000000..f867a91
--- /dev/null
@@ -0,0 +1,36 @@
+// Copyright (C) 2001-2003
+// William E. Kempf
+//
+//  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/thread/thread.hpp>
+#include <boost/thread/tss.hpp>
+#include <cassert>
+
+boost::thread_specific_ptr<int> value;
+
+void increment()
+{
+    int* p = value.get();
+    ++*p;
+}
+
+void thread_proc()
+{
+    value.reset(new int(0)); // initialize the thread's storage
+    for (int i=0; i<10; ++i)
+    {
+        increment();
+        int* p = value.get();
+        assert(*p == i+1);
+    }
+}
+
+int main(int argc, char* argv[])
+{
+    boost::thread_group threads;
+    for (int i=0; i<5; ++i)
+        threads.create_thread(&thread_proc);
+    threads.join_all();
+}

In the beginning the Universe was created. This has made a lot of people very angry and has been widely regarded as a bad move.

Douglas Adams


Typeset in Trocchi and Trocchi Bold Sans Serif.