From: Wolfgang Bangerth Date: Wed, 19 Jun 2024 23:42:46 +0000 (-0600) Subject: Also make access to the update flags of GridTools::Cache thread-safe. X-Git-Tag: v9.6.0-rc1~170^2~1 X-Git-Url: https://gitweb.dealii.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=305af707c1a47833deabe24dd6d6e961ea49e4ac;p=dealii.git Also make access to the update flags of GridTools::Cache thread-safe. --- diff --git a/include/deal.II/grid/grid_tools_cache.h b/include/deal.II/grid/grid_tools_cache.h index d584335802..d7f110e63e 100644 --- a/include/deal.II/grid/grid_tools_cache.h +++ b/include/deal.II/grid/grid_tools_cache.h @@ -33,8 +33,10 @@ #include +#include #include + 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> update_flags; /** * A pointer to the Triangulation. diff --git a/source/grid/grid_tools_cache.cc b/source/grid/grid_tools_cache.cc index a320b82f39..8f831a3c25 100644 --- a/source/grid/grid_tools_cache.cc +++ b/source/grid/grid_tools_cache.cc @@ -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;