/* Copyright 2015 The TensorFlow Authors. 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 <condition_variable>

#include "tensorflow/core/lib/core/threadpool.h"
#include "tensorflow/core/platform/cpu_info.h"
#include "tensorflow/core/platform/env_time.h"
#include "tensorflow/core/platform/mem.h"
#include "tensorflow/core/platform/mutex.h"
#include "tensorflow/core/platform/test.h"

namespace tensorflow {
namespace port {

TEST(Port, AlignedMalloc) {
  for (size_t alignment = 1; alignment <= 1 << 20; alignment <<= 1) {
    void* p = AlignedMalloc(1, alignment);
    ASSERT_TRUE(p != nullptr) << "AlignedMalloc(1, " << alignment << ")";
    uintptr_t pval = reinterpret_cast<uintptr_t>(p);
    EXPECT_EQ(pval % alignment, 0);
    AlignedFree(p);
  }
}

TEST(Port, GetCurrentCPU) {
  GTEST_SKIP() << "Currently not stable.";  // b/132640908
  const int cpu = GetCurrentCPU();
#if !defined(__APPLE__)
  // GetCurrentCPU does not currently work on MacOS.
  EXPECT_GE(cpu, 0);
  EXPECT_LT(cpu, NumTotalCPUs());
#endif
}

TEST(ConditionVariable, WaitForMilliseconds_Timeout) {
  mutex m;
  mutex_lock l(m);
  condition_variable cv;
  ConditionResult result = kCond_MaybeNotified;
  time_t start = time(nullptr);
  // Condition variables are subject to spurious wakeups on some platforms,
  // so need to check for a timeout within a loop.
  while (result == kCond_MaybeNotified) {
    result = WaitForMilliseconds(&l, &cv, 3000);
  }
  EXPECT_EQ(result, kCond_Timeout);
  time_t finish = time(nullptr);
  EXPECT_GE(finish - start, 3);
}

TEST(ConditionVariable, WaitForMilliseconds_Signalled) {
  thread::ThreadPool pool(Env::Default(), "test", 1);
  mutex m;
  mutex_lock l(m);
  condition_variable cv;
  time_t start = time(nullptr);
  // Sleep for just 1 second then notify.  We have a timeout of 3 secs,
  // so the condition variable will notice the cv signal before the timeout.
  pool.Schedule([&m, &cv]() {
    Env::Default()->SleepForMicroseconds(1 * 1000 * 1000);
    mutex_lock l(m);
    cv.notify_all();
  });
  EXPECT_EQ(WaitForMilliseconds(&l, &cv, 3000), kCond_MaybeNotified);
  time_t finish = time(nullptr);
  EXPECT_LT(finish - start, 3);
}

TEST(ConditionalCriticalSections, AwaitWithDeadline_Timeout) {
  bool always_false = false;
  mutex m;
  m.lock();
  time_t start = time(nullptr);
  bool result = m.AwaitWithDeadline(
      Condition(&always_false),
      EnvTime::Default()->NowNanos() + 3 * EnvTime::kSecondsToNanos);
  time_t finish = time(nullptr);
  m.unlock();
  EXPECT_EQ(result, false);
  EXPECT_GE(finish - start, 3);
}

TEST(ConditionalCriticalSections, AwaitWithDeadline_Woken) {
  thread::ThreadPool pool(Env::Default(), "test", 1);
  bool woken = false;
  mutex m;
  m.lock();
  time_t start = time(nullptr);
  // Sleep for just 1 second then set the boolean.  We have a timeout of 3
  // secs, so the mutex implementation will notice the boolean state change
  // before the timeout.
  pool.Schedule([&m, &woken]() {
    Env::Default()->SleepForMicroseconds(1 * 1000 * 1000);
    m.lock();
    woken = true;
    m.unlock();
  });
  bool result =
      m.AwaitWithDeadline(Condition(&woken), EnvTime::Default()->NowNanos() +
                                                 3 * EnvTime::kSecondsToNanos);
  time_t finish = time(nullptr);
  m.unlock();
  EXPECT_EQ(result, true);
  EXPECT_LT(finish - start, 3);
}

// Return the negation of *b.  Used as an Await() predicate.
static bool Invert(bool* b) { return !*b; }

// The Value() method inverts the value of the boolean specified in
// the constructor.
class InvertClass {
 public:
  explicit InvertClass(bool* value) : value_(value) {}
  bool Value() { return !*this->value_; }

 private:
  InvertClass();
  bool* value_;
};

TEST(ConditionalCriticalSections, Await_PingPong) {
  thread::ThreadPool pool(Env::Default(), "test", 1);
  bool ping_pong = false;
  bool done = false;
  mutex m;
  pool.Schedule([&m, &ping_pong, &done]() {
    m.lock();
    for (int i = 0; i != 1000; i++) {
      m.Await(Condition(&ping_pong));
      ping_pong = false;
    }
    done = true;
    m.unlock();
  });
  m.lock();
  InvertClass invert(&ping_pong);
  for (int i = 0; i != 1000; i++) {
    m.Await(Condition(&Invert, &ping_pong));
    ping_pong = true;
  }
  m.Await(Condition(&done));
  m.unlock();
}

TEST(ConditionalCriticalSections, Await_PingPongMethod) {
  thread::ThreadPool pool(Env::Default(), "test", 1);
  bool ping_pong = false;
  bool done = false;
  mutex m;
  pool.Schedule([&m, &ping_pong, &done]() {
    m.lock();
    for (int i = 0; i != 1000; i++) {
      m.Await(Condition(&ping_pong));
      ping_pong = false;
    }
    done = true;
    m.unlock();
  });
  m.lock();
  InvertClass invert(&ping_pong);
  for (int i = 0; i != 1000; i++) {
    m.Await(Condition(&invert, &InvertClass::Value));
    ping_pong = true;
  }
  m.Await(Condition(&done));
  m.unlock();
}

TEST(TestCPUFeature, TestFeature) {
  // We don't know what the result should be on this platform, so just make
  // sure it's callable.
  const bool has_avx = TestCPUFeature(CPUFeature::AVX);
  LOG(INFO) << "has_avx = " << has_avx;
  const bool has_avx2 = TestCPUFeature(CPUFeature::AVX2);
  LOG(INFO) << "has_avx2 = " << has_avx2;
}

}  // namespace port
}  // namespace tensorflow
