// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <memory>
#include <vector>

#include "base/at_exit.h"
#include "base/atomic_sequence_num.h"
#include "base/atomicops.h"
#include "base/barrier_closure.h"
#include "base/bind.h"
#include "base/lazy_instance.h"
#include "base/sys_info.h"
#include "base/threading/platform_thread.h"
#include "base/threading/simple_thread.h"
#include "base/time/time.h"
#include "build/build_config.h"
#include "starboard/types.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace {

base::AtomicSequenceNumber constructed_seq_;
base::AtomicSequenceNumber destructed_seq_;

class ConstructAndDestructLogger {
 public:
  ConstructAndDestructLogger() {
    constructed_seq_.GetNext();
  }
  ~ConstructAndDestructLogger() {
    destructed_seq_.GetNext();
  }

 private:
  DISALLOW_COPY_AND_ASSIGN(ConstructAndDestructLogger);
};

class SlowConstructor {
 public:
  SlowConstructor() : some_int_(0) {
    // Sleep for 1 second to try to cause a race.
    base::PlatformThread::Sleep(base::TimeDelta::FromSeconds(1));
    ++constructed;
    some_int_ = 12;
  }
  int some_int() const { return some_int_; }

  static int constructed;
 private:
  int some_int_;

  DISALLOW_COPY_AND_ASSIGN(SlowConstructor);
};

// static
int SlowConstructor::constructed = 0;

class SlowDelegate : public base::DelegateSimpleThread::Delegate {
 public:
  explicit SlowDelegate(
      base::LazyInstance<SlowConstructor>::DestructorAtExit* lazy)
      : lazy_(lazy) {}

  void Run() override {
    EXPECT_EQ(12, lazy_->Get().some_int());
    EXPECT_EQ(12, lazy_->Pointer()->some_int());
  }

 private:
  base::LazyInstance<SlowConstructor>::DestructorAtExit* lazy_;

  DISALLOW_COPY_AND_ASSIGN(SlowDelegate);
};

}  // namespace

base::LazyInstance<ConstructAndDestructLogger>::DestructorAtExit lazy_logger =
    LAZY_INSTANCE_INITIALIZER;

TEST(LazyInstanceTest, Basic) {
  {
    base::ShadowingAtExitManager shadow;

    EXPECT_FALSE(lazy_logger.IsCreated());
    EXPECT_EQ(0, constructed_seq_.GetNext());
    EXPECT_EQ(0, destructed_seq_.GetNext());

    lazy_logger.Get();
    EXPECT_TRUE(lazy_logger.IsCreated());
    EXPECT_EQ(2, constructed_seq_.GetNext());
    EXPECT_EQ(1, destructed_seq_.GetNext());

    lazy_logger.Pointer();
    EXPECT_TRUE(lazy_logger.IsCreated());
    EXPECT_EQ(3, constructed_seq_.GetNext());
    EXPECT_EQ(2, destructed_seq_.GetNext());
  }
  EXPECT_FALSE(lazy_logger.IsCreated());
  EXPECT_EQ(4, constructed_seq_.GetNext());
  EXPECT_EQ(4, destructed_seq_.GetNext());
}

base::LazyInstance<SlowConstructor>::DestructorAtExit lazy_slow =
    LAZY_INSTANCE_INITIALIZER;

TEST(LazyInstanceTest, ConstructorThreadSafety) {
  {
    base::ShadowingAtExitManager shadow;

    SlowDelegate delegate(&lazy_slow);
    EXPECT_EQ(0, SlowConstructor::constructed);

    base::DelegateSimpleThreadPool pool("lazy_instance_cons", 5);
    pool.AddWork(&delegate, 20);
    EXPECT_EQ(0, SlowConstructor::constructed);

    pool.Start();
    pool.JoinAll();
    EXPECT_EQ(1, SlowConstructor::constructed);
  }
}

namespace {

// DeleteLogger is an object which sets a flag when it's destroyed.
// It accepts a bool* and sets the bool to true when the dtor runs.
class DeleteLogger {
 public:
  DeleteLogger() : deleted_(nullptr) {}
  ~DeleteLogger() { *deleted_ = true; }

  void SetDeletedPtr(bool* deleted) {
    deleted_ = deleted;
  }

 private:
  bool* deleted_;
};

}  // anonymous namespace

TEST(LazyInstanceTest, LeakyLazyInstance) {
  // Check that using a plain LazyInstance causes the dtor to run
  // when the AtExitManager finishes.
  bool deleted1 = false;
  {
    base::ShadowingAtExitManager shadow;
    static base::LazyInstance<DeleteLogger>::DestructorAtExit test =
        LAZY_INSTANCE_INITIALIZER;
    test.Get().SetDeletedPtr(&deleted1);
  }
  EXPECT_TRUE(deleted1);

  // Check that using a *leaky* LazyInstance makes the dtor not run
  // when the AtExitManager finishes.
  bool deleted2 = false;
  {
    base::ShadowingAtExitManager shadow;
    static base::LazyInstance<DeleteLogger>::Leaky
        test = LAZY_INSTANCE_INITIALIZER;
    test.Get().SetDeletedPtr(&deleted2);
  }
  EXPECT_FALSE(deleted2);
}

namespace {

template <size_t alignment>
class AlignedData {
 public:
  AlignedData() = default;
  ~AlignedData() = default;
  alignas(alignment) char data_[alignment];
};

}  // namespace

#define EXPECT_ALIGNED(ptr, align) \
    EXPECT_EQ(0u, reinterpret_cast<uintptr_t>(ptr) & (align - 1))

