// Copyright 2014 the V8 project 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 <cstring>

#include "src/base/platform/platform.h"
#include "src/base/platform/semaphore.h"
#include "src/base/platform/time.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace v8 {
namespace base {

namespace {

static const char kAlphabet[] = "XKOAD";
static const size_t kAlphabetSize = sizeof(kAlphabet) - 1;
static const size_t kBufferSize = 987;  // GCD(buffer size, alphabet size) = 1
static const size_t kDataSize = kBufferSize * kAlphabetSize * 10;


class ProducerThread FINAL : public Thread {
 public:
  ProducerThread(char* buffer, Semaphore* free_space, Semaphore* used_space)
      : Thread(Options("ProducerThread")),
        buffer_(buffer),
        free_space_(free_space),
        used_space_(used_space) {}
  virtual ~ProducerThread() {}

  virtual void Run() OVERRIDE {
    for (size_t n = 0; n < kDataSize; ++n) {
      free_space_->Wait();
      buffer_[n % kBufferSize] = kAlphabet[n % kAlphabetSize];
      used_space_->Signal();
    }
  }

 private:
  char* buffer_;
  Semaphore* const free_space_;
  Semaphore* const used_space_;
};


class ConsumerThread FINAL : public Thread {
 public:
  ConsumerThread(const char* buffer, Semaphore* free_space,
                 Semaphore* used_space)
      : Thread(Options("ConsumerThread")),
        buffer_(buffer),
        free_space_(free_space),
        used_space_(used_space) {}
  virtual ~ConsumerThread() {}

  virtual void Run() OVERRIDE {
    for (size_t n = 0; n < kDataSize; ++n) {
      used_space_->Wait();
      EXPECT_EQ(kAlphabet[n % kAlphabetSize], buffer_[n % kBufferSize]);
      free_space_->Signal();
    }
  }

 private:
  const char* buffer_;
  Semaphore* const free_space_;
  Semaphore* const used_space_;
};


class WaitAndSignalThread FINAL : public Thread {
 public:
  explicit WaitAndSignalThread(Semaphore* semaphore)
      : Thread(Options("WaitAndSignalThread")), semaphore_(semaphore) {}
  virtual ~WaitAndSignalThread() {}

  virtual void Run() OVERRIDE {
    for (int n = 0; n < 100; ++n) {
      semaphore_->Wait();
      ASSERT_FALSE(semaphore_->WaitFor(TimeDelta::FromMicroseconds(1)));
      semaphore_->Signal();
    }
  }

 private:
  Semaphore* const semaphore_;
};

}  // namespace


TEST(Semaphore, ProducerConsumer) {
  char buffer[kBufferSize];
  std::memset(buffer, 0, sizeof(buffer));
  Semaphore free_space(kBufferSize);
  Semaphore used_space(0);
  ProducerThread producer_thread(buffer, &free_space, &used_space);
  ConsumerThread consumer_thread(buffer, &free_space, &used_space);
  producer_thread.Start();
  consumer_thread.Start();
  producer_thread.Join();
  consumer_thread.Join();
}


TEST(Semaphore, WaitAndSignal) {
  Semaphore semaphore(0);
  WaitAndSignalThread t1(&semaphore);
  WaitAndSignalThread t2(&semaphore);

  t1.Start();
  t2.Start();

  // Make something available.
  semaphore.Signal();

  t1.Join();
  t2.Join();

  semaphore.Wait();

  EXPECT_FALSE(semaphore.WaitFor(TimeDelta::FromMicroseconds(1)));
}


TEST(Semaphore, WaitFor) {
  Semaphore semaphore(0);

  // Semaphore not signalled - timeout.
  ASSERT_FALSE(semaphore.WaitFor(TimeDelta::FromMicroseconds(0)));
  ASSERT_FALSE(semaphore.WaitFor(TimeDelta::FromMicroseconds(100)));
  ASSERT_FALSE(semaphore.WaitFor(TimeDelta::FromMicroseconds(1000)));

  // Semaphore signalled - no timeout.
  semaphore.Signal();
  ASSERT_TRUE(semaphore.WaitFor(TimeDelta::FromMicroseconds(0)));
  semaphore.Signal();
  ASSERT_TRUE(semaphore.WaitFor(TimeDelta::FromMicroseconds(100)));
  semaphore.Signal();
  ASSERT_TRUE(semaphore.WaitFor(TimeDelta::FromMicroseconds(1000)));
}

}  // namespace base
}  // namespace v8
