Home | History | Annotate | Download | only in cctest
      1 // Copyright 2013 the V8 project authors. All rights reserved.
      2 // Redistribution and use in source and binary forms, with or without
      3 // modification, are permitted provided that the following conditions are
      4 // met:
      5 //
      6 //     * Redistributions of source code must retain the above copyright
      7 //       notice, this list of conditions and the following disclaimer.
      8 //     * Redistributions in binary form must reproduce the above
      9 //       copyright notice, this list of conditions and the following
     10 //       disclaimer in the documentation and/or other materials provided
     11 //       with the distribution.
     12 //     * Neither the name of Google Inc. nor the names of its
     13 //       contributors may be used to endorse or promote products derived
     14 //       from this software without specific prior written permission.
     15 //
     16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
     22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     27 
     28 #include <stdlib.h>
     29 
     30 #include "src/v8.h"
     31 
     32 #include "src/platform.h"
     33 #include "test/cctest/cctest.h"
     34 
     35 
     36 using namespace ::v8::internal;
     37 
     38 
     39 class WaitAndSignalThread V8_FINAL : public Thread {
     40  public:
     41   explicit WaitAndSignalThread(Semaphore* semaphore)
     42       : Thread("WaitAndSignalThread"), semaphore_(semaphore) {}
     43   virtual ~WaitAndSignalThread() {}
     44 
     45   virtual void Run() V8_OVERRIDE {
     46     for (int n = 0; n < 1000; ++n) {
     47       semaphore_->Wait();
     48       bool result = semaphore_->WaitFor(TimeDelta::FromMicroseconds(1));
     49       ASSERT(!result);
     50       USE(result);
     51       semaphore_->Signal();
     52     }
     53   }
     54 
     55  private:
     56   Semaphore* semaphore_;
     57 };
     58 
     59 
     60 TEST(WaitAndSignal) {
     61   Semaphore semaphore(0);
     62   WaitAndSignalThread t1(&semaphore);
     63   WaitAndSignalThread t2(&semaphore);
     64 
     65   t1.Start();
     66   t2.Start();
     67 
     68   // Make something available.
     69   semaphore.Signal();
     70 
     71   t1.Join();
     72   t2.Join();
     73 
     74   semaphore.Wait();
     75 
     76   bool result = semaphore.WaitFor(TimeDelta::FromMicroseconds(1));
     77   ASSERT(!result);
     78   USE(result);
     79 }
     80 
     81 
     82 TEST(WaitFor) {
     83   bool ok;
     84   Semaphore semaphore(0);
     85 
     86   // Semaphore not signalled - timeout.
     87   ok = semaphore.WaitFor(TimeDelta::FromMicroseconds(0));
     88   CHECK(!ok);
     89   ok = semaphore.WaitFor(TimeDelta::FromMicroseconds(100));
     90   CHECK(!ok);
     91   ok = semaphore.WaitFor(TimeDelta::FromMicroseconds(1000));
     92   CHECK(!ok);
     93 
     94   // Semaphore signalled - no timeout.
     95   semaphore.Signal();
     96   ok = semaphore.WaitFor(TimeDelta::FromMicroseconds(0));
     97   CHECK(ok);
     98   semaphore.Signal();
     99   ok = semaphore.WaitFor(TimeDelta::FromMicroseconds(100));
    100   CHECK(ok);
    101   semaphore.Signal();
    102   ok = semaphore.WaitFor(TimeDelta::FromMicroseconds(1000));
    103   CHECK(ok);
    104 }
    105 
    106 
    107 static const char alphabet[] = "XKOAD";
    108 static const int kAlphabetSize = sizeof(alphabet) - 1;
    109 static const int kBufferSize = 4096;  // GCD(buffer size, alphabet size) = 1
    110 static char buffer[kBufferSize];
    111 static const int kDataSize = kBufferSize * kAlphabetSize * 10;
    112 
    113 static Semaphore free_space(kBufferSize);
    114 static Semaphore used_space(0);
    115 
    116 
    117 class ProducerThread V8_FINAL : public Thread {
    118  public:
    119   ProducerThread() : Thread("ProducerThread") {}
    120   virtual ~ProducerThread() {}
    121 
    122   virtual void Run() V8_OVERRIDE {
    123     for (int n = 0; n < kDataSize; ++n) {
    124       free_space.Wait();
    125       buffer[n % kBufferSize] = alphabet[n % kAlphabetSize];
    126       used_space.Signal();
    127     }
    128   }
    129 };
    130 
    131 
    132 class ConsumerThread V8_FINAL : public Thread {
    133  public:
    134   ConsumerThread() : Thread("ConsumerThread") {}
    135   virtual ~ConsumerThread() {}
    136 
    137   virtual void Run() V8_OVERRIDE {
    138     for (int n = 0; n < kDataSize; ++n) {
    139       used_space.Wait();
    140       ASSERT_EQ(static_cast<int>(alphabet[n % kAlphabetSize]),
    141                 static_cast<int>(buffer[n % kBufferSize]));
    142       free_space.Signal();
    143     }
    144   }
    145 };
    146 
    147 
    148 TEST(ProducerConsumer) {
    149   ProducerThread producer_thread;
    150   ConsumerThread consumer_thread;
    151   producer_thread.Start();
    152   consumer_thread.Start();
    153   producer_thread.Join();
    154   consumer_thread.Join();
    155 }
    156