// 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 "third_party/iwlwifi/platform/rcu-manager.h"

#include <lib/async-testing/test_loop.h>
#include <lib/sync/completion.h>
#include <zircon/time.h>

#include <memory>
#include <thread>

#include <gtest/gtest.h>

namespace wlan::testing {
namespace {

TEST(RcuManagerTest, NestedReadLock) {
  auto test_loop = std::make_unique<::async::TestLoop>();
  auto manager = std::make_unique<::wlan::iwlwifi::RcuManager>(test_loop->dispatcher());

  manager->InitForThread();
  manager->ReadLock();

  // Call RcuManager::Sync() on another thread.
  bool synced = false;
  std::thread sync_thread([&]() {
    manager->InitForThread();
    manager->Sync();
    synced = true;
  });
  EXPECT_FALSE(synced);

  // Nesting a lock and then unlocking it (without unlocking the outer lock) should not cause the
  // Sync() call to complete yet.
  manager->ReadLock();
  EXPECT_FALSE(synced);
  manager->ReadUnlock();
  EXPECT_FALSE(synced);

  // Unlocking the lock a final time should allow the Sync() call to finish.
  manager->ReadUnlock();
  sync_thread.join();
  EXPECT_TRUE(synced);
}

TEST(RcuManagerTest, ThreadedReadLock) {
  auto test_loop = std::make_unique<::async::TestLoop>();
  auto manager = std::make_unique<::wlan::iwlwifi::RcuManager>(test_loop->dispatcher());

  manager->InitForThread();
  manager->ReadLock();

  // Perform a read-side lock on another thread.
  sync_completion_t thread_started = {};
  sync_completion_t thread_continue = {};
  std::thread lock_thread([&]() {
    manager->InitForThread();
    manager->ReadLock();
    sync_completion_signal(&thread_started);
    sync_completion_wait(&thread_continue, ZX_TIME_INFINITE);
    manager->ReadUnlock();
  });

  // Wait for the other thread to read-side lock.
  sync_completion_wait(&thread_started, ZX_TIME_INFINITE);

  // Start a thread that waits for a sync.
  bool synced = false;
  std::thread sync_thread([&]() {
    manager->InitForThread();
    manager->Sync();
    synced = true;
  });
  EXPECT_FALSE(synced);

  // Unlocking this thread still means another thread is holding the read-side lock.
  manager->ReadUnlock();
  EXPECT_FALSE(synced);

  // Unlocking the other thread finally allows the Sync() to complete.
  sync_completion_signal(&thread_continue);
  lock_thread.join();
  sync_thread.join();
  EXPECT_TRUE(synced);
}

TEST(RcuManagerTest, CallSync) {
  auto test_loop = std::make_unique<::async::TestLoop>();
  auto manager = std::make_unique<::wlan::iwlwifi::RcuManager>(test_loop->dispatcher());

  manager->InitForThread();
  manager->ReadLock();

  // Prepare a call that will execute after all read-side locks are unlocked.
  bool called = false;
  manager->CallSync([](void* data) { *reinterpret_cast<bool*>(data) = true; }, &called);
  std::thread loop_thread([&]() { test_loop->RunUntilIdle(); });
  EXPECT_FALSE(called);

  // A nested lock will not cause the call to executed.
  manager->ReadLock();
  EXPECT_FALSE(called);
  manager->ReadUnlock();
  EXPECT_FALSE(called);

  // Unlocking the last lock allows the call to proceed.
  manager->ReadUnlock();
  loop_thread.join();
  EXPECT_TRUE(called);
}

}  // namespace
}  // namespace wlan::testing
