Fix a data race found by tsan.
authorRui Ueyama <ruiu@google.com>
Mon, 2 Oct 2017 20:16:13 +0000 (20:16 +0000)
committerRui Ueyama <ruiu@google.com>
Mon, 2 Oct 2017 20:16:13 +0000 (20:16 +0000)
Reads from `Live` and writes to `OutputOff` in the following code race
even though they are logically independent because they are bitfields
sharing the same word.

  for (size_t I = 0, E = Sec->Pieces.size(); I != E; ++I) {
    if (!Sec->Pieces[I].Live)
      continue;
    CachedHashStringRef Str = Sec->getData(I);
    size_t ShardId = getShardId(Str.hash());
    if ((ShardId & (Concurrency - 1)) == ThreadId)
      Sec->Pieces[I].OutputOff = Shards[ShardId].add(Str);
  }

llvm-svn: 314711

lld/ELF/InputSection.h

index 8cc644b..de78b8f 100644 (file)
@@ -196,11 +196,11 @@ private:
 // be found by looking at the next one) and put the hash in a side table.
 struct SectionPiece {
   SectionPiece(size_t Off, bool Live = false)
-      : InputOff(Off), OutputOff(-1), Live(Live || !Config->GcSections) {}
+      : InputOff(Off), Live(Live || !Config->GcSections), OutputOff(-1) {}
 
-  size_t InputOff;
-  ssize_t OutputOff : 8 * sizeof(ssize_t) - 1;
+  size_t InputOff : 8 * sizeof(ssize_t) - 1;
   size_t Live : 1;
+  ssize_t OutputOff;
 };
 static_assert(sizeof(SectionPiece) == 2 * sizeof(size_t),
               "SectionPiece is too big");