// Copyright 2016 The Fuchsia Authors
//
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file or at
// https://opensource.org/licenses/MIT

#include <align.h>

#include <lib/unittest/unittest.h>
#include <fbl/alloc_checker.h>
#include <fbl/arena.h>
#include <vm/vm_aspace.h>

using fbl::Arena;

struct TestObj {
  int xx, yy, zz;
};

static bool init_null_name_succeeds() {
  BEGIN_TEST;
  Arena arena;
  EXPECT_EQ(ZX_OK, arena.Init(nullptr, sizeof(TestObj), 16));
  END_TEST;
}

static bool init_zero_ob_size_fails() {
  BEGIN_TEST;
  Arena arena;
  EXPECT_EQ(ZX_ERR_INVALID_ARGS, arena.Init("name", 0, 16));
  END_TEST;
}

static bool init_large_ob_size_fails() {
  BEGIN_TEST;
  Arena arena;
  EXPECT_EQ(ZX_ERR_INVALID_ARGS, arena.Init("name", PAGE_SIZE + 1, 16));
  END_TEST;
}

static bool init_zero_count_fails() {
  BEGIN_TEST;
  Arena arena;
  EXPECT_EQ(ZX_ERR_INVALID_ARGS, arena.Init("name", sizeof(TestObj), 0));
  END_TEST;
}

static bool start_and_end_look_good() {
  BEGIN_TEST;
  static const size_t num_slots = (2 * PAGE_SIZE) / sizeof(TestObj);
  static const size_t expected_size = num_slots * sizeof(TestObj);

  Arena arena;
  EXPECT_EQ(ZX_OK, arena.Init("name", sizeof(TestObj), num_slots));

  EXPECT_NONNULL(arena.start());
  EXPECT_NONNULL(arena.end());
  auto start = reinterpret_cast<vaddr_t>(arena.start());
  auto end = reinterpret_cast<vaddr_t>(arena.end());
  EXPECT_LT(start, end);
  EXPECT_GE(end - start, expected_size);
  END_TEST;
}

static bool in_range_tests() {
  BEGIN_TEST;
  static const size_t num_slots = (2 * PAGE_SIZE) / sizeof(TestObj);

  Arena arena;
  EXPECT_EQ(ZX_OK, arena.Init("name", sizeof(TestObj), num_slots));

  auto start = reinterpret_cast<char*>(arena.start());

  // Nothing is allocated yet, so not even the start address
  // should be in range.
  EXPECT_FALSE(arena.in_range(start));

  // Allocate some objects, and check that each is within range.
  static const int nobjs = 16;
  void* objs[nobjs];
  for (int i = 0; i < nobjs; i++) {
    char msg[32];
    snprintf(msg, sizeof(msg), "[%d]", i);
    objs[i] = arena.Alloc();
    EXPECT_NONNULL(objs[i], msg);
    // The allocated object should be in range.
    EXPECT_TRUE(arena.in_range(objs[i]), msg);
    // The slot just after this object should not be in range.
    // FRAGILE: assumes that objects are allocated in increasing order.
    EXPECT_FALSE(arena.in_range(reinterpret_cast<TestObj*>(objs[i]) + 1), msg);
    // The count should correspond to the number of times we have
    // allocated.
    EXPECT_EQ(static_cast<size_t>(i + 1), arena.DiagnosticCount(), msg);
  }

  // Deallocate the objects and check whether they're in range.
  for (int i = nobjs - 1; i >= 0; i--) {
    char msg[32];
    snprintf(msg, sizeof(msg), "[%d]", i);
    // The object should still be in range.
    EXPECT_TRUE(arena.in_range(objs[i]), msg);

    arena.Free(objs[i]);

    // The free slot will still be in range.
    // NOTE: If Arena ever learns to coalesce and decommit whole pages of
    // free objects, this test will need to change.
    EXPECT_TRUE(arena.in_range(objs[i]), msg);

    // The count should correspond to the number of times we have
    // deallocated.
    EXPECT_EQ(static_cast<size_t>(i), arena.DiagnosticCount(), msg);
  }
  END_TEST;
}

