]> https://gitweb.dealii.org/ - dealii.git/commitdiff
Also make access to the update flags of GridTools::Cache thread-safe.
authorWolfgang Bangerth <bangerth@colostate.edu>
Wed, 19 Jun 2024 23:42:46 +0000 (17:42 -0600)
committerWolfgang Bangerth <bangerth@colostate.edu>
Wed, 19 Jun 2024 23:42:46 +0000 (17:42 -0600)
include/deal.II/grid/grid_tools_cache.h
source/grid/grid_tools_cache.cc

index d5843358028183e38f64e260b39452f4dc922e2a..d7f110e63ed380606dd42bb1c30ba9c6817c2e04 100644 (file)
 
 #include <boost/signals2.hpp>
 
+#include <atomic>
 #include <cmath>
 
+
 DEAL_II_NAMESPACE_OPEN
 
 namespace GridTools
@@ -227,8 +229,13 @@ namespace GridTools
      * corresponding flag. The constructor as well as the signal slot
      * that is called whenever the triangulation changes the re-sets this
      * flag to `update_all` again.
+     *
+     * The various get_() member functions may be reading and updating this
+     * variable from different threads, but are only ever reading or writing
+     * individual bits. We can make that thread-safe by using std::atomic
+     * with the correct integer type for the `enum` type of `CacheUpdateFlags`.
      */
-    mutable CacheUpdateFlags update_flags;
+    mutable std::atomic<std::underlying_type_t<CacheUpdateFlags>> update_flags;
 
     /**
      * A pointer to the Triangulation.
index a320b82f39f1e7a6ec1464d8f175375486860514..8f831a3c25b82a01ee50806ae1ff903b726d557b 100644 (file)
@@ -69,7 +69,10 @@ namespace GridTools
     if (update_flags & update_vertex_to_cell_map)
       {
         vertex_to_cells = GridTools::vertex_to_cell_map(*tria);
-        update_flags    = update_flags & ~update_vertex_to_cell_map;
+
+        // Atomically clear the flag that indicates that this data member
+        // needs to be updated:
+        update_flags &= ~update_vertex_to_cell_map;
       }
     return vertex_to_cells;
   }
@@ -91,7 +94,10 @@ namespace GridTools
       {
         vertex_to_cell_centers = GridTools::vertex_to_cell_centers_directions(
           *tria, get_vertex_to_cell_map());
-        update_flags = update_flags & ~update_vertex_to_cell_centers_directions;
+
+        // Atomically clear the flag that indicates that this data member
+        // needs to be updated:
+        update_flags &= ~update_vertex_to_cell_centers_directions;
       }
     return vertex_to_cell_centers;
   }
@@ -112,7 +118,10 @@ namespace GridTools
     if (update_flags & update_used_vertices)
       {
         used_vertices = GridTools::extract_used_vertices(*tria, *mapping);
-        update_flags  = update_flags & ~update_used_vertices;
+
+        // Atomically clear the flag that indicates that this data member
+        // needs to be updated:
+        update_flags &= ~update_used_vertices;
       }
     return used_vertices;
   }
@@ -139,7 +148,10 @@ namespace GridTools
         for (const auto &it : used_vertices)
           vertices[i++] = std::make_pair(it.second, it.first);
         used_vertices_rtree = pack_rtree(vertices);
-        update_flags        = update_flags & ~update_used_vertices_rtree;
+
+        // Atomically clear the flag that indicates that this data member
+        // needs to be updated:
+        update_flags &= ~update_used_vertices_rtree;
       }
     return used_vertices_rtree;
   }
@@ -170,7 +182,10 @@ namespace GridTools
           boxes.emplace_back(mapping->get_bounding_box(cell), cell);
 
         cell_bounding_boxes_rtree = pack_rtree(boxes);
-        update_flags = update_flags & ~update_cell_bounding_boxes_rtree;
+
+        // Atomically clear the flag that indicates that this data member
+        // needs to be updated:
+        update_flags &= ~update_cell_bounding_boxes_rtree;
       }
     return cell_bounding_boxes_rtree;
   }
@@ -208,8 +223,10 @@ namespace GridTools
           boxes.emplace_back(mapping->get_bounding_box(cell), cell);
 
         locally_owned_cell_bounding_boxes_rtree = pack_rtree(boxes);
-        update_flags =
-          update_flags & ~update_locally_owned_cell_bounding_boxes_rtree;
+
+        // Atomically clear the flag that indicates that this data member
+        // needs to be updated:
+        update_flags &= ~update_locally_owned_cell_bounding_boxes_rtree;
       }
     return locally_owned_cell_bounding_boxes_rtree;
   }
@@ -246,7 +263,10 @@ namespace GridTools
             covering_rtree[level] =
               GridTools::build_global_description_tree(boxes, MPI_COMM_SELF);
           }
-        update_flags = update_flags & ~update_covering_rtree;
+
+        // Atomically clear the flag that indicates that this data member
+        // needs to be updated:
+        update_flags &= ~update_covering_rtree;
       }
 
     return covering_rtree[level];
@@ -276,7 +296,9 @@ namespace GridTools
                 vertex_to_neighbor_subdomain[cell->vertex_index(v)].insert(
                   cell->subdomain_id());
           }
-        update_flags = update_flags & ~update_vertex_to_neighbor_subdomain;
+        // Atomically clear the flag that indicates that this data member
+        // needs to be updated:
+        update_flags &= ~update_vertex_to_neighbor_subdomain;
       }
     return vertex_to_neighbor_subdomain;
   }
@@ -299,7 +321,9 @@ namespace GridTools
         vertices_with_ghost_neighbors =
           GridTools::compute_vertices_with_ghost_neighbors(*tria);
 
-        update_flags = update_flags & ~update_vertex_with_ghost_neighbors;
+        // Atomically clear the flag that indicates that this data member
+        // needs to be updated:
+        update_flags &= ~update_vertex_with_ghost_neighbors;
       }
 
     return vertices_with_ghost_neighbors;

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.