LCOV - code coverage report
Current view: top level - test/unittests/base/platform - semaphore-unittest.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 53 53 100.0 %
Date: 2019-04-17 Functions: 11 20 55.0 %

          Line data    Source code
       1             : // Copyright 2014 the V8 project authors. All rights reserved.
       2             : // Use of this source code is governed by a BSD-style license that can be
       3             : // found in the LICENSE file.
       4             : 
       5             : #include <cstring>
       6             : 
       7             : #include "src/base/platform/platform.h"
       8             : #include "src/base/platform/semaphore.h"
       9             : #include "src/base/platform/time.h"
      10             : #include "testing/gtest/include/gtest/gtest.h"
      11             : 
      12             : namespace v8 {
      13             : namespace base {
      14             : 
      15             : namespace {
      16             : 
      17             : static const char kAlphabet[] = "XKOAD";
      18             : static const size_t kAlphabetSize = sizeof(kAlphabet) - 1;
      19             : static const size_t kBufferSize = 987;  // GCD(buffer size, alphabet size) = 1
      20             : static const size_t kDataSize = kBufferSize * kAlphabetSize * 10;
      21             : 
      22             : 
      23           1 : class ProducerThread final : public Thread {
      24             :  public:
      25             :   ProducerThread(char* buffer, Semaphore* free_space, Semaphore* used_space)
      26             :       : Thread(Options("ProducerThread")),
      27             :         buffer_(buffer),
      28             :         free_space_(free_space),
      29           1 :         used_space_(used_space) {}
      30             : 
      31           1 :   void Run() override {
      32       98701 :     for (size_t n = 0; n < kDataSize; ++n) {
      33       49350 :       free_space_->Wait();
      34       49350 :       buffer_[n % kBufferSize] = kAlphabet[n % kAlphabetSize];
      35       49350 :       used_space_->Signal();
      36             :     }
      37           1 :   }
      38             : 
      39             :  private:
      40             :   char* buffer_;
      41             :   Semaphore* const free_space_;
      42             :   Semaphore* const used_space_;
      43             : };
      44             : 
      45             : 
      46           1 : class ConsumerThread final : public Thread {
      47             :  public:
      48             :   ConsumerThread(const char* buffer, Semaphore* free_space,
      49             :                  Semaphore* used_space)
      50             :       : Thread(Options("ConsumerThread")),
      51             :         buffer_(buffer),
      52             :         free_space_(free_space),
      53           1 :         used_space_(used_space) {}
      54             : 
      55           1 :   void Run() override {
      56       98701 :     for (size_t n = 0; n < kDataSize; ++n) {
      57       49350 :       used_space_->Wait();
      58       98700 :       EXPECT_EQ(kAlphabet[n % kAlphabetSize], buffer_[n % kBufferSize]);
      59       49350 :       free_space_->Signal();
      60             :     }
      61           1 :   }
      62             : 
      63             :  private:
      64             :   const char* buffer_;
      65             :   Semaphore* const free_space_;
      66             :   Semaphore* const used_space_;
      67             : };
      68             : 
      69             : 
      70           1 : class WaitAndSignalThread final : public Thread {
      71             :  public:
      72             :   explicit WaitAndSignalThread(Semaphore* semaphore)
      73           2 :       : Thread(Options("WaitAndSignalThread")), semaphore_(semaphore) {}
      74             : 
      75           2 :   void Run() override {
      76         402 :     for (int n = 0; n < 100; ++n) {
      77         200 :       semaphore_->Wait();
      78         400 :       ASSERT_FALSE(semaphore_->WaitFor(TimeDelta::FromMicroseconds(1)));
      79         200 :       semaphore_->Signal();
      80             :     }
      81             :   }
      82             : 
      83             :  private:
      84             :   Semaphore* const semaphore_;
      85             : };
      86             : 
      87             : }  // namespace
      88             : 
      89             : 
      90       15443 : TEST(Semaphore, ProducerConsumer) {
      91             :   char buffer[kBufferSize];
      92             :   std::memset(buffer, 0, sizeof(buffer));
      93           2 :   Semaphore free_space(kBufferSize);
      94           2 :   Semaphore used_space(0);
      95             :   ProducerThread producer_thread(buffer, &free_space, &used_space);
      96             :   ConsumerThread consumer_thread(buffer, &free_space, &used_space);
      97           1 :   producer_thread.Start();
      98           1 :   consumer_thread.Start();
      99           1 :   producer_thread.Join();
     100           1 :   consumer_thread.Join();
     101           1 : }
     102             : 
     103             : 
     104       15443 : TEST(Semaphore, WaitAndSignal) {
     105           2 :   Semaphore semaphore(0);
     106             :   WaitAndSignalThread t1(&semaphore);
     107             :   WaitAndSignalThread t2(&semaphore);
     108             : 
     109           1 :   t1.Start();
     110           1 :   t2.Start();
     111             : 
     112             :   // Make something available.
     113           1 :   semaphore.Signal();
     114             : 
     115           1 :   t1.Join();
     116           1 :   t2.Join();
     117             : 
     118           1 :   semaphore.Wait();
     119             : 
     120           2 :   EXPECT_FALSE(semaphore.WaitFor(TimeDelta::FromMicroseconds(1)));
     121           1 : }
     122             : 
     123             : 
     124       15443 : TEST(Semaphore, WaitFor) {
     125           2 :   Semaphore semaphore(0);
     126             : 
     127             :   // Semaphore not signalled - timeout.
     128           2 :   ASSERT_FALSE(semaphore.WaitFor(TimeDelta::FromMicroseconds(0)));
     129           2 :   ASSERT_FALSE(semaphore.WaitFor(TimeDelta::FromMicroseconds(100)));
     130           2 :   ASSERT_FALSE(semaphore.WaitFor(TimeDelta::FromMicroseconds(1000)));
     131             : 
     132             :   // Semaphore signalled - no timeout.
     133           1 :   semaphore.Signal();
     134           2 :   ASSERT_TRUE(semaphore.WaitFor(TimeDelta::FromMicroseconds(0)));
     135           1 :   semaphore.Signal();
     136           2 :   ASSERT_TRUE(semaphore.WaitFor(TimeDelta::FromMicroseconds(100)));
     137           1 :   semaphore.Signal();
     138           2 :   ASSERT_TRUE(semaphore.WaitFor(TimeDelta::FromMicroseconds(1000)));
     139             : }
     140             : 
     141             : }  // namespace base
     142        9264 : }  // namespace v8

Generated by: LCOV version 1.10