> We append a patch that lets TBB wait for the task to complete (using
> tbb::Task::wait_for_all() at the correct place). The only restriction
> TBB seems to set is that wait_for_all is called only once. With this
> patch, everything is fine on our machines.

The patch was still buggy - in case a task finished before calling
join(), it would not shut down the task properly. This should be fixed
in the new patch.

Best,
Katharina and Martin
Index: include/deal.II/base/thread_management.h
===================================================================
--- include/deal.II/base/thread_management.h	(revision 22834)
+++ include/deal.II/base/thread_management.h	(working copy)
@@ -3692,25 +3692,6 @@
 					     // and put the return value
 					     // into the proper place
 	    call (task_descriptor.function, task_descriptor.ret_val);
-
-					     // indicate that the task
-					     // has finished, both
-					     // through the flag and
-					     // through the mutex that
-					     // was locked before we
-					     // started and that now
-					     // needs to be
-					     // released. this may
-					     // also wake up all
-					     // threads that may be
-					     // waiting for the task's
-					     // demise by blocking on
-					     // completion_mutex.acquire()
-					     // in
-					     // TaskDescriptor::join().
-	    task_descriptor.task_is_done = true;
-	    task_descriptor.completion_mutex.release ();
-
 	    return 0;
 	  }
 
@@ -3798,19 +3779,6 @@
 					  */
 	bool task_is_done;
 
-                                         /**
-                                          * Mutex used to indicate
-                                          * when the task is done. It
-                                          * is locked before the task
-                                          * is spawned; the join()
-                                          * function tries to acquire
-                                          * it, but that will fail
-                                          * unless the task has
-                                          * unlocked it, which it does
-                                          * upon completion.
-                                          */
-        mutable ThreadMutex completion_mutex;
-
       public:
 
 					 /**
@@ -3851,7 +3819,7 @@
 					  * Queue up the task to the
 					  * scheduler. We need to do
 					  * this in a separate
-					  * function since we the new
+					  * function since the new
 					  * tasks needs to access
 					  * objects from the current
 					  * object and that can only
@@ -3894,11 +3862,6 @@
     void
     TaskDescriptor<RT>::queue_task ()
     {
-				       // lock the mutex. it will
-				       // become unlocked when the
-				       // task is done
-      completion_mutex.acquire ();
-
 				       // use the pattern described in
 				       // the TBB book on pages
 				       // 230/231 ("Start a large task
@@ -3958,7 +3921,6 @@
 				       // explicitly destroy the empty
 				       // task object
       Assert (task != 0, ExcInternalError());
-      task->wait_for_all ();
       task->destroy (*task);
     }
 
@@ -3968,23 +3930,17 @@
     void
     TaskDescriptor<RT>::join ()
     {
-                                       // use Schmidt's double checking
-                                       // pattern: if thread has already
-                                       // indicated that it is done, then
-                                       // return immediately
-      if (task_is_done)
+				       // if the task is already done, just
+				       // return. this makes sure we call
+				       // tbb::Task::wait_for_all() exactly
+				       // once
+      if (task_is_done == true)
 	return;
 
-				       // acquire the lock; this can
-				       // only succeed when the task
-				       // is done
-      completion_mutex.acquire ();
-
-				       // release it again; at this
-				       // point the task must have
-				       // finished
-      completion_mutex.release ();
-      Assert (task_is_done == true, ExcInternalError());
+				       // let TBB wait for the task to
+				       // complete. TBB will make sure that it
+				       // ends properly.
+      task->wait_for_all();
     }
 
 
_______________________________________________
dealii mailing list http://poisson.dealii.org/mailman/listinfo/dealii

Reply via email to