OLD | NEW |
---|---|
(Empty) | |
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 V8_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() V8_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 V8_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() V8_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 V8_FINAL : public Thread { | |
73 public: | |
74 explicit WaitAndSignalThread(Semaphore* semaphore) | |
75 : Thread(Options("WaitAndSignalThread")), semaphore_(semaphore) {} | |
76 virtual ~WaitAndSignalThread() {} | |
77 | |
78 virtual void Run() V8_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))); | |
Michael Achenbach
2014/08/22 08:21:07
What's the difference to ASSERT_FALSE above?
Benedikt Meurer
2014/08/22 08:51:58
EXPECT_* just record a failure, while ASSERT_* ter
| |
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))); | |
Michael Achenbach
2014/08/22 08:21:07
Do we really need the last one? What could make th
| |
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 | |
OLD | NEW |