static bool out_of_memory() {
  BEGIN_TEST;
  static const size_t num_slots = (2 * PAGE_SIZE) / sizeof(TestObj);

  Arena arena;
  EXPECT_EQ(ZX_OK, arena.Init("name", sizeof(TestObj), num_slots));

  // Allocate all of the data objects.
  fbl::AllocChecker ac;
  ktl::unique_ptr<void*[]> objs = ktl::unique_ptr<void*[]>(new (&ac) void*[num_slots]);
  EXPECT_TRUE(ac.check());
  void** top = &objs[0];
  for (size_t i = 0; i < num_slots; i++) {
    char msg[32];
    snprintf(msg, sizeof(msg), "[%zu]", i);
    *top++ = arena.Alloc();
    EXPECT_NONNULL(top[-1], msg);
  }

  // Any further allocations should return nullptr.
  EXPECT_NULL(arena.Alloc());
  EXPECT_NULL(arena.Alloc());
  EXPECT_NULL(arena.Alloc());
  EXPECT_NULL(arena.Alloc());

  // Free two objects.
  arena.Free(*--top);
  arena.Free(*--top);

  // Two allocations should succeed; any further should fail.
  *top++ = arena.Alloc();
  EXPECT_NONNULL(top[-1]);
  *top++ = arena.Alloc();
  EXPECT_NONNULL(top[-1]);
  EXPECT_NULL(arena.Alloc());
  EXPECT_NULL(arena.Alloc());

  // Free all objects.
  // Nothing much to check except that it doesn't crash.
  while (top > objs.get()) {
    arena.Free(*--top);
  }

  END_TEST;
}

// Test helper. Counts the number of committed and uncommitted pages in the
// range. Returns {*committed, *uncommitted} = {0, 0} if |start| doesn't
// correspond to a live VmMapping.
static bool count_committed_pages(vaddr_t start, vaddr_t end, size_t* committed,
                                  size_t* uncommitted) {
  BEGIN_TEST;  // Not a test, but we need these guards to use ASSERT_*
  *committed = 0;
  *uncommitted = 0;

  // Find the VmMapping that covers |start|. Assume that it covers |end-1|.
  const auto region = VmAspace::kernel_aspace()->FindRegion(start);
  ASSERT_NONNULL(region, "FindRegion");
  const auto mapping = region->as_vm_mapping();
  if (mapping == nullptr) {
    // It's a VMAR, not a mapping, so no pages are committed.
    // Return 0/0.
    return true;
  }

  // Ask the VMO how many pages it's allocated within the range.
  auto start_off = ROUNDDOWN(start, PAGE_SIZE) - mapping->base();
  auto end_off = ROUNDUP(end, PAGE_SIZE) - mapping->base();
  *committed = mapping->vmo()->AttributedPagesInRange(start_off + mapping->object_offset(),
                                                      end_off - start_off);
  *uncommitted = (end_off - start_off) / PAGE_SIZE - *committed;
  END_TEST;
}

