OLD | NEW |
1 // Copyright 2010 the V8 project authors. All rights reserved. | 1 // Copyright 2010 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
69 // possible that it can catch up and overwrite a chunk that a consumer | 69 // possible that it can catch up and overwrite a chunk that a consumer |
70 // is currently reading, resulting in a corrupt record being read. | 70 // is currently reading, resulting in a corrupt record being read. |
71 class SamplingCircularQueue { | 71 class SamplingCircularQueue { |
72 public: | 72 public: |
73 // Executed on the application thread. | 73 // Executed on the application thread. |
74 SamplingCircularQueue(int record_size_in_bytes, | 74 SamplingCircularQueue(int record_size_in_bytes, |
75 int desired_chunk_size_in_bytes, | 75 int desired_chunk_size_in_bytes, |
76 int buffer_size_in_chunks); | 76 int buffer_size_in_chunks); |
77 ~SamplingCircularQueue(); | 77 ~SamplingCircularQueue(); |
78 | 78 |
79 // Executed on the producer (sampler) or application thread. | |
80 void SetUpProducer(); | |
81 // Enqueue returns a pointer to a memory location for storing the next | 79 // Enqueue returns a pointer to a memory location for storing the next |
82 // record. | 80 // record. |
83 INLINE(void* Enqueue()); | 81 INLINE(void* Enqueue()); |
84 void TearDownProducer(); | |
85 | 82 |
86 // Executed on the consumer (analyzer) thread. | 83 // Executed on the consumer (analyzer) thread. |
87 void SetUpConsumer(); | |
88 // StartDequeue returns a pointer to a memory location for retrieving | 84 // StartDequeue returns a pointer to a memory location for retrieving |
89 // the next record. After the record had been read by a consumer, | 85 // the next record. After the record had been read by a consumer, |
90 // FinishDequeue must be called. Until that moment, subsequent calls | 86 // FinishDequeue must be called. Until that moment, subsequent calls |
91 // to StartDequeue will return the same pointer. | 87 // to StartDequeue will return the same pointer. |
92 void* StartDequeue(); | 88 void* StartDequeue(); |
93 void FinishDequeue(); | 89 void FinishDequeue(); |
94 // Due to a presence of slipping between the producer and the consumer, | 90 // Due to a presence of slipping between the producer and the consumer, |
95 // the queue must be notified whether producing has been finished in order | 91 // the queue must be notified whether producing has been finished in order |
96 // to process remaining records from the buffer. | 92 // to process remaining records from the buffer. |
97 void FlushResidualRecords(); | 93 void FlushResidualRecords(); |
98 void TearDownConsumer(); | |
99 | 94 |
100 typedef AtomicWord Cell; | 95 typedef AtomicWord Cell; |
101 // Reserved values for the first cell of a record. | 96 // Reserved values for the first cell of a record. |
102 static const Cell kClear = 0; // Marks clean (processed) chunks. | 97 static const Cell kClear = 0; // Marks clean (processed) chunks. |
103 static const Cell kEnd = -1; // Marks the end of the buffer. | 98 static const Cell kEnd = -1; // Marks the end of the buffer. |
104 | 99 |
105 private: | 100 private: |
| 101 struct ProducerPosition { |
| 102 Cell* enqueue_pos; |
| 103 }; |
106 struct ConsumerPosition { | 104 struct ConsumerPosition { |
107 Cell* dequeue_chunk_pos; | 105 Cell* dequeue_chunk_pos; |
108 Cell* dequeue_chunk_poll_pos; | 106 Cell* dequeue_chunk_poll_pos; |
109 Cell* dequeue_pos; | 107 Cell* dequeue_pos; |
110 Cell* dequeue_end_pos; | 108 Cell* dequeue_end_pos; |
111 }; | 109 }; |
112 | 110 |
113 INLINE(void WrapPositionIfNeeded(Cell** pos)); | 111 INLINE(void WrapPositionIfNeeded(Cell** pos)); |
114 | 112 |
115 const int record_size_; | 113 const int record_size_; |
116 const int chunk_size_in_bytes_; | 114 const int chunk_size_in_bytes_; |
117 const int chunk_size_; | 115 const int chunk_size_; |
118 const int buffer_size_; | 116 const int buffer_size_; |
119 const int producer_consumer_distance_; | 117 const int producer_consumer_distance_; |
120 Cell* buffer_; | 118 Cell* buffer_; |
121 // Store producer and consumer data in TLS to avoid modifying the | 119 byte* positions_; |
122 // same CPU cache line from two threads simultaneously. | 120 ProducerPosition* producer_pos_; |
123 Thread::LocalStorageKey consumer_key_; | 121 ConsumerPosition* consumer_pos_; |
124 Thread::LocalStorageKey producer_key_; | |
125 }; | 122 }; |
126 | 123 |
127 | 124 |
128 } } // namespace v8::internal | 125 } } // namespace v8::internal |
129 | 126 |
130 #endif // V8_CIRCULAR_QUEUE_H_ | 127 #endif // V8_CIRCULAR_QUEUE_H_ |
OLD | NEW |