//===-- secondary_test.cpp --------------------------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "tests/scudo_unit_test.h"

#include "secondary.h"

#include <stdio.h>

#include <condition_variable>
#include <mutex>
#include <random>
#include <thread>
#include <vector>

template <class SecondaryT> static void testSecondaryBasic(void) {
  scudo::GlobalStats S;
  S.init();
  SecondaryT *L = new SecondaryT;
  L->init(&S);
  const scudo::uptr Size = 1U << 16;
  void *P = L->allocate(Size);
  EXPECT_NE(P, nullptr);
  memset(P, 'A', Size);
  EXPECT_GE(SecondaryT::getBlockSize(P), Size);
  L->deallocate(P);
  // If the Secondary can't cache that pointer, it will be unmapped.
  if (!SecondaryT::canCache(Size))
    EXPECT_DEATH(memset(P, 'A', Size), "");

  const scudo::uptr Align = 1U << 16;
  P = L->allocate(Size + Align, Align);
  EXPECT_NE(P, nullptr);
  void *AlignedP = reinterpret_cast<void *>(
      scudo::roundUpTo(reinterpret_cast<scudo::uptr>(P), Align));
  memset(AlignedP, 'A', Size);
  L->deallocate(P);

  std::vector<void *> V;
  for (scudo::uptr I = 0; I < 32U; I++)
    V.push_back(L->allocate(Size));
  std::shuffle(V.begin(), V.end(), std::mt19937(std::random_device()()));
  while (!V.empty()) {
    L->deallocate(V.back());
    V.pop_back();
  }
  scudo::ScopedString Str(1024);
  L->getStats(&Str);
  Str.output();
}

TEST(ScudoSecondaryTest, SecondaryBasic) {
  testSecondaryBasic<scudo::MapAllocator<scudo::MapAllocatorNoCache>>();
#if !SCUDO_FUCHSIA
  testSecondaryBasic<scudo::MapAllocator<scudo::MapAllocatorCache<>>>();
  testSecondaryBasic<
      scudo::MapAllocator<scudo::MapAllocatorCache<64U, 1UL << 20>>>();
#endif
}

#if SCUDO_FUCHSIA
using LargeAllocator = scudo::MapAllocator<scudo::MapAllocatorNoCache>;
#else
using LargeAllocator = scudo::MapAllocator<scudo::MapAllocatorCache<>>;
#endif

// This exercises a variety of combinations of size and alignment for the
// MapAllocator. The size computation done here mimic the ones done by the
// combined allocator.
TEST(ScudoSecondaryTest, SecondaryCombinations) {
  constexpr scudo::uptr MinAlign = FIRST_32_SECOND_64(8, 16);
  constexpr scudo::uptr HeaderSize = scudo::roundUpTo(8, MinAlign);
  LargeAllocator *L = new LargeAllocator;
  L->init(nullptr);
  for (scudo::uptr SizeLog = 0; SizeLog <= 20; SizeLog++) {
    for (scudo::uptr AlignLog = FIRST_32_SECOND_64(3, 4); AlignLog <= 16;
         AlignLog++) {
      const scudo::uptr Align = 1U << AlignLog;
      for (scudo::sptr Delta = -128; Delta <= 128; Delta += 8) {
        if (static_cast<scudo::sptr>(1U << SizeLog) + Delta <= 0)
          continue;
        const scudo::uptr UserSize =
            scudo::roundUpTo((1U << SizeLog) + Delta, MinAlign);
        const scudo::uptr Size =
            HeaderSize + UserSize + (Align > MinAlign ? Align - HeaderSize : 0);
        void *P = L->allocate(Size, Align);
        EXPECT_NE(P, nullptr);
        void *AlignedP = reinterpret_cast<void *>(
            scudo::roundUpTo(reinterpret_cast<scudo::uptr>(P), Align));
        memset(AlignedP, 0xff, UserSize);
        L->deallocate(P);
      }
    }
  }
  scudo::ScopedString Str(1024);
  L->getStats(&Str);
  Str.output();
}

TEST(ScudoSecondaryTest, SecondaryIterate) {
  LargeAllocator *L = new LargeAllocator;
  L->init(nullptr);
  std::vector<void *> V;
  const scudo::uptr PageSize = scudo::getPageSizeCached();
  for (scudo::uptr I = 0; I < 32U; I++)
    V.push_back(L->allocate((std::rand() % 16) * PageSize));
  auto Lambda = [V](scudo::uptr Block) {
    EXPECT_NE(std::find(V.begin(), V.end(), reinterpret_cast<void *>(Block)),
              V.end());
  };
  L->disable();
  L->iterateOverBlocks(Lambda);
  L->enable();
  while (!V.empty()) {
    L->deallocate(V.back());
    V.pop_back();
  }
  scudo::ScopedString Str(1024);
  L->getStats(&Str);
  Str.output();
}

static std::mutex Mutex;
static std::condition_variable Cv;
static bool Ready = false;

static void performAllocations(LargeAllocator *L) {
  std::vector<void *> V;
  const scudo::uptr PageSize = scudo::getPageSizeCached();
  {
    std::unique_lock<std::mutex> Lock(Mutex);
    while (!Ready)
      Cv.wait(Lock);
  }
  for (scudo::uptr I = 0; I < 128U; I++) {
    // Deallocate 75% of the blocks.
    const bool Deallocate = (rand() & 3) != 0;
    void *P = L->allocate((std::rand() % 16) * PageSize);
    if (Deallocate)
      L->deallocate(P);
    else
      V.push_back(P);
  }
  while (!V.empty()) {
    L->deallocate(V.back());
    V.pop_back();
  }
}

TEST(ScudoSecondaryTest, SecondaryThreadsRace) {
  LargeAllocator *L = new LargeAllocator;
  L->init(nullptr, /*ReleaseToOsInterval=*/0);
  std::thread Threads[16];
  for (scudo::uptr I = 0; I < ARRAY_SIZE(Threads); I++)
    Threads[I] = std::thread(performAllocations, L);
  {
    std::unique_lock<std::mutex> Lock(Mutex);
    Ready = true;
    Cv.notify_all();
  }
  for (auto &T : Threads)
    T.join();
  scudo::ScopedString Str(1024);
  L->getStats(&Str);
  Str.output();
}
