diff options
Diffstat (limited to 'deps/v8/src/base/platform/semaphore-unittest.cc')
-rw-r--r-- | deps/v8/src/base/platform/semaphore-unittest.cc | 145 |
1 files changed, 145 insertions, 0 deletions
diff --git a/deps/v8/src/base/platform/semaphore-unittest.cc b/deps/v8/src/base/platform/semaphore-unittest.cc new file mode 100644 index 0000000000..c68435f875 --- /dev/null +++ b/deps/v8/src/base/platform/semaphore-unittest.cc @@ -0,0 +1,145 @@ +// 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 |