/* Copyright 2019 Google LLC. All Rights Reserved.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
==============================================================================*/

#include "ruy/wait.h"

#include <atomic>
#include <condition_variable>  // NOLINT(build/c++11)
#include <mutex>               // NOLINT(build/c++11)
#include <thread>              // NOLINT(build/c++11)

#include "ruy/gtest_wrapper.h"
#include "ruy/platform.h"

namespace ruy {
namespace {

// Thread taking a `value` atomic counter and incrementing it until it equals
// `end_value`, then notifying the condition variable as long as
// `value == end_value`.  If `end_value` is increased, it will then resume
// incrementing `value`, etc.  Terminates if `end_value == -1`.
class ThreadCountingUpToValue {
 public:
  ThreadCountingUpToValue(const std::atomic<int>& end_value,
                          std::atomic<int>* value,
                          std::condition_variable* condvar, std::mutex* mutex)
      : end_value_(end_value),
        value_(value),
        condvar_(condvar),
        mutex_(mutex) {}
  void operator()() {
    // end_value_==-1 is how the master thread will tell us it's OK to terminate
    while (end_value_.load() != -1) {
      // wait until end_value is set to a higher value
      while (value_->load() == end_value_.load()) {
      }
      // increment value as long as it's lower than end_value
      while (value_->fetch_add(1) < end_value_.load() - 1) {
      }
      // when value has reached end_value, notify the master thread.
      while (value_->load() == end_value_.load()) {
        std::lock_guard<std::mutex> lock(*mutex_);
        condvar_->notify_all();
      }
    }
  }

 private:
  const std::atomic<int>& end_value_;
  std::atomic<int>* value_;
  std::condition_variable* condvar_;
  std::mutex* mutex_;
};

void WaitTest(const Duration& spin_duration, const Duration& delay) {
#if RUY_PLATFORM_EMSCRIPTEN
  // b/139927184, std::thread constructor raises exception
  return;
#endif
  std::condition_variable condvar;
  std::mutex mutex;
  std::atomic<int> value(0);
  std::atomic<int> end_value(0);
  ThreadCountingUpToValue thread_callable(end_value, &value, &condvar, &mutex);
  std::thread thread(thread_callable);
  std::this_thread::sleep_for(delay);
  for (int i = 1; i < 10; i++) {
    end_value.store(1000 * i);
    const auto& condition = [&value, &end_value]() {
      return value.load() == end_value.load();
    };
    ruy::Wait(condition, spin_duration, &condvar, &mutex);
    EXPECT_EQ(value.load(), end_value.load());
  }
  end_value.store(-1);
  thread.join();
}

TEST(WaitTest, WaitTestNoSpin) {
  WaitTest(DurationFromSeconds(0), DurationFromSeconds(0));
}

TEST(WaitTest, WaitTestSpinOneMicrosecond) {
  WaitTest(DurationFromSeconds(1e-6), DurationFromSeconds(0));
}

TEST(WaitTest, WaitTestSpinOneMillisecond) {
  WaitTest(DurationFromSeconds(1e-3), DurationFromSeconds(0));
}

TEST(WaitTest, WaitTestSpinOneSecond) {
  WaitTest(DurationFromSeconds(1), DurationFromSeconds(0));
}

// Testcase to consistently reproduce the hang in b/139062384.
TEST(WaitTest, WaitTestNoSpinWithDelayBug139062384) {
  WaitTest(DurationFromSeconds(0), DurationFromSeconds(1));
}

}  // namespace
}  // namespace ruy

int main(int argc, char** argv) {
  ::testing::InitGoogleTest(&argc, argv);
  return RUN_ALL_TESTS();
}
