lib: Removed global variables from module math for thread safety#237
lib: Removed global variables from module math for thread safety#237jow- merged 1 commit intojow-:masterfrom
Conversation
|
Isn't that overengineered? The 'srand_called' boolean is a cheap hack to prevent that srand() (and mainly gettimeofday(), I suppose) will be called when rand() is never called. Just to save some computer cycles. I wouldn't be surprised if calling 'uc_vm_registry_set(vm, "math.srand_called", ucv_boolean_new(false));' in uc_module_init() is more expensive than calling gettimeofday()+srand(). So why not call srand() in uc_module_init(), and just skip the whole 'srand_called', removing the necessity of doing the expensive check of the registry in uc_rand()? Apart from that, I always thought you have to call srand() once in each thread. But now I checked, and that isn't true, at least not for musl and glibc. In musl the implementation of srand()/rand() is: So there is only one global variable for all threads. When you call rand() from several threads simultaneously that will add some extra randomness, I suppose? ;) Glibc is more sophisticated: where 'unsafe_state' is a static struct. So in both cases srand() has only to be called once in the whole process. Which the original implementation with a single global 'srand_called' boolean was perfectly able to accomplish. (Well, not completely. When you would run 2 scripts in 2 threads which would call math.rand() for the first time on the same moment, it is possible that one of the two would return with an unseeded 'random' value.) |
|
The intended logic here is modeled after Perl's
So the idea is that naively calling Always calling
I guess the expectation is that each thread in an application gets a different sequence of random numbers when calling Am I missing something here, or am I overthinking it? The |
Signed-off-by: Sebastian Ertz <sebastian.ertz@gmx.de>
|
Pushed after adjusting the commit subject. Thanks! |
The
srand_calledis stored in a registry entry.