// Copyright 2021 The Fuchsia 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 <lib/concurrent/seqlock.h>

#include <chrono>
#include <thread>

#include <zxtest/zxtest.h>

namespace test {

using SeqLock = concurrent::SeqLock<>;

TEST(SeqLock, UncontestedRead) {
  SeqLock lock;

  // With no writer, read transactions should always succeed.
  SeqLock::ReadTransactionToken token1 = lock.BeginReadTransaction();
  ASSERT_TRUE(lock.EndReadTransaction(token1));

  // A second transaction with no write in-between should also succeed, and the
  // reported sequence number should be unchanged.
  SeqLock::ReadTransactionToken token2 = lock.BeginReadTransaction();
  ASSERT_TRUE(lock.EndReadTransaction(token2));
  ASSERT_EQ(token1.seq_num(), token2.seq_num());

  // After a write cycle, further subsequent read transactions should also
  // succeed, but with a different sequence number.
  lock.Acquire();
  lock.Release();
  SeqLock::ReadTransactionToken token3 = lock.BeginReadTransaction();
  ASSERT_TRUE(lock.EndReadTransaction(token3));
  ASSERT_NE(token1.seq_num(), token3.seq_num());
}

TEST(SeqLock, ContestedRead) {
  SeqLock lock;

  // Any write cycle which happens during a read should cause the read
  // transaction to fail.
  SeqLock::ReadTransactionToken token = lock.BeginReadTransaction();

  // Note that to keep life simple, and single threaded, we need to disable
  // clang's static analysis while we go through the write cycle.  While this
  // would not actually deadlock in any way, to clang, it looks like we are
  // attempting to obtain a capability exclusively while we already have
  // acquired that capability for shared access.
  [&]() __TA_NO_THREAD_SAFETY_ANALYSIS {
    lock.Acquire();
    lock.Release();
  }();

  ASSERT_FALSE(lock.EndReadTransaction(token));
}

TEST(SeqLock, ReadTimeouts) {
  SeqLock lock;

  // Trying to begin a read transaction when there is no write-cycle in flight
  // should always succeed, even with a timeout of zero.
  SeqLock::ReadTransactionToken token;
  if (lock.TryBeginReadTransaction(token, 0)) {
    ASSERT_TRUE(lock.EndReadTransaction(token));
  } else {
    ASSERT_TRUE(false);
  }

  // Same is true for deadlines in the past.
  if (lock.TryBeginReadTransactionDeadline(token, 0)) {
    ASSERT_TRUE(lock.EndReadTransaction(token));
  } else {
    ASSERT_TRUE(false);
  }

  // Attempting to start a transaction while a write cycle is in progress should
  // always timeout.
  [&]() __TA_NO_THREAD_SAFETY_ANALYSIS { lock.Acquire(); }();

  if (lock.TryBeginReadTransaction(token, ZX_MSEC(100))) {
    ASSERT_TRUE(lock.EndReadTransaction(token));
    ASSERT_TRUE(false);
  }

  // Unfortunately, we do not have a great way of checking the deadline variant
  // of this assertion, since the OS abstraction being using by the SeqLock
  // implementation is not currently guaranteed to be visible to us.  If we know
  // for sure that we are running on fuchsia, however, we should be able to
  // assume zx_clock_get_monotonic is our proper time reference.  Otherwise, we
  // use a deadline which is almost certainly in the past.  The operation should
  // still fail, it just will not end up spinning at all.
  zx_time_t now{0};
#if defined(__Fuchsia__)
  now = zx_clock_get_monotonic();
#endif
  if (lock.TryBeginReadTransactionDeadline(token, now + ZX_MSEC(100))) {
    ASSERT_TRUE(lock.EndReadTransaction(token));
    ASSERT_TRUE(false);
  }
}

TEST(SeqLock, UncontestedWrite) {
  SeqLock lock;

  // This one seems pretty trivial.  As long as there is only one writer,
  // acquire operations should always immediately succeed (including the
  // timeout/deadline versions, even if their timeout/deadlines are 0 or in the
  // past.
  constexpr uint32_t kTrials = 1000;
  for (uint32_t i = 0; i < kTrials; ++i) {
    lock.Acquire();
    lock.Release();

    if (lock.TryAcquire(0)) {
      lock.Release();
    } else {
      ASSERT_TRUE(false);
    }

    if (lock.TryAcquireDeadline(0)) {
      lock.Release();
    } else {
      ASSERT_TRUE(false);
    }
  }
}

TEST(SeqLock, ContestedWrite) {
  SeqLock lock;

  // Simulate contention, then make sure that all of the timeout forms of
  // Acquire time out.
  [&]() __TA_NO_THREAD_SAFETY_ANALYSIS { lock.Acquire(); }();

  if (lock.TryAcquire(ZX_MSEC(100))) {
    lock.Release();
    ASSERT_TRUE(false);
  }

  zx_time_t now{0};
#if defined(__Fuchsia__)
  now = zx_clock_get_monotonic();
#endif
  if (lock.TryAcquireDeadline(now + ZX_MSEC(100))) {
    lock.Release();
    ASSERT_TRUE(false);
  }

  // Make a best-effort attempt to validate a normal Acquire.
  //
  // Note that this can never be a conclusive test.  In addition to never being
  // able to absolutely guarantee that our test thread has actually started the
  // acquire operation after signaling to us that it has (via the shared bool),
  // no matter how long we wait, we can never actually prove that it the test
  // thread _wouldn't_ have eventually entered the exclusive portion of the lock
  // had we simply waited a bit longer.
  enum class State : uint32_t {
    NotStarted,
    AttemptingAcquire,
    AcquireSucceeded,
  };
  static_assert(std::atomic<State>::is_always_lock_free);

  std::atomic<State> state{State::NotStarted};
  std::thread acquire_thread([&]() {
    state.store(State::AttemptingAcquire);
    lock.Acquire();
    state.store(State::AcquireSucceeded);
    lock.Release();
  });

  // Wait forever for the thread start it's acquire attempt.
  while (state.load() != State::AttemptingAcquire) {
    // empty body.  Just spinning.
  }

  // Wait just a bit, then verify that the test thread has still not acquired
  // the lock.
  std::chrono::duration<int64_t, std::milli> delay{500};
  std::this_thread::sleep_for(delay);
  EXPECT_EQ(State::AttemptingAcquire, state.load());

  // Release the lock and verify that the test thread successfully acquires and
  // release it.
  [&]() __TA_NO_THREAD_SAFETY_ANALYSIS { lock.Release(); }();
  while (state.load() != State::AcquireSucceeded) {
    // empty body.  Just spinning.
  }

  // We should now be able to bounce through the lock without any significant
  // delay. The test thread may still be in the process of releasing the lock,
  // but it should eventually succeed.
  lock.Acquire();
  lock.Release();

  // The acquire_thread may not have exited yet, but it should do so in short
  // order.
  acquire_thread.join();
}

}  // namespace test
