-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[libc][stdlib] Remove LIBC_THREAD_LOCAL from rand_next #96245
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
@llvm/pr-subscribers-libc Author: None (PiJoules) Changessrand and rand do not need to be threadsafe, so it should be permissible to remove thise from rand_next whose only users are srand and rand. This is helpful for the baremetal runtimes where we still need to setup the TLS machinery. Full diff: https://github.com/llvm/llvm-project/pull/96245.diff 2 Files Affected:
diff --git a/libc/src/stdlib/rand_util.cpp b/libc/src/stdlib/rand_util.cpp
index 1f3dbce9c7860..4aa03bfe3eba9 100644
--- a/libc/src/stdlib/rand_util.cpp
+++ b/libc/src/stdlib/rand_util.cpp
@@ -18,7 +18,7 @@ ThreadLocal<unsigned long> rand_next;
#else
// C standard 7.10p2: If 'rand' is called before 'srand' it is to proceed as if
// the 'srand' function was called with a value of '1'.
-LIBC_THREAD_LOCAL unsigned long rand_next = 1;
+unsigned long rand_next = 1;
#endif
} // namespace LIBC_NAMESPACE
diff --git a/libc/src/stdlib/rand_util.h b/libc/src/stdlib/rand_util.h
index cadd6b5cdcbb8..b32302f486dce 100644
--- a/libc/src/stdlib/rand_util.h
+++ b/libc/src/stdlib/rand_util.h
@@ -34,7 +34,7 @@ template <typename T> class ThreadLocal {
extern ThreadLocal<unsigned long> rand_next;
#else
-extern LIBC_THREAD_LOCAL unsigned long rand_next;
+extern unsigned long rand_next;
#endif
} // namespace LIBC_NAMESPACE
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sounds like you can change this for GPU, too?
You know, looking into this it's baffling that POSIX made For the GPU, it's unlikely people would be able to use this seriously if it's not thread safe, but the thread local hack isn't really serviceable either. It's prefer a functional reentrant version above anything else. I thought |
This code is also the only user of ThreadLocal, so we could probably delete src/stdlib/rand_util.h if we remove ThreadLocal. |
I thought |
thread local is used in a couple places: |
I'm talking about the |
I am curious about what MT-Safe means exactly here. For example, this function https://android.googlesource.com/platform/bionic/+/android-4.2.2_r1/libc/bionic/tdestroy.c is clearly not to be called concurrently on the same tree, while POSIX and this manpage claims it is MT-safe. I assume it is safe in the sense that it can be invoked concurrently on different trees in the same time, but there is no clarification on this. |
srand and rand do not need to be threadsafe, so it should be permissible to remove thise from rand_next whose only users are srand and rand. This is helpful for the baremetal runtimes where we still need to setup the TLS machinery.
0aef51f
to
97dda8d
Compare
Done |
Looking at some other implementations, it seems like ISO C states that the random seed is per-process, but that multiple threads should be not able to interfere with it? I was looking at So, this to me seems like we'd need to implement some kind of RMW atomic on the underlying state, not just get rid of the thread_local. Honestly, I might try to write it this way since it would solve some issues on the GPU and it's easier than implementing |
FWIW, Bionic uses NetBSD's srandom, which uses a |
I feel like updating this with a CAS loop is a good middle-ground #96692. This also lets the GPU implementation actually work, since previously I couldn't statically initialize it to 1. Though, it's not like CAS loops are cheap, but I didn't want to use actual locks since they're a PITA to make work on the GPU (see the RPC implementation). |
I concur that the single atomic is the best approach for this case. |
Thanks for bringing this to attention, I think we ended up with a good solution. |
srand and rand do not need to be threadsafe, so it should be permissible to remove thise from rand_next whose only users are srand and rand. This is helpful for the baremetal runtimes where we still need to setup the TLS machinery.