OLD | NEW |
| (Empty) |
1 // Copyright 2010 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 #ifndef V8_CIRCULAR_QUEUE_H_ | |
6 #define V8_CIRCULAR_QUEUE_H_ | |
7 | |
8 #include "src/base/atomicops.h" | |
9 #include "src/globals.h" | |
10 | |
11 namespace v8 { | |
12 namespace internal { | |
13 | |
14 | |
15 // Lock-free cache-friendly sampling circular queue for large | |
16 // records. Intended for fast transfer of large records between a | |
17 // single producer and a single consumer. If the queue is full, | |
18 // StartEnqueue will return NULL. The queue is designed with | |
19 // a goal in mind to evade cache lines thrashing by preventing | |
20 // simultaneous reads and writes to adjanced memory locations. | |
21 template<typename T, unsigned Length> | |
22 class SamplingCircularQueue { | |
23 public: | |
24 // Executed on the application thread. | |
25 SamplingCircularQueue(); | |
26 ~SamplingCircularQueue(); | |
27 | |
28 // StartEnqueue returns a pointer to a memory location for storing the next | |
29 // record or NULL if all entries are full at the moment. | |
30 T* StartEnqueue(); | |
31 // Notifies the queue that the producer has complete writing data into the | |
32 // memory returned by StartEnqueue and it can be passed to the consumer. | |
33 void FinishEnqueue(); | |
34 | |
35 // Executed on the consumer (analyzer) thread. | |
36 // Retrieves, but does not remove, the head of this queue, returning NULL | |
37 // if this queue is empty. After the record had been read by a consumer, | |
38 // Remove must be called. | |
39 T* Peek(); | |
40 void Remove(); | |
41 | |
42 private: | |
43 // Reserved values for the entry marker. | |
44 enum { | |
45 kEmpty, // Marks clean (processed) entries. | |
46 kFull // Marks entries already filled by the producer but not yet | |
47 // completely processed by the consumer. | |
48 }; | |
49 | |
50 struct V8_ALIGNED(PROCESSOR_CACHE_LINE_SIZE) Entry { | |
51 Entry() : marker(kEmpty) {} | |
52 T record; | |
53 base::Atomic32 marker; | |
54 }; | |
55 | |
56 Entry* Next(Entry* entry); | |
57 | |
58 Entry buffer_[Length]; | |
59 V8_ALIGNED(PROCESSOR_CACHE_LINE_SIZE) Entry* enqueue_pos_; | |
60 V8_ALIGNED(PROCESSOR_CACHE_LINE_SIZE) Entry* dequeue_pos_; | |
61 | |
62 DISALLOW_COPY_AND_ASSIGN(SamplingCircularQueue); | |
63 }; | |
64 | |
65 | |
66 } } // namespace v8::internal | |
67 | |
68 #endif // V8_CIRCULAR_QUEUE_H_ | |
OLD | NEW |