random.cc 1.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. // Copyright 2019 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "base/allocator/partition_allocator/random.h"
  5. #include <type_traits>
  6. #include "base/allocator/partition_allocator/partition_alloc_base/rand_util.h"
  7. #include "base/allocator/partition_allocator/partition_alloc_base/thread_annotations.h"
  8. #include "base/allocator/partition_allocator/partition_lock.h"
  9. namespace partition_alloc {
  10. class RandomGenerator {
  11. public:
  12. constexpr RandomGenerator() {}
  13. uint32_t RandomValue() {
  14. ::partition_alloc::internal::ScopedGuard guard(lock_);
  15. return GetGenerator()->RandUint32();
  16. }
  17. void SeedForTesting(uint64_t seed) {
  18. ::partition_alloc::internal::ScopedGuard guard(lock_);
  19. GetGenerator()->ReseedForTesting(seed);
  20. }
  21. private:
  22. ::partition_alloc::internal::Lock lock_ = {};
  23. bool initialized_ PA_GUARDED_BY(lock_) = false;
  24. union {
  25. internal::base::InsecureRandomGenerator instance_ PA_GUARDED_BY(lock_);
  26. uint8_t instance_buffer_[sizeof(
  27. internal::base::InsecureRandomGenerator)] PA_GUARDED_BY(lock_) = {};
  28. };
  29. internal::base::InsecureRandomGenerator* GetGenerator()
  30. PA_EXCLUSIVE_LOCKS_REQUIRED(lock_) {
  31. if (!initialized_) {
  32. new (instance_buffer_) internal::base::InsecureRandomGenerator();
  33. initialized_ = true;
  34. }
  35. return &instance_;
  36. }
  37. };
  38. // Note: this is redundant, since the anonymous union is incompatible with a
  39. // non-trivial default destructor. Not meant to be destructed anyway.
  40. static_assert(std::is_trivially_destructible<RandomGenerator>::value, "");
  41. namespace {
  42. RandomGenerator g_generator = {};
  43. } // namespace
  44. namespace internal {
  45. uint32_t RandomValue() {
  46. return g_generator.RandomValue();
  47. }
  48. } // namespace internal
  49. void SetMmapSeedForTesting(uint64_t seed) {
  50. return g_generator.SeedForTesting(seed);
  51. }
  52. } // namespace partition_alloc