From a0975b40624dc2fe7bd57354490c397cf0e2b3b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=B6ter?= Date: Thu, 14 Feb 2019 15:35:42 +0100 Subject: [PATCH] Switch to thread-local RandomDevice instances. (#8150) --- lib/Basics/operating-system.h | 6 ----- lib/Random/RandomGenerator.cpp | 41 ++++++++++++++-------------------- lib/Random/RandomGenerator.h | 6 +++-- 3 files changed, 21 insertions(+), 32 deletions(-) diff --git a/lib/Basics/operating-system.h b/lib/Basics/operating-system.h index 2308b8830a..6dbf4f4476 100644 --- a/lib/Basics/operating-system.h +++ b/lib/Basics/operating-system.h @@ -290,10 +290,6 @@ #define TRI_SC_NPROCESSORS_ONLN 1 -#if __llvm__ == 1 -#define thread_local __thread -#endif - // alignment and limits #if __WORDSIZE == 64 @@ -789,8 +785,6 @@ typedef unsigned char bool; #define alloca _alloca -#define thread_local __declspec(thread) - // alignment and limits #if __WORDSIZE == 64 diff --git a/lib/Random/RandomGenerator.cpp b/lib/Random/RandomGenerator.cpp index 9d3ffd8f5b..ca3d7b649a 100644 --- a/lib/Random/RandomGenerator.cpp +++ b/lib/Random/RandomGenerator.cpp @@ -440,13 +440,19 @@ class RandomDeviceWin32 : public RandomDevice { // RandomGenerator // ----------------------------------------------------------------------------- -Mutex RandomGenerator::_lock; -std::unique_ptr RandomGenerator::_device(nullptr); +RandomGenerator::RandomType RandomGenerator::_type; +thread_local std::unique_ptr RandomGenerator::_device(nullptr); void RandomGenerator::initialize(RandomType type) { - MUTEX_LOCKER(guard, _lock); + _type = type; +} - switch (type) { +void RandomGenerator::ensureDeviceIsInitialized() { + if (_device) { + return; + } + + switch (_type) { case RandomType::MERSENNE: { _device.reset(new RandomDeviceMersenne()); break; @@ -467,7 +473,6 @@ void RandomGenerator::initialize(RandomType type) { _device.reset(new RandomDeviceCombined<600>("/dev/random")); break; } - #endif #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) { uint16_t value = static_cast( @@ -495,13 +503,7 @@ int16_t RandomGenerator::interval(int16_t left, int16_t right) { } int32_t RandomGenerator::interval(int32_t left, int32_t right) { - MUTEX_LOCKER(locker, _lock); - - if (_device == nullptr) { - THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_INTERNAL, - "random generator not initialized"); - } - + ensureDeviceIsInitialized(); int32_t value = _device->interval(left, right); TRI_ASSERT(value >= left && value <= right); return value; @@ -561,13 +563,7 @@ uint16_t RandomGenerator::interval(uint16_t right) { } uint32_t RandomGenerator::interval(uint32_t right) { - MUTEX_LOCKER(locker, _lock); - - if (_device == nullptr) { - THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_INTERNAL, - "random generator not initialized"); - } - + ensureDeviceIsInitialized(); uint32_t value = _device->interval(static_cast(0), right); TRI_ASSERT(value <= right); return value; @@ -603,10 +599,7 @@ uint64_t RandomGenerator::interval(uint64_t right) { } void RandomGenerator::seed(uint64_t seed) { - MUTEX_LOCKER(locker, _lock); - if (!_device) { - throw std::runtime_error("Random device not yet initialized!"); - } + ensureDeviceIsInitialized(); if (RandomDeviceMersenne* dev = dynamic_cast(_device.get())) { dev->seed(seed); return; diff --git a/lib/Random/RandomGenerator.h b/lib/Random/RandomGenerator.h index ce21de02df..c871e84749 100644 --- a/lib/Random/RandomGenerator.h +++ b/lib/Random/RandomGenerator.h @@ -93,8 +93,10 @@ class RandomGenerator { static uint64_t interval(uint64_t); private: - static Mutex _lock; - static std::unique_ptr _device; + static void ensureDeviceIsInitialized(); + + static RandomType _type; + static thread_local std::unique_ptr _device; }; } // namespace arangodb