TEST(LazyInstanceTest, Alignment) {
  using base::LazyInstance;

  // Create some static instances with increasing sizes and alignment
  // requirements. By ordering this way, the linker will need to do some work to
  // ensure proper alignment of the static data.
  static LazyInstance<AlignedData<4>>::DestructorAtExit align4 =
      LAZY_INSTANCE_INITIALIZER;
  static LazyInstance<AlignedData<32>>::DestructorAtExit align32 =
      LAZY_INSTANCE_INITIALIZER;
#if !defined(STARBOARD)
  static LazyInstance<AlignedData<4096>>::DestructorAtExit align4096 =
      LAZY_INSTANCE_INITIALIZER;
#endif

  EXPECT_ALIGNED(align4.Pointer(), 4);
  EXPECT_ALIGNED(align32.Pointer(), 32);
// At least on Raspi, alignas with big alignment numbers does not work and
// that is compliant with C++ standard as the alignment is larger than
// std::max_align_t.
#if !defined(STARBOARD)
  EXPECT_ALIGNED(align4096.Pointer(), 4096);
#endif
}

namespace {

// A class whose constructor busy-loops until it is told to complete
// construction.
class BlockingConstructor {
 public:
  BlockingConstructor() {
    EXPECT_FALSE(WasConstructorCalled());
    base::subtle::NoBarrier_Store(&constructor_called_, 1);
    EXPECT_TRUE(WasConstructorCalled());
    while (!base::subtle::NoBarrier_Load(&complete_construction_))
      base::PlatformThread::YieldCurrentThread();
    done_construction_ = true;
  }

  ~BlockingConstructor() {
    // Restore static state for the next test.
    base::subtle::NoBarrier_Store(&constructor_called_, 0);
    base::subtle::NoBarrier_Store(&complete_construction_, 0);
  }

  // Returns true if BlockingConstructor() was entered.
  static bool WasConstructorCalled() {
    return base::subtle::NoBarrier_Load(&constructor_called_);
  }

  // Instructs BlockingConstructor() that it may now unblock its construction.
  static void CompleteConstructionNow() {
    base::subtle::NoBarrier_Store(&complete_construction_, 1);
  }

  bool done_construction() { return done_construction_; }

 private:
  // Use Atomic32 instead of AtomicFlag for them to be trivially initialized.
  static base::subtle::Atomic32 constructor_called_;
  static base::subtle::Atomic32 complete_construction_;

  bool done_construction_ = false;

  DISALLOW_COPY_AND_ASSIGN(BlockingConstructor);
};

// A SimpleThread running at |thread_priority| which invokes |before_get|
// (optional) and then invokes Get() on the LazyInstance it's assigned.
class BlockingConstructorThread : public base::SimpleThread {
 public:
  BlockingConstructorThread(
      base::ThreadPriority thread_priority,
      base::LazyInstance<BlockingConstructor>::DestructorAtExit* lazy,
      base::OnceClosure before_get)
      : SimpleThread("BlockingConstructorThread", Options(thread_priority)),
        lazy_(lazy),
        before_get_(std::move(before_get)) {}

  void Run() override {
    if (before_get_)
      std::move(before_get_).Run();
    EXPECT_TRUE(lazy_->Get().done_construction());
  }

 private:
  base::LazyInstance<BlockingConstructor>::DestructorAtExit* lazy_;
  base::OnceClosure before_get_;

  DISALLOW_COPY_AND_ASSIGN(BlockingConstructorThread);
};

// static
base::subtle::Atomic32 BlockingConstructor::constructor_called_ = 0;
// static
base::subtle::Atomic32 BlockingConstructor::complete_construction_ = 0;

base::LazyInstance<BlockingConstructor>::DestructorAtExit lazy_blocking =
    LAZY_INSTANCE_INITIALIZER;

}  // namespace

// Tests that if the thread assigned to construct the LazyInstance runs at
// background priority : the foreground threads will yield to it enough for it
// to eventually complete construction.
// This is a regression test for https://crbug.com/797129.
TEST(LazyInstanceTest, PriorityInversionAtInitializationResolves) {
  base::TimeTicks test_begin = base::TimeTicks::Now();

  // Construct BlockingConstructor from a background thread.
  BlockingConstructorThread background_getter(
      base::ThreadPriority::BACKGROUND, &lazy_blocking, base::OnceClosure());
  background_getter.Start();

  while (!BlockingConstructor::WasConstructorCalled())
    base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(1));

  // Spin 4 foreground thread per core contending to get the already under
  // construction LazyInstance. When they are all running and poking at it :
  // allow the background thread to complete its work.
  const int kNumForegroundThreads = 4 * base::SysInfo::NumberOfProcessors();
  std::vector<std::unique_ptr<base::SimpleThread>> foreground_threads;
  base::RepeatingClosure foreground_thread_ready_callback =
      base::BarrierClosure(
          kNumForegroundThreads,
          base::BindOnce(&BlockingConstructor::CompleteConstructionNow));
  for (int i = 0; i < kNumForegroundThreads; ++i) {
    foreground_threads.push_back(std::make_unique<BlockingConstructorThread>(
        base::ThreadPriority::NORMAL, &lazy_blocking,
        foreground_thread_ready_callback));
    foreground_threads.back()->Start();
  }

  // This test will hang if the foreground threads become stuck in
  // LazyInstance::Get() per the background thread never being scheduled to
  // complete construction.
  for (auto& foreground_thread : foreground_threads)
    foreground_thread->Join();
  background_getter.Join();

  // Fail if this test takes more than 5 seconds (it takes 5-10 seconds on a
  // Z840 without r527445 but is expected to be fast (~30ms) with the fix).
  EXPECT_LT(base::TimeTicks::Now() - test_begin,
            base::TimeDelta::FromSeconds(5));
}
