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