// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "base/memory/discardable_memory_mach.h"

#include <mach/mach.h>

#include "base/basictypes.h"
#include "base/compiler_specific.h"
#include "base/lazy_instance.h"
#include "base/logging.h"
#include "base/mac/mach_logging.h"

namespace base {
namespace {

// For Mach, have the DiscardableMemoryManager trigger userspace eviction when
// address space usage gets too high (e.g. 512 MBytes).
const size_t kMachMemoryLimit = 512 * 1024 * 1024;

struct SharedState {
  SharedState()
      : manager(kMachMemoryLimit, kMachMemoryLimit, TimeDelta::Max()) {}

  internal::DiscardableMemoryManager manager;
};
LazyInstance<SharedState>::Leaky g_shared_state = LAZY_INSTANCE_INITIALIZER;

// The VM subsystem allows tagging of memory and 240-255 is reserved for
// application use (see mach/vm_statistics.h). Pick 252 (after chromium's atomic
// weight of ~52).
const int kDiscardableMemoryTag = VM_MAKE_TAG(252);

}  // namespace

namespace internal {

DiscardableMemoryMach::DiscardableMemoryMach(size_t bytes)
    : memory_(0, 0), bytes_(mach_vm_round_page(bytes)), is_locked_(false) {
  g_shared_state.Pointer()->manager.Register(this, bytes);
}

DiscardableMemoryMach::~DiscardableMemoryMach() {
  if (is_locked_)
    Unlock();
  g_shared_state.Pointer()->manager.Unregister(this);
}

// static
void DiscardableMemoryMach::PurgeForTesting() {
  int state = 0;
  vm_purgable_control(mach_task_self(), 0, VM_PURGABLE_PURGE_ALL, &state);
}

bool DiscardableMemoryMach::Initialize() {
  return Lock() != DISCARDABLE_MEMORY_LOCK_STATUS_FAILED;
}

DiscardableMemoryLockStatus DiscardableMemoryMach::Lock() {
  DCHECK(!is_locked_);

  bool purged = false;
  if (!g_shared_state.Pointer()->manager.AcquireLock(this, &purged))
    return DISCARDABLE_MEMORY_LOCK_STATUS_FAILED;

  is_locked_ = true;
  return purged ? DISCARDABLE_MEMORY_LOCK_STATUS_PURGED
                : DISCARDABLE_MEMORY_LOCK_STATUS_SUCCESS;
}

void DiscardableMemoryMach::Unlock() {
  DCHECK(is_locked_);
  g_shared_state.Pointer()->manager.ReleaseLock(this);
  is_locked_ = false;
}

void* DiscardableMemoryMach::Memory() const {
  DCHECK(is_locked_);
  return reinterpret_cast<void*>(memory_.address());
}

bool DiscardableMemoryMach::AllocateAndAcquireLock() {
  kern_return_t ret;
  bool persistent;
  if (!memory_.size()) {
    vm_address_t address = 0;
    ret = vm_allocate(
        mach_task_self(),
        &address,
        bytes_,
        VM_FLAGS_ANYWHERE | VM_FLAGS_PURGABLE | kDiscardableMemoryTag);
    MACH_CHECK(ret == KERN_SUCCESS, ret) << "vm_allocate";
    memory_.reset(address, bytes_);

    // When making a fresh allocation, it's impossible for |persistent| to
    // be true.
    persistent = false;
  } else {
    // |persistent| will be reset to false below if appropriate, but when
    // reusing an existing allocation, it's possible for it to be true.
    persistent = true;

#if !defined(NDEBUG)
    ret = vm_protect(mach_task_self(),
                     memory_.address(),
                     memory_.size(),
                     FALSE,
                     VM_PROT_DEFAULT);
    MACH_DCHECK(ret == KERN_SUCCESS, ret) << "vm_protect";
#endif
  }

  int state = VM_PURGABLE_NONVOLATILE;
  ret = vm_purgable_control(
      mach_task_self(), memory_.address(), VM_PURGABLE_SET_STATE, &state);
  MACH_CHECK(ret == KERN_SUCCESS, ret) << "vm_purgable_control";
  if (state & VM_PURGABLE_EMPTY)
    persistent = false;

  return persistent;
}

void DiscardableMemoryMach::ReleaseLock() {
  int state = VM_PURGABLE_VOLATILE | VM_VOLATILE_GROUP_DEFAULT;
  kern_return_t ret = vm_purgable_control(
      mach_task_self(), memory_.address(), VM_PURGABLE_SET_STATE, &state);
  MACH_CHECK(ret == KERN_SUCCESS, ret) << "vm_purgable_control";

#if !defined(NDEBUG)
  ret = vm_protect(
      mach_task_self(), memory_.address(), memory_.size(), FALSE, VM_PROT_NONE);
  MACH_DCHECK(ret == KERN_SUCCESS, ret) << "vm_protect";
#endif
}

void DiscardableMemoryMach::Purge() {
  memory_.reset();
}

}  // namespace internal
}  // namespace base
