//===-- wrappers_cpp_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 <atomic>
#include <condition_variable>
#include <mutex>
#include <thread>
#include <vector>

void operator delete(void *, size_t) noexcept;
void operator delete[](void *, size_t) noexcept;

// Note that every Cxx allocation function in the test binary will be fulfilled
// by Scudo. See the comment in the C counterpart of this file.

template <typename T> static void testCxxNew() {
  T *P = new T;
  EXPECT_NE(P, nullptr);
  memset(P, 0x42, sizeof(T));
  EXPECT_DEATH(delete[] P, "");
  delete P;
  EXPECT_DEATH(delete P, "");

  P = new T;
  EXPECT_NE(P, nullptr);
  memset(P, 0x42, sizeof(T));
  operator delete(P, sizeof(T));

  P = new (std::nothrow) T;
  EXPECT_NE(P, nullptr);
  memset(P, 0x42, sizeof(T));
  delete P;

  const size_t N = 16U;
  T *A = new T[N];
  EXPECT_NE(A, nullptr);
  memset(A, 0x42, sizeof(T) * N);
  EXPECT_DEATH(delete A, "");
  delete[] A;
  EXPECT_DEATH(delete[] A, "");

  A = new T[N];
  EXPECT_NE(A, nullptr);
  memset(A, 0x42, sizeof(T) * N);
  operator delete[](A, sizeof(T) * N);

  A = new (std::nothrow) T[N];
  EXPECT_NE(A, nullptr);
  memset(A, 0x42, sizeof(T) * N);
  delete[] A;
}

class Pixel {
public:
  enum class Color { Red, Green, Blue };
  int X = 0;
  int Y = 0;
  Color C = Color::Red;
};

TEST(ScudoWrappersCppTest, New) {
  if (getenv("SKIP_TYPE_MISMATCH")) {
    printf("Skipped type mismatch tests.\n");
    return;
  }
  testCxxNew<bool>();
  testCxxNew<uint8_t>();
  testCxxNew<uint16_t>();
  testCxxNew<uint32_t>();
  testCxxNew<uint64_t>();
  testCxxNew<float>();
  testCxxNew<double>();
  testCxxNew<long double>();
  testCxxNew<Pixel>();
}

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

static void stressNew() {
  std::vector<uintptr_t *> V;
  {
    std::unique_lock<std::mutex> Lock(Mutex);
    while (!Ready)
      Cv.wait(Lock);
  }
  for (size_t I = 0; I < 256U; I++) {
    const size_t N = std::rand() % 128U;
    uintptr_t *P = new uintptr_t[N];
    if (P) {
      memset(P, 0x42, sizeof(uintptr_t) * N);
      V.push_back(P);
    }
  }
  while (!V.empty()) {
    delete[] V.back();
    V.pop_back();
  }
}

TEST(ScudoWrappersCppTest, ThreadedNew) {
  Ready = false;
  std::thread Threads[32];
  for (size_t I = 0U; I < sizeof(Threads) / sizeof(Threads[0]); I++)
    Threads[I] = std::thread(stressNew);
  {
    std::unique_lock<std::mutex> Lock(Mutex);
    Ready = true;
    Cv.notify_all();
  }
  for (auto &T : Threads)
    T.join();
}

#if !SCUDO_FUCHSIA
// TODO(kostyak): for me, this test fails in a specific configuration when ran
//                by itself with some Scudo or GWP-ASan violation. Other people
//                can't seem to reproduce the failure. Consider skipping this in
//                the event it fails on the upstream bots.
TEST(ScudoWrappersCppTest, AllocAfterFork) {
  std::atomic_bool Stop;

  // Create threads that simply allocate and free different sizes.
  std::vector<std::thread *> Threads;
  for (size_t N = 0; N < 5; N++) {
    std::thread *T = new std::thread([&Stop] {
      while (!Stop) {
        for (size_t SizeLog = 3; SizeLog <= 21; SizeLog++) {
          char *P = new char[1UL << SizeLog];
          EXPECT_NE(P, nullptr);
          // Make sure this value is not optimized away.
          asm volatile("" : : "r,m"(P) : "memory");
          delete[] P;
        }
      }
    });
    Threads.push_back(T);
  }

  // Create a thread to fork and allocate.
  for (size_t N = 0; N < 100; N++) {
    pid_t Pid;
    if ((Pid = fork()) == 0) {
      for (size_t SizeLog = 3; SizeLog <= 21; SizeLog++) {
        char *P = new char[1UL << SizeLog];
        EXPECT_NE(P, nullptr);
        // Make sure this value is not optimized away.
        asm volatile("" : : "r,m"(P) : "memory");
        // Make sure we can touch all of the allocation.
        memset(P, 0x32, 1U << SizeLog);
        // EXPECT_LE(1U << SizeLog, malloc_usable_size(ptr));
        delete[] P;
      }
      _exit(10);
    }
    EXPECT_NE(-1, Pid);
    int Status;
    EXPECT_EQ(Pid, waitpid(Pid, &Status, 0));
    EXPECT_FALSE(WIFSIGNALED(Status));
    EXPECT_EQ(10, WEXITSTATUS(Status));
  }

  printf("Waiting for threads to complete\n");
  Stop = true;
  for (auto Thread : Threads)
    Thread->join();
  Threads.clear();
}
#endif
