Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(80)

Side by Side Diff: test/cctest/test-circular-queue.cc

Issue 1138004: Add multithreading test for SamplingCircularQueue, fix implementation. (Closed)
Patch Set: Created 10 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/globals.h ('k') | test/cctest/test-cpu-profiler.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2010 the V8 project authors. All rights reserved. 1 // Copyright 2010 the V8 project authors. All rights reserved.
2 // 2 //
3 // Tests of circular queues. 3 // Tests of circular queues.
4 4
5 #include "v8.h" 5 #include "v8.h"
6 #include "circular-queue-inl.h" 6 #include "circular-queue-inl.h"
7 #include "cctest.h" 7 #include "cctest.h"
8 8
9 namespace i = v8::internal; 9 namespace i = v8::internal;
10 10
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
54 CHECK(cq.IsEmpty()); 54 CHECK(cq.IsEmpty());
55 } 55 }
56 56
57 57
58 TEST(SamplingCircularQueue) { 58 TEST(SamplingCircularQueue) {
59 typedef SamplingCircularQueue::Cell Record; 59 typedef SamplingCircularQueue::Cell Record;
60 const int kRecordsPerChunk = 4; 60 const int kRecordsPerChunk = 4;
61 SamplingCircularQueue scq(sizeof(Record), 61 SamplingCircularQueue scq(sizeof(Record),
62 kRecordsPerChunk * sizeof(Record), 62 kRecordsPerChunk * sizeof(Record),
63 3); 63 3);
64 scq.SetUpProducer();
65 scq.SetUpConsumer();
66 64
67 // Check that we are using non-reserved values. 65 // Check that we are using non-reserved values.
68 CHECK_NE(SamplingCircularQueue::kClear, 1); 66 CHECK_NE(SamplingCircularQueue::kClear, 1);
69 CHECK_NE(SamplingCircularQueue::kEnd, 1); 67 CHECK_NE(SamplingCircularQueue::kEnd, 1);
70 // Fill up the first chunk. 68 // Fill up the first chunk.
71 CHECK_EQ(NULL, scq.StartDequeue()); 69 CHECK_EQ(NULL, scq.StartDequeue());
72 for (Record i = 1; i < 1 + kRecordsPerChunk; ++i) { 70 for (Record i = 1; i < 1 + kRecordsPerChunk; ++i) {
73 Record* rec = reinterpret_cast<Record*>(scq.Enqueue()); 71 Record* rec = reinterpret_cast<Record*>(scq.Enqueue());
74 CHECK_NE(NULL, rec); 72 CHECK_NE(NULL, rec);
75 *rec = i; 73 *rec = i;
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
114 Record* rec = reinterpret_cast<Record*>(scq.StartDequeue()); 112 Record* rec = reinterpret_cast<Record*>(scq.StartDequeue());
115 CHECK_NE(NULL, rec); 113 CHECK_NE(NULL, rec);
116 CHECK_EQ(static_cast<int64_t>(i), static_cast<int64_t>(*rec)); 114 CHECK_EQ(static_cast<int64_t>(i), static_cast<int64_t>(*rec));
117 CHECK_EQ(rec, reinterpret_cast<Record*>(scq.StartDequeue())); 115 CHECK_EQ(rec, reinterpret_cast<Record*>(scq.StartDequeue()));
118 scq.FinishDequeue(); 116 scq.FinishDequeue();
119 CHECK_NE(rec, reinterpret_cast<Record*>(scq.StartDequeue())); 117 CHECK_NE(rec, reinterpret_cast<Record*>(scq.StartDequeue()));
120 } 118 }
121 // Consumption must still be possible as the first cell of the 119 // Consumption must still be possible as the first cell of the
122 // last chunk is not clean. 120 // last chunk is not clean.
123 CHECK_NE(NULL, scq.StartDequeue()); 121 CHECK_NE(NULL, scq.StartDequeue());
122 }
124 123
125 scq.TearDownConsumer(); 124
126 scq.TearDownProducer(); 125 namespace {
126
127 class ProducerThread: public i::Thread {
128 public:
129 typedef SamplingCircularQueue::Cell Record;
130
131 ProducerThread(SamplingCircularQueue* scq,
132 int records_per_chunk,
133 Record value,
134 i::Semaphore* finished)
135 : scq_(scq),
136 records_per_chunk_(records_per_chunk),
137 value_(value),
138 finished_(finished) { }
139
140 virtual void Run() {
141 for (Record i = value_; i < value_ + records_per_chunk_; ++i) {
142 Record* rec = reinterpret_cast<Record*>(scq_->Enqueue());
143 CHECK_NE(NULL, rec);
144 *rec = i;
145 }
146
147 finished_->Signal();
148 }
149
150 private:
151 SamplingCircularQueue* scq_;
152 const int records_per_chunk_;
153 Record value_;
154 i::Semaphore* finished_;
155 };
156
157 } // namespace
158
159 TEST(SamplingCircularQueueMultithreading) {
160 // Emulate multiple VM threads working 'one thread at a time.'
161 // This test enqueues data from different threads. This corresponds
162 // to the case of profiling under Linux, where signal handler that
163 // does sampling is called in the context of different VM threads.
164
165 typedef ProducerThread::Record Record;
166 const int kRecordsPerChunk = 4;
167 SamplingCircularQueue scq(sizeof(Record),
168 kRecordsPerChunk * sizeof(Record),
169 3);
170 i::Semaphore* semaphore = i::OS::CreateSemaphore(0);
171 // Don't poll ahead, making possible to check data in the buffer
172 // immediately after enqueuing.
173 scq.FlushResidualRecords();
174
175 // Check that we are using non-reserved values.
176 CHECK_NE(SamplingCircularQueue::kClear, 1);
177 CHECK_NE(SamplingCircularQueue::kEnd, 1);
178 ProducerThread producer1(&scq, kRecordsPerChunk, 1, semaphore);
179 ProducerThread producer2(&scq, kRecordsPerChunk, 10, semaphore);
180 ProducerThread producer3(&scq, kRecordsPerChunk, 20, semaphore);
181
182 CHECK_EQ(NULL, scq.StartDequeue());
183 producer1.Start();
184 semaphore->Wait();
185 for (Record i = 1; i < 1 + kRecordsPerChunk; ++i) {
186 Record* rec = reinterpret_cast<Record*>(scq.StartDequeue());
187 CHECK_NE(NULL, rec);
188 CHECK_EQ(static_cast<int64_t>(i), static_cast<int64_t>(*rec));
189 CHECK_EQ(rec, reinterpret_cast<Record*>(scq.StartDequeue()));
190 scq.FinishDequeue();
191 CHECK_NE(rec, reinterpret_cast<Record*>(scq.StartDequeue()));
192 }
193
194 CHECK_EQ(NULL, scq.StartDequeue());
195 producer2.Start();
196 semaphore->Wait();
197 for (Record i = 10; i < 10 + kRecordsPerChunk; ++i) {
198 Record* rec = reinterpret_cast<Record*>(scq.StartDequeue());
199 CHECK_NE(NULL, rec);
200 CHECK_EQ(static_cast<int64_t>(i), static_cast<int64_t>(*rec));
201 CHECK_EQ(rec, reinterpret_cast<Record*>(scq.StartDequeue()));
202 scq.FinishDequeue();
203 CHECK_NE(rec, reinterpret_cast<Record*>(scq.StartDequeue()));
204 }
205
206 CHECK_EQ(NULL, scq.StartDequeue());
207 producer3.Start();
208 semaphore->Wait();
209 for (Record i = 20; i < 20 + kRecordsPerChunk; ++i) {
210 Record* rec = reinterpret_cast<Record*>(scq.StartDequeue());
211 CHECK_NE(NULL, rec);
212 CHECK_EQ(static_cast<int64_t>(i), static_cast<int64_t>(*rec));
213 CHECK_EQ(rec, reinterpret_cast<Record*>(scq.StartDequeue()));
214 scq.FinishDequeue();
215 CHECK_NE(rec, reinterpret_cast<Record*>(scq.StartDequeue()));
216 }
217
218 CHECK_EQ(NULL, scq.StartDequeue());
219
220 delete semaphore;
127 } 221 }
OLDNEW
« no previous file with comments | « src/globals.h ('k') | test/cctest/test-cpu-profiler.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698