[PATCH] D45192: [lld] fix data race in ELF/ICF.cpp

Bob Haarman via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Tue Apr 3 10:32:49 PDT 2018


This revision was automatically updated to reflect the committed changes.
Closed by commit rLLD329088: [lld] fix data race in ELF/ICF.cpp (authored by inglorion, committed by ).

Changed prior to commit:
  https://reviews.llvm.org/D45192?vs=140710&id=140821#toc

Repository:
  rL LLVM

https://reviews.llvm.org/D45192

Files:
  ELF/ICF.cpp


Index: ELF/ICF.cpp
===================================================================
--- ELF/ICF.cpp
+++ ELF/ICF.cpp
@@ -362,17 +362,12 @@
 // vector. Therefore, Sections vector can be considered as contiguous
 // groups of sections, grouped by the class.
 //
-// This function calls Fn on every group that starts within [Begin, End).
-// Note that a group must start in that range but doesn't necessarily
-// have to end before End.
+// This function calls Fn on every group within [Begin, End).
 template <class ELFT>
 void ICF<ELFT>::forEachClassRange(size_t Begin, size_t End,
                                   std::function<void(size_t, size_t)> Fn) {
-  if (Begin > 0)
-    Begin = findBoundary(Begin - 1, End);
-
   while (Begin < End) {
-    size_t Mid = findBoundary(Begin, Sections.size());
+    size_t Mid = findBoundary(Begin, End);
     Fn(Begin, Mid);
     Begin = Mid;
   }
@@ -392,12 +387,23 @@
   Current = Cnt % 2;
   Next = (Cnt + 1) % 2;
 
-  // Split sections into 256 shards and call Fn in parallel.
-  size_t NumShards = 256;
+  // Shard into non-overlapping intervals, and call Fn in parallel.
+  // The sharding must be completed before any calls to Fn are made
+  // so that Fn can modify the Chunks in its shard without causing data
+  // races.
+  const size_t NumShards = 256;
   size_t Step = Sections.size() / NumShards;
-  parallelForEachN(0, NumShards, [&](size_t I) {
-    size_t End = (I == NumShards - 1) ? Sections.size() : (I + 1) * Step;
-    forEachClassRange(I * Step, End, Fn);
+  size_t Boundaries[NumShards + 1];
+  Boundaries[0] = 0;
+  Boundaries[NumShards] = Sections.size();
+
+  parallelForEachN(1, NumShards, [&](size_t I) {
+    Boundaries[I] = findBoundary((I - 1) * Step, Sections.size());
+  });
+
+  parallelForEachN(1, NumShards + 1, [&](size_t I) {
+    if (Boundaries[I - 1] < Boundaries[I])
+      forEachClassRange(Boundaries[I - 1], Boundaries[I], Fn);
   });
   ++Cnt;
 }


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D45192.140821.patch
Type: text/x-patch
Size: 1937 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20180403/0f62e5d2/attachment.bin>


More information about the llvm-commits mailing list