[Bug target/94087] std::random_device often fails when used from multiple threads
redi at gcc dot gnu.org
gcc-bugzilla@gcc.gnu.org
Thu May 14 12:01:31 GMT 2020
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94087
--- Comment #21 from Jonathan Wakely <redi at gcc dot gnu.org> ---
(In reply to rguenther@suse.de from comment #18)
> Note in virtualized environments support for RDRAND might be disabled
> while RDSEED is enabled(?) even if no such hardware configuration
> exists [by now]. If I were a chip manufacturer (hello VIA?) that
> at the moment neither implements RDRAND nor RDSEED a good option
> would be to only go for the stronger RDSEED and leave RDRAND
> unimplemented.
So we'd want something like this to check if RDRAND is usable:
--- a/libstdc++-v3/src/c++11/random.cc
+++ b/libstdc++-v3/src/c++11/random.cc
@@ -97,7 +97,7 @@ namespace std _GLIBCXX_VISIBILITY(default)
#if USE_RDSEED
unsigned int
__attribute__ ((target("rdseed")))
- __x86_rdseed(void*)
+ __x86_rdseed(void* fallback)
{
unsigned int retries = 100;
unsigned int val;
@@ -105,12 +105,25 @@ namespace std _GLIBCXX_VISIBILITY(default)
while (__builtin_ia32_rdseed_si_step(&val) == 0)
{
if (--retries == 0)
- std::__throw_runtime_error(__N("random_device: rdseed failed"));
+ {
+ if (auto f = reinterpret_cast<unsigned int(*)(void*)>(fallback))
+ return f(nullptr);
+ std::__throw_runtime_error(__N("random_device: rdseed failed"));
+ }
__builtin_ia32_pause();
}
return val;
}
+
+#if USE_RDRAND
+ unsigned int
+ __attribute__ ((target("rdseed,rdrnd")))
+ __x86_rdseed_rdrand(void*)
+ {
+ return __x86_rdseed(reinterpret_cast<void*>(&__x86_rdrand));
+ }
+#endif
#endif
#ifdef _GLIBCXX_USE_CRT_RAND_S
@@ -205,6 +218,15 @@ namespace std _GLIBCXX_VISIBILITY(default)
__cpuid_count(7, 0, eax, ebx, ecx, edx);
if (ebx & bit_RDSEED)
{
+#ifdef USE_RDRAND
+ // CPUID.01H:ECX.RDRAND[bit 30]
+ __cpuid(1, eax, ebx, ecx, edx);
+ if (ecx & bit_RDRND)
+ {
+ _M_func = &__x86_rdseed_rdrand;
+ return;
+ }
+#endif
_M_func = &__x86_rdseed;
return;
}
More information about the Gcc-bugs
mailing list