static bool committing_tests() {
  BEGIN_TEST;
  static const size_t num_slots = (64 * PAGE_SIZE) / sizeof(TestObj);

  Arena arena;
  EXPECT_EQ(ZX_OK, arena.Init("name", sizeof(TestObj), num_slots));

  auto start = reinterpret_cast<vaddr_t>(arena.start());
  auto end = reinterpret_cast<vaddr_t>(arena.end());

  // Nothing is allocated yet, so no pages should be committed.
  size_t committed;
  size_t uncommitted;
  EXPECT_TRUE(count_committed_pages(start, end, &committed, &uncommitted));
  EXPECT_EQ(0u, committed);
  EXPECT_GT(uncommitted, 0u);

  // Allocate an object.
  auto obj = reinterpret_cast<vaddr_t>(arena.Alloc());
  EXPECT_NE(0u, obj);
  size_t atotal = sizeof(TestObj);

  // The page containing the object should be committed.
  auto ps = ROUNDDOWN(obj, PAGE_SIZE);
  auto pe = ROUNDUP(obj + sizeof(TestObj), PAGE_SIZE);
  EXPECT_TRUE(count_committed_pages(ps, pe, &committed, &uncommitted));
  EXPECT_GT(committed, 0u);
  EXPECT_EQ(0u, uncommitted);

  // The first handful of pages should also become committed, but the rest
  // should stay ucommitted.
  EXPECT_TRUE(count_committed_pages(start, end, &committed, &uncommitted));
  EXPECT_GT(committed, 0u);
  EXPECT_GT(uncommitted, 0u);

  // Fill the committed pages with objects; the set of committed pages
  // shouldn't change.
  auto orig_committed = committed;
  auto orig_uncommitted = uncommitted;
  while (atotal + sizeof(TestObj) <= orig_committed * PAGE_SIZE) {
    EXPECT_NONNULL(arena.Alloc());
    atotal += sizeof(TestObj);
  }
  EXPECT_TRUE(count_committed_pages(start, end, &committed, &uncommitted));
  EXPECT_EQ(orig_committed, committed);
  EXPECT_EQ(orig_uncommitted, uncommitted);

  // Allocating one more object should cause more pages to be committed.
  EXPECT_NONNULL(arena.Alloc());
  atotal += sizeof(TestObj);
  EXPECT_TRUE(count_committed_pages(start, end, &committed, &uncommitted));
  EXPECT_LT(orig_committed, committed);
  EXPECT_GT(orig_uncommitted, uncommitted);

  // TODO(dbort): Test uncommitting if Arena ever learns to decommit pages.
  END_TEST;
}

// Friend class that can see inside an Arena.
namespace fbl {
class ArenaTestFriend {
 public:
  ArenaTestFriend(const Arena& arena) : arena_(arena) {}

  constexpr static size_t control_slot_size() { return sizeof(Arena::Node); }

  vaddr_t control_start() const { return reinterpret_cast<vaddr_t>(arena_.control_.start()); }

  vaddr_t control_end() const { return reinterpret_cast<vaddr_t>(arena_.control_.end()); }

 private:
  const Arena& arena_;
};
}  // namespace fbl
using fbl::ArenaTestFriend;

