]> https://gitweb.dealii.org/ - dealii.git/commitdiff
Prefer std::atomic to volatile for thread data.
authorDavid Wells <wellsd2@rpi.edu>
Sat, 8 Apr 2017 04:54:42 +0000 (00:54 -0400)
committerDavid Wells <wellsd2@rpi.edu>
Thu, 13 Apr 2017 01:03:26 +0000 (21:03 -0400)
include/deal.II/base/config.h.in
include/deal.II/base/subscriptor.h
source/base/subscriptor.cc
source/base/thread_management.cc
tests/base/thread_local_storage_01.cc
tests/base/thread_local_storage_02.cc
tests/base/thread_validity_08.cc
tests/base/thread_validity_09.cc

index fec20fbfb5d01064378f274805dc0dff9a675cd6..c11c5627e399ee655190ff42e224d7c5980c5d6e 100644 (file)
  * Depending on the use of threads, we will have to make some variables
  * volatile. We do this here in a very old-fashioned C-style, but still
  * convenient way.
+ *
+ * @deprecated This macro is deprecated in favor of using the
+ * <code>std::atomic</code> template class.
  */
 #ifdef DEAL_II_WITH_THREADS
 #  define DEAL_VOLATILE volatile
index f826949f8c22cc8dda5b184df12316267271416c..37f3b1acadf125f547c3e71e625fc864c33c31e4 100644 (file)
 #include <deal.II/base/config.h>
 #include <deal.II/base/exceptions.h>
 
-#include <typeinfo>
+#include <atomic>
 #include <map>
 #include <string>
+#include <typeinfo>
 
 DEAL_II_NAMESPACE_OPEN
 
@@ -191,12 +192,12 @@ private:
    * We use the <tt>mutable</tt> keyword in order to allow subscription to
    * constant objects also.
    *
-   * In multithreaded mode, this counter may be modified by different threads.
-   * We thus have to mark it <tt>volatile</tt>. However, this is counter-
-   * productive in non-MT mode since it may pessimize code. So use the macro
-   * defined in <tt>deal.II/base/config.h</tt> to selectively add volatility.
+   * This counter may be read from and written to concurrently in
+   * multithreaded code: hence we use the <code>std::atomic</code> class
+   * template.
+   *
    */
-  mutable DEAL_VOLATILE unsigned int counter;
+  mutable std::atomic<unsigned int> counter;
 
   /**
    * In this map, we count subscriptions for each different identification
index e249163e80252547284b2f3685e2753cfc8c8d8c..ce05a88509aeb176df8d7ed419c1ad71d337bb00 100644 (file)
 DEAL_II_NAMESPACE_OPEN
 
 
-#ifdef DEBUG
-namespace
-{
-// create a lock that might be used to control subscription to and
-// unsubscription from objects, as that might happen in parallel.
-// since it should happen rather seldom that several threads try to
-// operate on different objects at the same time (the usual case is
-// that they subscribe to the same object right after thread
-// creation), a global lock should be sufficient, rather than one that
-// operates on a per-object base (in which case we would have to
-// include the huge <thread_management.h> file into the
-// <subscriptor.h> file).
-  Threads::Mutex subscription_lock;
-}
-#endif
-
-
 static const char *unknown_subscriber = "unknown subscriber";
 
 
@@ -167,7 +150,6 @@ Subscriptor::subscribe(const char *id) const
 #ifdef DEBUG
   if (object_info == nullptr)
     object_info = &typeid(*this);
-  Threads::Mutex::ScopedLock lock (subscription_lock);
   ++counter;
 
 #  ifndef DEAL_II_WITH_THREADS
@@ -199,7 +181,6 @@ Subscriptor::unsubscribe(const char *id) const
   if (counter == 0)
     return;
 
-  Threads::Mutex::ScopedLock lock (subscription_lock);
   --counter;
 
 #  ifndef DEAL_II_WITH_THREADS
index f60db61786b6769535a4e3cff02f7e237ad26e4a..0c43b4be1ad79eb4455b03725b06f5b227cb49ea 100644 (file)
 
 #include <deal.II/base/thread_management.h>
 
-#include <cerrno>
+#include <atomic>
 #include <cstdlib>
 #include <iostream>
-#include <list>
 
 #ifdef DEAL_II_HAVE_UNISTD_H
 #  include <unistd.h>
@@ -32,15 +31,11 @@ namespace Threads
 {
   namespace internal
   {
-    // counter and access mutex for the
-    // number of threads
-    volatile unsigned int n_existing_threads_counter = 1;
-    Mutex  n_existing_threads_mutex;
+    static std::atomic<unsigned int> n_existing_threads_counter(1);
 
 
     void register_thread ()
     {
-      Mutex::ScopedLock lock (n_existing_threads_mutex);
       ++n_existing_threads_counter;
     }
 
@@ -48,7 +43,6 @@ namespace Threads
 
     void deregister_thread ()
     {
-      Mutex::ScopedLock lock (n_existing_threads_mutex);
       --n_existing_threads_counter;
       Assert (n_existing_threads_counter >= 1,
               ExcInternalError());
@@ -128,7 +122,6 @@ namespace Threads
 
   unsigned int n_existing_threads ()
   {
-    Mutex::ScopedLock lock (internal::n_existing_threads_mutex);
     return internal::n_existing_threads_counter;
   }
 
index 70fcdd706a3854f053043f1ba33c095092377b26..017af3acc3b6eaf2239f3755c074b9441528833b 100644 (file)
@@ -17,6 +17,7 @@
 // verify that thread local storage works as advertised
 
 #include "../tests.h"
+#include <atomic>
 #include <iomanip>
 #include <fstream>
 
@@ -39,7 +40,7 @@ struct X
 
 Threads::ThreadLocalStorage<X> *tls_data;
 
-volatile int counter = 0;
+static std::atomic<int> counter(0);
 
 void execute (int i)
 {
index 683e1649212adf2eeb0bfbe7c5f5fc72b26b53b6..d57e520426d14013740fd91c440467abcd3a2b77 100644 (file)
@@ -18,6 +18,7 @@
 // the initialization with an exemplar
 
 #include "../tests.h"
+#include <atomic>
 #include <iomanip>
 #include <fstream>
 
@@ -49,7 +50,7 @@ struct X
 
 Threads::ThreadLocalStorage<X> *tls_data;
 
-volatile int counter = 0;
+static std::atomic<int> counter(0);
 
 void execute (int i)
 {
index 7581aec84e5de6be1ab09fab4eddc5598166259c..8cdbfcd2bfc5b5276934a1d0eedf06852158c6ac 100644 (file)
@@ -17,6 +17,7 @@
 // see if we can detach from threads
 
 #include "../tests.h"
+#include <atomic>
 #include <iomanip>
 #include <fstream>
 #include <unistd.h>
@@ -25,7 +26,7 @@
 
 
 Threads::Mutex mutex;
-volatile int spin_lock = 0;
+static std::atomic<int> spin_lock(0);
 
 
 void worker ()
index 0ba39f6d64b95c11b873b57e662d40b56cf39d9e..e21fa0c04927fdac98fd7633b90f9c7db356e69b 100644 (file)
@@ -20,6 +20,7 @@
 // and makes sure nobody writes into it at undue times
 
 #include "../tests.h"
+#include <atomic>
 #include <iomanip>
 #include <fstream>
 #include <unistd.h>
@@ -28,7 +29,7 @@
 
 
 Threads::Mutex mutex;
-volatile int spin_lock = 0;
+static std::atomic<int> spin_lock(0);
 
 
 int worker ()

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.