1
0
Fork 0

Switch to thread-local RandomDevice instances. (#8150)

This commit is contained in:
Manuel Pöter 2019-02-14 15:35:42 +01:00 committed by Jan
parent 820ba5dd7c
commit a0975b4062
3 changed files with 21 additions and 32 deletions

View File

@ -290,10 +290,6 @@
#define TRI_SC_NPROCESSORS_ONLN 1 #define TRI_SC_NPROCESSORS_ONLN 1
#if __llvm__ == 1
#define thread_local __thread
#endif
// alignment and limits // alignment and limits
#if __WORDSIZE == 64 #if __WORDSIZE == 64
@ -789,8 +785,6 @@ typedef unsigned char bool;
#define alloca _alloca #define alloca _alloca
#define thread_local __declspec(thread)
// alignment and limits // alignment and limits
#if __WORDSIZE == 64 #if __WORDSIZE == 64

View File

@ -440,13 +440,19 @@ class RandomDeviceWin32 : public RandomDevice {
// RandomGenerator // RandomGenerator
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
Mutex RandomGenerator::_lock; RandomGenerator::RandomType RandomGenerator::_type;
std::unique_ptr<RandomDevice> RandomGenerator::_device(nullptr); thread_local std::unique_ptr<RandomDevice> RandomGenerator::_device(nullptr);
void RandomGenerator::initialize(RandomType type) { void RandomGenerator::initialize(RandomType type) {
MUTEX_LOCKER(guard, _lock); _type = type;
}
switch (type) { void RandomGenerator::ensureDeviceIsInitialized() {
if (_device) {
return;
}
switch (_type) {
case RandomType::MERSENNE: { case RandomType::MERSENNE: {
_device.reset(new RandomDeviceMersenne()); _device.reset(new RandomDeviceMersenne());
break; break;
@ -467,7 +473,6 @@ void RandomGenerator::initialize(RandomType type) {
_device.reset(new RandomDeviceCombined<600>("/dev/random")); _device.reset(new RandomDeviceCombined<600>("/dev/random"));
break; break;
} }
#endif #endif
#ifdef _WIN32 #ifdef _WIN32
@ -484,7 +489,10 @@ void RandomGenerator::initialize(RandomType type) {
} }
} }
void RandomGenerator::shutdown() { _device.reset(nullptr); } void RandomGenerator::shutdown() {
// nothing to do...
// thread-local devices will be released when their respective threads terminate.
}
int16_t RandomGenerator::interval(int16_t left, int16_t right) { int16_t RandomGenerator::interval(int16_t left, int16_t right) {
uint16_t value = static_cast<int16_t>( uint16_t value = static_cast<int16_t>(
@ -495,13 +503,7 @@ int16_t RandomGenerator::interval(int16_t left, int16_t right) {
} }
int32_t RandomGenerator::interval(int32_t left, int32_t right) { int32_t RandomGenerator::interval(int32_t left, int32_t right) {
MUTEX_LOCKER(locker, _lock); ensureDeviceIsInitialized();
if (_device == nullptr) {
THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_INTERNAL,
"random generator not initialized");
}
int32_t value = _device->interval(left, right); int32_t value = _device->interval(left, right);
TRI_ASSERT(value >= left && value <= right); TRI_ASSERT(value >= left && value <= right);
return value; return value;
@ -561,13 +563,7 @@ uint16_t RandomGenerator::interval(uint16_t right) {
} }
uint32_t RandomGenerator::interval(uint32_t right) { uint32_t RandomGenerator::interval(uint32_t right) {
MUTEX_LOCKER(locker, _lock); ensureDeviceIsInitialized();
if (_device == nullptr) {
THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_INTERNAL,
"random generator not initialized");
}
uint32_t value = _device->interval(static_cast<uint32_t>(0), right); uint32_t value = _device->interval(static_cast<uint32_t>(0), right);
TRI_ASSERT(value <= right); TRI_ASSERT(value <= right);
return value; return value;
@ -603,10 +599,7 @@ uint64_t RandomGenerator::interval(uint64_t right) {
} }
void RandomGenerator::seed(uint64_t seed) { void RandomGenerator::seed(uint64_t seed) {
MUTEX_LOCKER(locker, _lock); ensureDeviceIsInitialized();
if (!_device) {
throw std::runtime_error("Random device not yet initialized!");
}
if (RandomDeviceMersenne* dev = dynamic_cast<RandomDeviceMersenne*>(_device.get())) { if (RandomDeviceMersenne* dev = dynamic_cast<RandomDeviceMersenne*>(_device.get())) {
dev->seed(seed); dev->seed(seed);
return; return;

View File

@ -93,8 +93,10 @@ class RandomGenerator {
static uint64_t interval(uint64_t); static uint64_t interval(uint64_t);
private: private:
static Mutex _lock; static void ensureDeviceIsInitialized();
static std::unique_ptr<RandomDevice> _device;
static RandomType _type;
static thread_local std::unique_ptr<RandomDevice> _device;
}; };
} // namespace arangodb } // namespace arangodb