mirror of https://gitee.com/bigwinds/arangodb
Switch to thread-local RandomDevice instances. (#8150)
This commit is contained in:
parent
820ba5dd7c
commit
a0975b4062
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue