[compiler-rt] [compiler-rt][emutls] Fix race condition when allocating object (PR #121320)

Kai Luo via llvm-commits llvm-commits at lists.llvm.org
Mon Dec 30 00:12:43 PST 2024


https://github.com/bzEq created https://github.com/llvm/llvm-project/pull/121320

For following program compiled with `-femulated-tls`, there is chance the first allocated object is different from other allocation.
```

thread_local int id = 0;
std::mutex print_mutex;

int main() {
  // std::cout << "thread " << 0 << ": " << &id << std::endl;
  std::vector<std::thread> group;
  for (int i = 1; i < 8; ++i) {
    group.emplace_back([i] {
      std::unique_lock<std::mutex> _(print_mutex);
      std::cout << "thread " << i << ": " << &id << std::endl;
    });
  }
  for (auto &t : group) t.join();
  return 0;
}

Output:
thread 1: 0x7f57040010a8
thread 2: 0x7f56fc000c98
thread 3: 0x7f56fc000c98
thread 5: 0x7f56fc000c98
thread 4: 0x7f56fc000c98
thread 6: 0x7f56fc000c98
thread 7: 0x7f56fc000c98
```
Also I have a question, is this implementation broken since it's returning the same address for the same thread_local variable in different threads.

>From 4095af59ec94cd16794a9b51cdc7ce7880195a17 Mon Sep 17 00:00:00 2001
From: Kai Law <lawkai at vivo.com>
Date: Mon, 30 Dec 2024 16:02:57 +0800
Subject: [PATCH] [compiler-rt] Fix race condition when allocating object

For following program compiled with `-femulated-tls`, there is chance
the first allocated object is different from other allocation.
```

thread_local int id = 0;
std::mutex print_mutex;

int main() {
  // std::cout << "thread " << 0 << ": " << &id << std::endl;
  std::vector<std::thread> group;
  for (int i = 1; i < 8; ++i) {
    group.emplace_back([i] {
      std::unique_lock<std::mutex> _(print_mutex);
      std::cout << "thread " << i << ": " << &id << std::endl;
    });
  }
  for (auto &t : group) t.join();
  return 0;
}

Output:
thread 1: 0x7f57040010a8
thread 2: 0x7f56fc000c98
thread 3: 0x7f56fc000c98
thread 5: 0x7f56fc000c98
thread 4: 0x7f56fc000c98
thread 6: 0x7f56fc000c98
thread 7: 0x7f56fc000c98
```
---
 compiler-rt/lib/builtins/emutls.c | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/compiler-rt/lib/builtins/emutls.c b/compiler-rt/lib/builtins/emutls.c
index 390ffb25f6cf00..ca18da2fffe6f5 100644
--- a/compiler-rt/lib/builtins/emutls.c
+++ b/compiler-rt/lib/builtins/emutls.c
@@ -392,8 +392,12 @@ __attribute__((visibility("default"), weak))
 void *__emutls_get_address(__emutls_control *control) {
   uintptr_t index = emutls_get_index(control);
   emutls_address_array *array = emutls_get_address_array(index--);
-  if (array->data[index] == NULL)
-    array->data[index] = emutls_allocate_object(control);
+  if (array->data[index] == NULL) {
+    emutls_lock();
+    if (array->data[index] == NULL)
+      array->data[index] = emutls_allocate_object(control);
+    emutls_unlock();
+  }
   return array->data[index];
 }
 



More information about the llvm-commits mailing list