Upstream version 11.39.266.0
[platform/framework/web/crosswalk.git] / src / v8 / src / base / platform / semaphore-unittest.cc
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 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         used_space_(used_space) {}
30   virtual ~ProducerThread() {}
31
32   virtual void Run() OVERRIDE {
33     for (size_t n = 0; n < kDataSize; ++n) {
34       free_space_->Wait();
35       buffer_[n % kBufferSize] = kAlphabet[n % kAlphabetSize];
36       used_space_->Signal();
37     }
38   }
39
40  private:
41   char* buffer_;
42   Semaphore* const free_space_;
43   Semaphore* const used_space_;
44 };
45
46
47 class ConsumerThread FINAL : public Thread {
48  public:
49   ConsumerThread(const char* buffer, Semaphore* free_space,
50                  Semaphore* used_space)
51       : Thread(Options("ConsumerThread")),
52         buffer_(buffer),
53         free_space_(free_space),
54         used_space_(used_space) {}
55   virtual ~ConsumerThread() {}
56
57   virtual void Run() OVERRIDE {
58     for (size_t n = 0; n < kDataSize; ++n) {
59       used_space_->Wait();
60       EXPECT_EQ(kAlphabet[n % kAlphabetSize], buffer_[n % kBufferSize]);
61       free_space_->Signal();
62     }
63   }
64
65  private:
66   const char* buffer_;
67   Semaphore* const free_space_;
68   Semaphore* const used_space_;
69 };
70
71
72 class WaitAndSignalThread FINAL : public Thread {
73  public:
74   explicit WaitAndSignalThread(Semaphore* semaphore)
75       : Thread(Options("WaitAndSignalThread")), semaphore_(semaphore) {}
76   virtual ~WaitAndSignalThread() {}
77
78   virtual void Run() OVERRIDE {
79     for (int n = 0; n < 100; ++n) {
80       semaphore_->Wait();
81       ASSERT_FALSE(semaphore_->WaitFor(TimeDelta::FromMicroseconds(1)));
82       semaphore_->Signal();
83     }
84   }
85
86  private:
87   Semaphore* const semaphore_;
88 };
89
90 }  // namespace
91
92
93 TEST(Semaphore, ProducerConsumer) {
94   char buffer[kBufferSize];
95   std::memset(buffer, 0, sizeof(buffer));
96   Semaphore free_space(kBufferSize);
97   Semaphore used_space(0);
98   ProducerThread producer_thread(buffer, &free_space, &used_space);
99   ConsumerThread consumer_thread(buffer, &free_space, &used_space);
100   producer_thread.Start();
101   consumer_thread.Start();
102   producer_thread.Join();
103   consumer_thread.Join();
104 }
105
106
107 TEST(Semaphore, WaitAndSignal) {
108   Semaphore semaphore(0);
109   WaitAndSignalThread t1(&semaphore);
110   WaitAndSignalThread t2(&semaphore);
111
112   t1.Start();
113   t2.Start();
114
115   // Make something available.
116   semaphore.Signal();
117
118   t1.Join();
119   t2.Join();
120
121   semaphore.Wait();
122
123   EXPECT_FALSE(semaphore.WaitFor(TimeDelta::FromMicroseconds(1)));
124 }
125
126
127 TEST(Semaphore, WaitFor) {
128   Semaphore semaphore(0);
129
130   // Semaphore not signalled - timeout.
131   ASSERT_FALSE(semaphore.WaitFor(TimeDelta::FromMicroseconds(0)));
132   ASSERT_FALSE(semaphore.WaitFor(TimeDelta::FromMicroseconds(100)));
133   ASSERT_FALSE(semaphore.WaitFor(TimeDelta::FromMicroseconds(1000)));
134
135   // Semaphore signalled - no timeout.
136   semaphore.Signal();
137   ASSERT_TRUE(semaphore.WaitFor(TimeDelta::FromMicroseconds(0)));
138   semaphore.Signal();
139   ASSERT_TRUE(semaphore.WaitFor(TimeDelta::FromMicroseconds(100)));
140   semaphore.Signal();
141   ASSERT_TRUE(semaphore.WaitFor(TimeDelta::FromMicroseconds(1000)));
142 }
143
144 }  // namespace base
145 }  // namespace v8