/*
 * Copyright (C) 2022 The Android Open Source Project
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *  * Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *  * Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */

#include <malloc.h>
#include <string.h>
#include <unistd.h>

#include <algorithm>
#include <chrono>
#include <iostream>
#include <memory>
#include <random>
#include <thread>
#include <vector>

#include <android-base/strings.h>
#if defined(__BIONIC__)
#include <malloc.h>
#include <meminfo/procmeminfo.h>
#include <procinfo/process_map.h>
#endif

constexpr size_t kMaxThreads = 8;
// The max number of bytes that can be allocated by a thread. Note that each
// allocator may have its own limitation on each size allocation. For example,
// Scudo has a 256 MB limit for each size-class in the primary allocator. The
// amount of memory allocated should not exceed the limit in each allocator.
constexpr size_t kMaxBytes = 1 << 24;
constexpr size_t kMaxLen = kMaxBytes;
void* MemPool[kMaxThreads][kMaxLen];

void dirtyMem(void* ptr, size_t bytes) {
  memset(ptr, 1U, bytes);
}

void ThreadTask(int id, size_t allocSize) {
  // In the following, we will first allocate blocks with kMaxBytes of memory
  // and release all of them in random order. In the end, we will do another
  // round of allocations until it reaches 1/10 kMaxBytes.

  // Total number of blocks
  const size_t maxCounts = kMaxBytes / allocSize;
  // The number of blocks in the end
  const size_t finalCounts = maxCounts / 10;

  for (size_t i = 0; i < maxCounts; ++i) {
    MemPool[id][i] = malloc(allocSize);
    if (MemPool[id][i] == 0) {
      std::cout << "Allocation failure."
                   "Please consider reducing the number of threads"
                << std::endl;
      exit(1);
    }
    dirtyMem(MemPool[id][i], allocSize);
  }

  // Each allocator may apply different strategies to manage the free blocks and
  // each strategy may have different impacts on future memory usage. For
  // example, managing free blocks in simple FIFO list may have its memory usage
  // highly correlated with the blocks releasing pattern. Therefore, release the
  // blocks in random order to observe the impact of free blocks handling.
  unsigned seed = std::chrono::system_clock::now().time_since_epoch().count();
  std::shuffle(MemPool[id], MemPool[id] + maxCounts, std::default_random_engine(seed));
  for (size_t i = 0; i < maxCounts; ++i) {
    free(MemPool[id][i]);
    MemPool[id][i] = nullptr;
  }

  for (size_t i = 0; i < finalCounts; ++i) {
    MemPool[id][i] = malloc(allocSize);
    dirtyMem(MemPool[id][i], allocSize);
  }
}

void StressSizeClass(size_t numThreads, size_t allocSize) {
  // We would like to see the minimum memory usage under aggressive page
  // releasing.
  mallopt(M_DECAY_TIME, 0);

  std::thread* threads[kMaxThreads];
  for (size_t i = 0; i < numThreads; ++i) threads[i] = new std::thread(ThreadTask, i, allocSize);

  for (size_t i = 0; i < numThreads; ++i) {
    threads[i]->join();
    delete threads[i];
  }

  // Do an explicit purge to ensure we will be more likely to get the actual
  // in-use memory.
  mallopt(M_PURGE, 0);

  android::meminfo::ProcMemInfo proc_mem(getpid());
  const std::vector<android::meminfo::Vma>& maps = proc_mem.MapsWithoutUsageStats();
  uint64_t rss_bytes = 0;
  uint64_t vss_bytes = 0;

  for (auto& vma : maps) {
    if (vma.name == "[anon:libc_malloc]" || android::base::StartsWith(vma.name, "[anon:scudo:") ||
        android::base::StartsWith(vma.name, "[anon:GWP-ASan")) {
      android::meminfo::Vma update_vma(vma);
      if (!proc_mem.FillInVmaStats(update_vma)) {
        std::cout << "Failed to parse VMA" << std::endl;
        exit(1);
      }
      rss_bytes += update_vma.usage.rss;
      vss_bytes += update_vma.usage.vss;
    }
  }

  std::cout << "RSS: " << rss_bytes / (1024.0 * 1024.0) << " MB" << std::endl;
  std::cout << "VSS: " << vss_bytes / (1024.0 * 1024.0) << " MB" << std::endl;

  for (size_t i = 0; i < numThreads; ++i) {
    for (size_t j = 0; j < kMaxLen; ++j) free(MemPool[i][j]);
  }
}

int main(int argc, char* argv[]) {
  if (argc != 3) {
    std::cerr << "usage: " << argv[0] << " $NUM_THREADS $ALLOC_SIZE" << std::endl;
    return 1;
  }

  size_t numThreads = atoi(argv[1]);
  size_t allocSize = atoi(argv[2]);

  if (numThreads == 0 || allocSize == 0) {
    std::cerr << "Please provide valid $NUM_THREADS and $ALLOC_SIZE" << std::endl;
    return 1;
  }

  if (numThreads > kMaxThreads) {
    std::cerr << "The max number of threads is " << kMaxThreads << std::endl;
    return 1;
  }

  StressSizeClass(numThreads, allocSize);

  return 0;
}
