[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