// Hit the decommit code path. We can't observe it without peeking inside the
// control pool, since the data pool doesn't currently decommit.
static bool uncommitting_tests() {
  BEGIN_TEST;
  // Create an arena with a 16-page control pool.
  static const size_t num_pages = 16;
  static const size_t num_slots = (num_pages * PAGE_SIZE) / ArenaTestFriend::control_slot_size();

  Arena arena;
  // Use a small data slot size (1) to keep our memory usage down.
  EXPECT_EQ(ZX_OK, arena.Init("name", 1, num_slots));

  // Get the extent of the control pool.
  vaddr_t start;
  vaddr_t end;
  {
    ArenaTestFriend atf(arena);
    start = reinterpret_cast<vaddr_t>(atf.control_start());
    end = reinterpret_cast<vaddr_t>(atf.control_end());
  }

  // Nothing is allocated yet, so no control pages should be committed.
  size_t committed;
  size_t uncommitted;
  EXPECT_TRUE(count_committed_pages(start, end, &committed, &uncommitted));
  EXPECT_EQ(num_pages, committed + uncommitted);
  EXPECT_EQ(0u, committed);
  EXPECT_GT(uncommitted, 0u);

  // Allocate all of the data objects. Hold onto the pointers so we can free
  // them.
  fbl::AllocChecker ac;
  ktl::unique_ptr<void*[]> objs = ktl::unique_ptr<void*[]>(new (&ac) void*[num_slots]);
  EXPECT_TRUE(ac.check());
  void** top = &objs[0];
  for (size_t i = 0; i < num_slots; i++) {
    char msg[32];
    snprintf(msg, sizeof(msg), "[%zu]", i);
    *top++ = arena.Alloc();
    EXPECT_NONNULL(top[-1], msg);
  }

  // We still shouldn't see any control pages committed, becase no objects
  // have been freed yet.
  EXPECT_TRUE(count_committed_pages(start, end, &committed, &uncommitted));
  EXPECT_EQ(num_pages, committed + uncommitted);
  EXPECT_EQ(0u, committed);
  EXPECT_GT(uncommitted, 0u);

  // Demonstrate that we've allocated all of the data objects.
  void* no = arena.Alloc();
  EXPECT_NULL(no);

  // Free a data object.
  arena.Free(*--top);

  // We should now see some committed pages inside the control pool.
  EXPECT_TRUE(count_committed_pages(start, end, &committed, &uncommitted));
  EXPECT_EQ(num_pages, committed + uncommitted);
  EXPECT_GT(committed, 0u);
  EXPECT_GT(uncommitted, 0u);

  // Free all of the data objects.
  while (top > objs.get()) {
    arena.Free(*--top);
  }

  // All of the control pages should be committed.
  EXPECT_TRUE(count_committed_pages(start, end, &committed, &uncommitted));
  EXPECT_EQ(num_pages, committed + uncommitted);
  EXPECT_EQ(committed, num_pages);
  EXPECT_EQ(uncommitted, 0u);

  // Allocate half of the data objects, freeing up half of the free nodes
  // (and thus half of the control slots).
  auto orig_committed = committed;
  ASSERT_EQ(top, objs.get());
  for (size_t i = 0; i < num_slots / 2; i++) {
    char msg[32];
    snprintf(msg, sizeof(msg), "[%zu]", i);
    *top++ = arena.Alloc();
    EXPECT_NONNULL(top[-1], msg);
  }

  // The number of committed pages should have dropped.
  EXPECT_TRUE(count_committed_pages(start, end, &committed, &uncommitted));
  EXPECT_EQ(num_pages, committed + uncommitted);
  EXPECT_LT(committed, orig_committed);
  EXPECT_GT(uncommitted, 0u);

  // Free more control slots (by allocating data objects) until we see more
  // unmapping happen.
  orig_committed = committed;
  for (size_t i = num_slots / 2; i < num_slots; i++) {
    char msg[32];
    snprintf(msg, sizeof(msg), "[%zu]", i);
    *top++ = arena.Alloc();
    EXPECT_NONNULL(top[-1], msg);

    EXPECT_TRUE(count_committed_pages(start, end, &committed, &uncommitted));
    if (committed != orig_committed) {
      break;
    }
  }
  EXPECT_GT(orig_committed, committed);

  // Allocating one more control slot (by freeing a data object) should not
  // cause the number of committed pages to change: there should be some
  // hysteresis built into the system to avoid flickering back and forth.
  orig_committed = committed;
  arena.Free(*--top);
  EXPECT_TRUE(count_committed_pages(start, end, &committed, &uncommitted));
  EXPECT_EQ(num_pages, committed + uncommitted);
  EXPECT_EQ(committed, orig_committed);
  EXPECT_GT(uncommitted, 0u);

  // Same for freeing a couple more control slots (by allocating more data
  // objects).
  *top++ = arena.Alloc();
  *top++ = arena.Alloc();
  EXPECT_TRUE(count_committed_pages(start, end, &committed, &uncommitted));
  EXPECT_EQ(num_pages, committed + uncommitted);
  EXPECT_EQ(committed, orig_committed);
  EXPECT_GT(uncommitted, 0u);

  END_TEST;
}

