1// Copyright 2014 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
5#include "base/memory/discardable_memory.h"
6
7#include "base/lazy_instance.h"
8#include "base/logging.h"
9
10namespace base {
11namespace {
12
13const struct TypeNamePair {
14  DiscardableMemoryType type;
15  const char* name;
16} kTypeNamePairs[] = {
17  { DISCARDABLE_MEMORY_TYPE_ASHMEM, "ashmem" },
18  { DISCARDABLE_MEMORY_TYPE_MAC, "mac" },
19  { DISCARDABLE_MEMORY_TYPE_EMULATED, "emulated" },
20  { DISCARDABLE_MEMORY_TYPE_MALLOC, "malloc" }
21};
22
23DiscardableMemoryType g_preferred_type = DISCARDABLE_MEMORY_TYPE_NONE;
24
25struct DefaultPreferredType {
26  DefaultPreferredType() : value(DISCARDABLE_MEMORY_TYPE_NONE) {
27    std::vector<DiscardableMemoryType> supported_types;
28    DiscardableMemory::GetSupportedTypes(&supported_types);
29    DCHECK(!supported_types.empty());
30    value = supported_types[0];
31  }
32  DiscardableMemoryType value;
33};
34LazyInstance<DefaultPreferredType>::Leaky g_default_preferred_type =
35    LAZY_INSTANCE_INITIALIZER;
36
37}  // namespace
38
39// static
40DiscardableMemoryType DiscardableMemory::GetNamedType(
41    const std::string& name) {
42  for (size_t i = 0; i < arraysize(kTypeNamePairs); ++i) {
43    if (name == kTypeNamePairs[i].name)
44      return kTypeNamePairs[i].type;
45  }
46
47  return DISCARDABLE_MEMORY_TYPE_NONE;
48}
49
50// static
51const char* DiscardableMemory::GetTypeName(DiscardableMemoryType type) {
52  for (size_t i = 0; i < arraysize(kTypeNamePairs); ++i) {
53    if (type == kTypeNamePairs[i].type)
54      return kTypeNamePairs[i].name;
55  }
56
57  return "unknown";
58}
59
60// static
61void DiscardableMemory::SetPreferredType(DiscardableMemoryType type) {
62  // NONE is a reserved value and not a valid default type.
63  DCHECK_NE(DISCARDABLE_MEMORY_TYPE_NONE, type);
64
65  // Make sure this function is only called once before the first call
66  // to GetPreferredType().
67  DCHECK_EQ(DISCARDABLE_MEMORY_TYPE_NONE, g_preferred_type);
68
69  g_preferred_type = type;
70}
71
72// static
73DiscardableMemoryType DiscardableMemory::GetPreferredType() {
74  if (g_preferred_type == DISCARDABLE_MEMORY_TYPE_NONE)
75    g_preferred_type = g_default_preferred_type.Get().value;
76
77  return g_preferred_type;
78}
79
80// static
81scoped_ptr<DiscardableMemory> DiscardableMemory::CreateLockedMemory(
82    size_t size) {
83  return CreateLockedMemoryWithType(GetPreferredType(), size);
84}
85
86}  // namespace base
87