xref: /aosp_15_r20/external/cronet/base/memory/discardable_memory.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1 // Copyright 2014 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 "base/memory/discardable_memory.h"
6 
7 #include "base/feature_list.h"
8 #include "base/memory/discardable_memory_internal.h"
9 #include "base/memory/madv_free_discardable_memory_posix.h"
10 #include "base/metrics/field_trial_params.h"
11 #include "base/notreached.h"
12 #include "build/build_config.h"
13 
14 #if BUILDFLAG(IS_ANDROID)
15 #include "third_party/ashmem/ashmem.h"
16 #endif  // BUILDFLAG(IS_ANDROID)
17 
18 namespace base {
19 
20 namespace features {
21 #if BUILDFLAG(IS_POSIX)
22 // Feature flag allowing the use of MADV_FREE discardable memory when there are
23 // multiple supported discardable memory backings.
24 BASE_FEATURE(kMadvFreeDiscardableMemory,
25              "MadvFreeDiscardableMemory",
26              base::FEATURE_DISABLED_BY_DEFAULT);
27 #endif  // BUILDFLAG(IS_POSIX)
28 
29 #if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
30 BASE_FEATURE(kDiscardableMemoryBackingTrial,
31              "DiscardableMemoryBackingTrial",
32              base::FEATURE_DISABLED_BY_DEFAULT);
33 
34 // Association of trial group names to trial group enum. Array order must match
35 // order of DiscardableMemoryTrialGroup enum.
36 const base::FeatureParam<DiscardableMemoryTrialGroup>::Option
37     kDiscardableMemoryBackingParamOptions[] = {
38         {DiscardableMemoryTrialGroup::kEmulatedSharedMemory, "shmem"},
39         {DiscardableMemoryTrialGroup::kMadvFree, "madvfree"},
40         {DiscardableMemoryTrialGroup::kAshmem, "ashmem"}};
41 
42 const base::FeatureParam<DiscardableMemoryTrialGroup>
43     kDiscardableMemoryBackingParam{
44         &kDiscardableMemoryBackingTrial, "DiscardableMemoryBacking",
45         DiscardableMemoryTrialGroup::kEmulatedSharedMemory,
46         &kDiscardableMemoryBackingParamOptions};
47 
48 #endif  // BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_LINUX) ||
49         // BUILDFLAG(IS_CHROMEOS)
50 
51 }  // namespace features
52 
53 namespace {
54 
55 #if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
56 
GetBackingForFieldTrial()57 DiscardableMemoryBacking GetBackingForFieldTrial() {
58   DiscardableMemoryTrialGroup trial_group =
59       GetDiscardableMemoryBackingFieldTrialGroup();
60   switch (trial_group) {
61     case DiscardableMemoryTrialGroup::kEmulatedSharedMemory:
62     case DiscardableMemoryTrialGroup::kAshmem:
63       return DiscardableMemoryBacking::kSharedMemory;
64     case DiscardableMemoryTrialGroup::kMadvFree:
65       return DiscardableMemoryBacking::kMadvFree;
66   }
67   NOTREACHED();
68 }
69 #endif  // BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_LINUX) ||
70         // BUILDFLAG(IS_CHROMEOS)
71 
72 }  // namespace
73 
74 #if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
75 
76 // Probe capabilities of this device to determine whether we should participate
77 // in the discardable memory backing trial.
DiscardableMemoryBackingFieldTrialIsEnabled()78 bool DiscardableMemoryBackingFieldTrialIsEnabled() {
79 #if BUILDFLAG(IS_ANDROID)
80   if (!ashmem_device_is_supported())
81     return false;
82 #endif  // BUILDFLAG(IS_ANDROID)
83   if (base::GetMadvFreeSupport() != base::MadvFreeSupport::kSupported)
84     return false;
85 
86   // IMPORTANT: Only query the feature after we determine the device has the
87   // capabilities required, which will have the side-effect of assigning a
88   // trial-group.
89   return base::FeatureList::IsEnabled(features::kDiscardableMemoryBackingTrial);
90 }
91 
GetDiscardableMemoryBackingFieldTrialGroup()92 DiscardableMemoryTrialGroup GetDiscardableMemoryBackingFieldTrialGroup() {
93   DCHECK(DiscardableMemoryBackingFieldTrialIsEnabled());
94   return features::kDiscardableMemoryBackingParam.Get();
95 }
96 #endif  // BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_LINUX) ||
97         // BUILDFLAG(IS_CHROMEOS)
98 
99 DiscardableMemory::DiscardableMemory() = default;
100 
101 DiscardableMemory::~DiscardableMemory() = default;
102 
GetDiscardableMemoryBacking()103 DiscardableMemoryBacking GetDiscardableMemoryBacking() {
104 #if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
105   if (DiscardableMemoryBackingFieldTrialIsEnabled()) {
106     return GetBackingForFieldTrial();
107   }
108 #endif  // BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_LINUX) ||
109         // BUILDFLAG(IS_CHROMEOS)
110 
111 #if BUILDFLAG(IS_ANDROID)
112   if (ashmem_device_is_supported())
113     return DiscardableMemoryBacking::kSharedMemory;
114 #endif  // BUILDFLAG(IS_ANDROID)
115 
116 #if BUILDFLAG(IS_POSIX)
117   if (base::FeatureList::IsEnabled(
118           base::features::kMadvFreeDiscardableMemory) &&
119       base::GetMadvFreeSupport() == base::MadvFreeSupport::kSupported) {
120     return DiscardableMemoryBacking::kMadvFree;
121   }
122 #endif  // BUILDFLAG(IS_POSIX)
123 
124   return DiscardableMemoryBacking::kSharedMemory;
125 }
126 
127 }  // namespace base
128