/*
 * Copyright (C) 2014 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "swap_space.h"

#include <sys/mman.h>

#include <algorithm>
#include <numeric>

#include "base/bit_utils.h"
#include "base/mem_map.h"
#include "base/macros.h"
#include "base/mutex.h"
#include "thread-current-inl.h"

namespace art {

// The chunk size by which the swap file is increased and mapped.
static constexpr size_t kMinimumMapSize = 16 * MB;

static constexpr bool kCheckFreeMaps = false;

template <typename FreeBySizeSet>
static void DumpFreeMap(const FreeBySizeSet& free_by_size) {
  size_t last_size = static_cast<size_t>(-1);
  for (const auto& entry : free_by_size) {
    if (last_size != entry.size) {
      last_size = entry.size;
      LOG(INFO) << "Size " << last_size;
    }
    LOG(INFO) << "  0x" << std::hex << entry.free_by_start_entry->Start()
        << " size=" << std::dec << entry.free_by_start_entry->size;
  }
}

void SwapSpace::RemoveChunk(FreeBySizeSet::const_iterator free_by_size_pos) {
  auto free_by_start_pos = free_by_size_pos->free_by_start_entry;
  free_by_size_.erase(free_by_size_pos);
  free_by_start_.erase(free_by_start_pos);
}

inline void SwapSpace::InsertChunk(const SpaceChunk& chunk) {
  DCHECK_NE(chunk.size, 0u);
  auto insert_result = free_by_start_.insert(chunk);
  DCHECK(insert_result.second);
  free_by_size_.emplace(chunk.size, insert_result.first);
}

SwapSpace::SwapSpace(int fd, size_t initial_size)
    : fd_(fd),
      size_(0),
      lock_("SwapSpace lock", static_cast<LockLevel>(LockLevel::kDefaultMutexLevel - 1)) {
  // Assume that the file is unlinked.

  InsertChunk(NewFileChunk(initial_size));
}

SwapSpace::~SwapSpace() {
  // Unmap all mmapped chunks. Nothing should be allocated anymore at
  // this point, so there should be only full size chunks in free_by_start_.
  for (const SpaceChunk& chunk : free_by_start_) {
    if (munmap(chunk.ptr, chunk.size) != 0) {
      PLOG(ERROR) << "Failed to unmap swap space chunk at "
          << static_cast<const void*>(chunk.ptr) << " size=" << chunk.size;
    }
  }
  // All arenas are backed by the same file. Just close the descriptor.
  close(fd_);
}

template <typename FreeByStartSet, typename FreeBySizeSet>
static size_t CollectFree(const FreeByStartSet& free_by_start, const FreeBySizeSet& free_by_size) {
  if (free_by_start.size() != free_by_size.size()) {
    LOG(FATAL) << "Size: " << free_by_start.size() << " vs " << free_by_size.size();
  }

  // Calculate over free_by_size.
  size_t sum1 = 0;
  for (const auto& entry : free_by_size) {
    sum1 += entry.free_by_start_entry->size;
  }

  // Calculate over free_by_start.
  size_t sum2 = 0;
  for (const auto& entry : free_by_start) {
    sum2 += entry.size;
  }

  if (sum1 != sum2) {
    LOG(FATAL) << "Sum: " << sum1 << " vs " << sum2;
  }
  return sum1;
}

void* SwapSpace::Alloc(size_t size) {
  MutexLock lock(Thread::Current(), lock_);
  size = RoundUp(size, 8U);

  // Check the free list for something that fits.
  // TODO: Smarter implementation. Global biggest chunk, ...
  auto it = free_by_start_.empty()
      ? free_by_size_.end()
      : free_by_size_.lower_bound(FreeBySizeEntry { size, free_by_start_.begin() });
  if (it != free_by_size_.end()) {
    SpaceChunk old_chunk = *it->free_by_start_entry;
    if (old_chunk.size == size) {
      RemoveChunk(it);
    } else {
      // Avoid deallocating and allocating the std::set<> nodes.
      // This would be much simpler if we could use replace() from Boost.Bimap.

      // The free_by_start_ map contains disjoint intervals ordered by the `ptr`.
      // Shrinking the interval does not affect the ordering.
      it->free_by_start_entry->ptr += size;
      it->free_by_start_entry->size -= size;

      auto node = free_by_size_.extract(it);
      node.value().size -= size;
      free_by_size_.insert(std::move(node));
    }
    return old_chunk.ptr;
  } else {
    // Not a big enough free chunk, need to increase file size.
    SpaceChunk new_chunk = NewFileChunk(size);
    if (new_chunk.size != size) {
      // Insert the remainder.
      SpaceChunk remainder = { new_chunk.ptr + size, new_chunk.size - size };
      InsertChunk(remainder);
    }
    return new_chunk.ptr;
  }
}

SwapSpace::SpaceChunk SwapSpace::NewFileChunk(size_t min_size) {
#if !defined(__APPLE__)
  const size_t page_size = MemMap::GetPageSize();
  size_t next_part = std::max(RoundUp(min_size, page_size), RoundUp(kMinimumMapSize, page_size));
  int result = TEMP_FAILURE_RETRY(ftruncate64(fd_, size_ + next_part));
  if (result != 0) {
    PLOG(FATAL) << "Unable to increase swap file.";
  }
  uint8_t* ptr = reinterpret_cast<uint8_t*>(
      mmap(nullptr, next_part, PROT_READ | PROT_WRITE, MAP_SHARED, fd_, size_));
  if (ptr == MAP_FAILED) {
    LOG(ERROR) << "Unable to mmap new swap file chunk.";
    LOG(ERROR) << "Current size: " << size_ << " requested: " << next_part << "/" << min_size;
    LOG(ERROR) << "Free list:";
    DumpFreeMap(free_by_size_);
    LOG(ERROR) << "In free list: " << CollectFree(free_by_start_, free_by_size_);
    PLOG(FATAL) << "Unable to mmap new swap file chunk.";
  }
  size_ += next_part;
  SpaceChunk new_chunk = {ptr, next_part};
  return new_chunk;
#else
  UNUSED(min_size, kMinimumMapSize);
  LOG(FATAL) << "No swap file support on the Mac.";
  UNREACHABLE();
#endif
}

// TODO: Full coalescing.
void SwapSpace::Free(void* ptr, size_t size) {
  MutexLock lock(Thread::Current(), lock_);
  size = RoundUp(size, 8U);

  size_t free_before = 0;
  if (kCheckFreeMaps) {
    free_before = CollectFree(free_by_start_, free_by_size_);
  }

  SpaceChunk chunk = { reinterpret_cast<uint8_t*>(ptr), size };
  auto it = free_by_start_.lower_bound(chunk);
  if (it != free_by_start_.begin()) {
    auto prev = it;
    --prev;
    CHECK_LE(prev->End(), chunk.Start());
    if (prev->End() == chunk.Start()) {
      // Merge *prev with this chunk.
      chunk.size += prev->size;
      chunk.ptr -= prev->size;
      auto erase_pos = free_by_size_.find(FreeBySizeEntry { prev->size, prev });
      DCHECK(erase_pos != free_by_size_.end());
      RemoveChunk(erase_pos);
      // "prev" is invalidated but "it" remains valid.
    }
  }
  if (it != free_by_start_.end()) {
    CHECK_LE(chunk.End(), it->Start());
    if (chunk.End() == it->Start()) {
      // Merge *it with this chunk.
      chunk.size += it->size;
      auto erase_pos = free_by_size_.find(FreeBySizeEntry { it->size, it });
      DCHECK(erase_pos != free_by_size_.end());
      RemoveChunk(erase_pos);
      // "it" is invalidated but we don't need it anymore.
    }
  }
  InsertChunk(chunk);

  if (kCheckFreeMaps) {
    size_t free_after = CollectFree(free_by_start_, free_by_size_);

    if (free_after != free_before + size) {
      DumpFreeMap(free_by_size_);
      CHECK_EQ(free_after, free_before + size) << "Should be " << size << " difference from " << free_before;
    }
  }
}

}  // namespace art
