// 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_manager.h"

#include "base/bind.h"
#include "base/containers/hash_tables.h"
#include "base/containers/mru_cache.h"
#include "base/debug/crash_logging.h"
#include "base/debug/trace_event.h"
#include "base/strings/string_number_conversions.h"
#include "base/synchronization/lock.h"

namespace base {
namespace internal {

DiscardableMemoryManager::DiscardableMemoryManager(
    size_t memory_limit,
    size_t soft_memory_limit,
    TimeDelta hard_memory_limit_expiration_time)
    : allocations_(AllocationMap::NO_AUTO_EVICT),
      bytes_allocated_(0u),
      memory_limit_(memory_limit),
      soft_memory_limit_(soft_memory_limit),
      hard_memory_limit_expiration_time_(hard_memory_limit_expiration_time) {
  BytesAllocatedChanged(bytes_allocated_);
}

DiscardableMemoryManager::~DiscardableMemoryManager() {
  DCHECK(allocations_.empty());
  DCHECK_EQ(0u, bytes_allocated_);
}

void DiscardableMemoryManager::SetMemoryLimit(size_t bytes) {
  AutoLock lock(lock_);
  memory_limit_ = bytes;
  PurgeIfNotUsedSinceTimestampUntilUsageIsWithinLimitWithLockAcquired(
      Now(), memory_limit_);
}

void DiscardableMemoryManager::SetSoftMemoryLimit(size_t bytes) {
  AutoLock lock(lock_);
  soft_memory_limit_ = bytes;
}

void DiscardableMemoryManager::SetHardMemoryLimitExpirationTime(
    TimeDelta hard_memory_limit_expiration_time) {
  AutoLock lock(lock_);
  hard_memory_limit_expiration_time_ = hard_memory_limit_expiration_time;
}

bool DiscardableMemoryManager::ReduceMemoryUsage() {
  return PurgeIfNotUsedSinceHardLimitCutoffUntilWithinSoftMemoryLimit();
}

void DiscardableMemoryManager::ReduceMemoryUsageUntilWithinLimit(size_t bytes) {
  AutoLock lock(lock_);
  PurgeIfNotUsedSinceTimestampUntilUsageIsWithinLimitWithLockAcquired(Now(),
                                                                      bytes);
}

void DiscardableMemoryManager::Register(Allocation* allocation, size_t bytes) {
  AutoLock lock(lock_);
  DCHECK(allocations_.Peek(allocation) == allocations_.end());
  allocations_.Put(allocation, AllocationInfo(bytes));
}

void DiscardableMemoryManager::Unregister(Allocation* allocation) {
  AutoLock lock(lock_);
  AllocationMap::iterator it = allocations_.Peek(allocation);
  DCHECK(it != allocations_.end());
  const AllocationInfo& info = it->second;

  if (info.purgable) {
    size_t bytes_purgable = info.bytes;
    DCHECK_LE(bytes_purgable, bytes_allocated_);
    bytes_allocated_ -= bytes_purgable;
    BytesAllocatedChanged(bytes_allocated_);
  }
  allocations_.Erase(it);
}

bool DiscardableMemoryManager::AcquireLock(Allocation* allocation,
                                           bool* purged) {
  AutoLock lock(lock_);
  // Note: |allocations_| is an MRU cache, and use of |Get| here updates that
  // cache.
  AllocationMap::iterator it = allocations_.Get(allocation);
  DCHECK(it != allocations_.end());
  AllocationInfo* info = &it->second;

  if (!info->bytes)
    return false;

  TimeTicks now = Now();
  size_t bytes_required = info->purgable ? 0u : info->bytes;

  if (memory_limit_) {
    size_t limit = 0;
    if (bytes_required < memory_limit_)
      limit = memory_limit_ - bytes_required;

    PurgeIfNotUsedSinceTimestampUntilUsageIsWithinLimitWithLockAcquired(now,
                                                                        limit);
  }

  // Check for overflow.
  if (std::numeric_limits<size_t>::max() - bytes_required < bytes_allocated_)
    return false;

  *purged = !allocation->AllocateAndAcquireLock();
  info->purgable = false;
  info->last_usage = now;
  if (bytes_required) {
    bytes_allocated_ += bytes_required;
    BytesAllocatedChanged(bytes_allocated_);
  }
  return true;
}

void DiscardableMemoryManager::ReleaseLock(Allocation* allocation) {
  AutoLock lock(lock_);
  // Note: |allocations_| is an MRU cache, and use of |Get| here updates that
  // cache.
  AllocationMap::iterator it = allocations_.Get(allocation);
  DCHECK(it != allocations_.end());
  AllocationInfo* info = &it->second;

  TimeTicks now = Now();
  allocation->ReleaseLock();
  info->purgable = true;
  info->last_usage = now;

  PurgeIfNotUsedSinceTimestampUntilUsageIsWithinLimitWithLockAcquired(
      now, memory_limit_);
}

void DiscardableMemoryManager::PurgeAll() {
  AutoLock lock(lock_);
  PurgeIfNotUsedSinceTimestampUntilUsageIsWithinLimitWithLockAcquired(Now(), 0);
}

bool DiscardableMemoryManager::IsRegisteredForTest(
    Allocation* allocation) const {
  AutoLock lock(lock_);
  AllocationMap::const_iterator it = allocations_.Peek(allocation);
  return it != allocations_.end();
}

bool DiscardableMemoryManager::CanBePurgedForTest(
    Allocation* allocation) const {
  AutoLock lock(lock_);
  AllocationMap::const_iterator it = allocations_.Peek(allocation);
  return it != allocations_.end() && it->second.purgable;
}

size_t DiscardableMemoryManager::GetBytesAllocatedForTest() const {
  AutoLock lock(lock_);
  return bytes_allocated_;
}

bool DiscardableMemoryManager::
    PurgeIfNotUsedSinceHardLimitCutoffUntilWithinSoftMemoryLimit() {
  AutoLock lock(lock_);

  PurgeIfNotUsedSinceTimestampUntilUsageIsWithinLimitWithLockAcquired(
      Now() - hard_memory_limit_expiration_time_, soft_memory_limit_);

  return bytes_allocated_ <= soft_memory_limit_;
}

void DiscardableMemoryManager::
    PurgeIfNotUsedSinceTimestampUntilUsageIsWithinLimitWithLockAcquired(
        TimeTicks timestamp,
        size_t limit) {
  lock_.AssertAcquired();

  size_t bytes_allocated_before_purging = bytes_allocated_;
  for (AllocationMap::reverse_iterator it = allocations_.rbegin();
       it != allocations_.rend();
       ++it) {
    Allocation* allocation = it->first;
    AllocationInfo* info = &it->second;

    if (bytes_allocated_ <= limit)
      break;

    bool purgable = info->purgable && info->last_usage <= timestamp;
    if (!purgable)
      continue;

    size_t bytes_purgable = info->bytes;
    DCHECK_LE(bytes_purgable, bytes_allocated_);
    bytes_allocated_ -= bytes_purgable;
    info->purgable = false;
    allocation->Purge();
  }

  if (bytes_allocated_ != bytes_allocated_before_purging)
    BytesAllocatedChanged(bytes_allocated_);
}

void DiscardableMemoryManager::BytesAllocatedChanged(
    size_t new_bytes_allocated) const {
  TRACE_COUNTER_ID1(
      "base", "DiscardableMemoryUsage", this, new_bytes_allocated);

  static const char kDiscardableMemoryUsageKey[] = "dm-usage";
  base::debug::SetCrashKeyValue(kDiscardableMemoryUsageKey,
                                Uint64ToString(new_bytes_allocated));
}

TimeTicks DiscardableMemoryManager::Now() const {
  return TimeTicks::Now();
}

}  // namespace internal
}  // namespace base