// Checks that destroying an arena unmaps all of its pages.
static bool memory_cleanup() {
  BEGIN_TEST;
  static const size_t num_slots = (16 * PAGE_SIZE) / sizeof(TestObj);

  fbl::AllocChecker ac;
  Arena* arena = new (&ac) Arena();
  EXPECT_TRUE(ac.check());
  EXPECT_EQ(ZX_OK, arena->Init("name", sizeof(TestObj), num_slots));

  auto start = reinterpret_cast<vaddr_t>(arena->start());
  auto end = reinterpret_cast<vaddr_t>(arena->end());

  // Allocate and leak a bunch of objects.
  for (size_t i = 0; i < num_slots; i++) {
    char msg[32];
    snprintf(msg, sizeof(msg), "[%zu]", i);
    EXPECT_NONNULL(arena->Alloc(), msg);
  }

  // Should see some committed pages.
  size_t committed;
  size_t uncommitted;
  EXPECT_TRUE(count_committed_pages(start, end, &committed, &uncommitted));
  EXPECT_GT(committed, 0u);

  // Destroying the Arena should destroy the underlying VmMapping,
  // along with all of its pages.
  delete arena;
  EXPECT_TRUE(count_committed_pages(start, end, &committed, &uncommitted));
  // 0/0 means "no mapping at this address".
  // FLAKY: Another thread could could come in and allocate a mapping at the
  // old location.
  EXPECT_EQ(committed, 0u);
  EXPECT_EQ(uncommitted, 0u);
  END_TEST;
}

// Basic checks that the contents of allocated objects stick around, aren't
// stomped on.
static bool content_preservation() {
  BEGIN_TEST;
  Arena arena;
  zx_status_t s = arena.Init("arena_tests", sizeof(TestObj), 1000);
  ASSERT_EQ(ZX_OK, s, "arena.Init()");

  const int count = 30;

  for (int times = 0; times != 5; ++times) {
    TestObj* afp[count] = {0};

    for (int ix = 0; ix != count; ++ix) {
      afp[ix] = reinterpret_cast<TestObj*>(arena.Alloc());
      ASSERT_NONNULL(afp[ix], "arena.Alloc()");
      *afp[ix] = {17, 5, ix + 100};
    }

    arena.Free(afp[3]);
    arena.Free(afp[4]);
    arena.Free(afp[5]);
    afp[3] = afp[4] = afp[5] = nullptr;

    afp[4] = reinterpret_cast<TestObj*>(arena.Alloc());
    ASSERT_NONNULL(afp[4], "arena.Alloc()");
    *afp[4] = {17, 5, 104};

    for (int ix = 0; ix != count; ++ix) {
      if (!afp[ix])
        continue;

      EXPECT_EQ(17, afp[ix]->xx);
      EXPECT_EQ(5, afp[ix]->yy);
      EXPECT_EQ(ix + 100, afp[ix]->zz);

      arena.Free(afp[ix]);
    }

    // Leak a few objects.
    for (int ix = 0; ix != 7; ++ix) {
      TestObj* leak = reinterpret_cast<TestObj*>(arena.Alloc());
      ASSERT_NONNULL(leak, "arena.Alloc()");
      *leak = {2121, 77, 55};
    }
  }
  END_TEST;
}

#define ARENA_UNITTEST(fname) UNITTEST(#fname, fname)

UNITTEST_START_TESTCASE(arena_tests)
ARENA_UNITTEST(init_null_name_succeeds)
ARENA_UNITTEST(init_zero_ob_size_fails)
ARENA_UNITTEST(init_large_ob_size_fails)
ARENA_UNITTEST(init_zero_count_fails)
ARENA_UNITTEST(start_and_end_look_good)
ARENA_UNITTEST(in_range_tests)
ARENA_UNITTEST(out_of_memory)
ARENA_UNITTEST(committing_tests)
ARENA_UNITTEST(uncommitting_tests)
ARENA_UNITTEST(memory_cleanup)
ARENA_UNITTEST(content_preservation)
UNITTEST_END_TESTCASE(arena_tests, "arenatests", "Arena allocator test")
