]> https://gitweb.dealii.org/ - dealii.git/commitdiff
Add a mutex to IndexSet and use it to make IndexSet::do_compress() thread-safe. 3687/head
authorWolfgang Bangerth <bangerth@colostate.edu>
Tue, 20 Dec 2016 16:00:01 +0000 (09:00 -0700)
committerWolfgang Bangerth <bangerth@colostate.edu>
Tue, 20 Dec 2016 16:00:01 +0000 (09:00 -0700)
IndexSet has a number of 'mutable' member variables. The only function that modifies them is
'do_compress', which is called by 'compress', which is in turn called by all of the
'const' member functions. To make all of these 'const' member functions thread-safe, we
need to use a mutex in 'do_compress'. This patch does this.

I have verified that no other 'const' function actually modifies any of the 'mutable'
member variables, so only guarding 'do_compress' by the mutex is sufficient.

doc/news/changes/minor/20161220Bangerth [new file with mode: 0644]
include/deal.II/base/index_set.h
source/base/index_set.cc

diff --git a/doc/news/changes/minor/20161220Bangerth b/doc/news/changes/minor/20161220Bangerth
new file mode 100644 (file)
index 0000000..7985bf1
--- /dev/null
@@ -0,0 +1,6 @@
+ <li> Changed: IndexSet::compress() and, by extension, all of the
+ "const" member functions of the IndexSet class, are now thread-safe.
+ <br>
+ (Wolfgang Bangerth, 2016/12/20)
+ </li>
+
index 67dd11a99caa79d168992f41ed7d6aac0431aa03..c1e3472c336457782e288f0a9cdd2ebf4a31f31f 100644 (file)
@@ -19,6 +19,7 @@
 #include <deal.II/base/config.h>
 #include <deal.II/base/utilities.h>
 #include <deal.II/base/exceptions.h>
+#include <deal.II/base/thread_management.h>
 #include <boost/serialization/vector.hpp>
 #include <vector>
 #include <algorithm>
@@ -853,6 +854,12 @@ private:
    */
   mutable size_type largest_range;
 
+  /**
+   * A mutex that is used to synchronize operations of the do_compress() function
+   * that is called from many 'const' functions via compress().
+   */
+  mutable Threads::Mutex compress_mutex;
+
   /**
    * Actually perform the compress() operation.
    */
@@ -1751,7 +1758,7 @@ IndexSet::print (StreamType &out) const
       else
         out << "[" << p->begin << "," << p->end-1 << "]";
 
-      if (p !=--ranges.end())
+      if (p != --ranges.end())
         out << ", ";
     }
   out << "}" << std::endl;
index c6f78e3ea4a7f9764ff8592307520da86839ae2b..c8efcf2489dd12e1ad8f5321fe4c42975c2149bc 100644 (file)
@@ -119,6 +119,13 @@ IndexSet::add_range (const size_type begin,
 void
 IndexSet::do_compress () const
 {
+  // we will, in the following, modify mutable variables. this can only
+  // work in multithreaded applications if we lock the data structures
+  // via a mutex, so that users can call 'const' functions from threads
+  // in parallel (and these 'const' functions can then call compress()
+  // which itself calls the current function)
+  Threads::Mutex::ScopedLock lock (compress_mutex);
+
   // see if any of the contiguous ranges can be merged. do not use
   // std::vector::erase in-place as it is quadratic in the number of
   // ranges. since the ranges are sorted by their first index, determining
@@ -660,7 +667,8 @@ IndexSet::memory_consumption () const
 {
   return (MemoryConsumption::memory_consumption (ranges) +
           MemoryConsumption::memory_consumption (is_compressed) +
-          MemoryConsumption::memory_consumption (index_space_size));
+          MemoryConsumption::memory_consumption (index_space_size) +
+          sizeof (compress_mutex));
 }
 
 

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.