Version 2.1.8
Added fine-grained garbage collection callbacks to the API.
Performance improvements on all platforms.
git-svn-id: http://v8.googlecode.com/svn/trunk@4238 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
diff --git a/src/circular-queue.cc b/src/circular-queue.cc
index 5f7a33e..a7c2532 100644
--- a/src/circular-queue.cc
+++ b/src/circular-queue.cc
@@ -52,52 +52,44 @@
buffer_[i] = kClear;
}
buffer_[buffer_size_] = kEnd;
+
+ // Layout producer and consumer position pointers each on their own
+ // cache lines to avoid cache lines thrashing due to simultaneous
+ // updates of positions by different processor cores.
+ const int positions_size =
+ RoundUp(1, kProcessorCacheLineSize) +
+ RoundUp(sizeof(ProducerPosition), kProcessorCacheLineSize) +
+ RoundUp(sizeof(ConsumerPosition), kProcessorCacheLineSize);
+ positions_ = NewArray<byte>(positions_size);
+
+ producer_pos_ = reinterpret_cast<ProducerPosition*>(
+ RoundUp(positions_, kProcessorCacheLineSize));
+ producer_pos_->enqueue_pos = buffer_;
+
+ consumer_pos_ = reinterpret_cast<ConsumerPosition*>(
+ reinterpret_cast<byte*>(producer_pos_) + kProcessorCacheLineSize);
+ ASSERT(reinterpret_cast<byte*>(consumer_pos_ + 1) <=
+ positions_ + positions_size);
+ consumer_pos_->dequeue_chunk_pos = buffer_;
+ consumer_pos_->dequeue_chunk_poll_pos = buffer_ + producer_consumer_distance_;
+ consumer_pos_->dequeue_pos = NULL;
}
SamplingCircularQueue::~SamplingCircularQueue() {
+ DeleteArray(positions_);
DeleteArray(buffer_);
}
-void SamplingCircularQueue::SetUpProducer() {
- producer_key_ = Thread::CreateThreadLocalKey();
- Thread::SetThreadLocal(producer_key_, buffer_);
-}
-
-
-void SamplingCircularQueue::TearDownProducer() {
- Thread::DeleteThreadLocalKey(producer_key_);
-}
-
-
-void SamplingCircularQueue::SetUpConsumer() {
- consumer_key_ = Thread::CreateThreadLocalKey();
- ConsumerPosition* cp = new ConsumerPosition;
- cp->dequeue_chunk_pos = buffer_;
- cp->dequeue_chunk_poll_pos = buffer_ + producer_consumer_distance_;
- cp->dequeue_pos = NULL;
- Thread::SetThreadLocal(consumer_key_, cp);
-}
-
-
-void SamplingCircularQueue::TearDownConsumer() {
- delete reinterpret_cast<ConsumerPosition*>(
- Thread::GetThreadLocal(consumer_key_));
- Thread::DeleteThreadLocalKey(consumer_key_);
-}
-
-
void* SamplingCircularQueue::StartDequeue() {
- ConsumerPosition* cp = reinterpret_cast<ConsumerPosition*>(
- Thread::GetThreadLocal(consumer_key_));
- if (cp->dequeue_pos != NULL) {
- return cp->dequeue_pos;
+ if (consumer_pos_->dequeue_pos != NULL) {
+ return consumer_pos_->dequeue_pos;
} else {
- if (*cp->dequeue_chunk_poll_pos != kClear) {
- cp->dequeue_pos = cp->dequeue_chunk_pos;
- cp->dequeue_end_pos = cp->dequeue_pos + chunk_size_;
- return cp->dequeue_pos;
+ if (*consumer_pos_->dequeue_chunk_poll_pos != kClear) {
+ consumer_pos_->dequeue_pos = consumer_pos_->dequeue_chunk_pos;
+ consumer_pos_->dequeue_end_pos = consumer_pos_->dequeue_pos + chunk_size_;
+ return consumer_pos_->dequeue_pos;
} else {
return NULL;
}
@@ -106,25 +98,21 @@
void SamplingCircularQueue::FinishDequeue() {
- ConsumerPosition* cp = reinterpret_cast<ConsumerPosition*>(
- Thread::GetThreadLocal(consumer_key_));
- cp->dequeue_pos += record_size_;
- if (cp->dequeue_pos < cp->dequeue_end_pos) return;
+ consumer_pos_->dequeue_pos += record_size_;
+ if (consumer_pos_->dequeue_pos < consumer_pos_->dequeue_end_pos) return;
// Move to next chunk.
- cp->dequeue_pos = NULL;
- *cp->dequeue_chunk_pos = kClear;
- cp->dequeue_chunk_pos += chunk_size_;
- WrapPositionIfNeeded(&cp->dequeue_chunk_pos);
- cp->dequeue_chunk_poll_pos += chunk_size_;
- WrapPositionIfNeeded(&cp->dequeue_chunk_poll_pos);
+ consumer_pos_->dequeue_pos = NULL;
+ *consumer_pos_->dequeue_chunk_pos = kClear;
+ consumer_pos_->dequeue_chunk_pos += chunk_size_;
+ WrapPositionIfNeeded(&consumer_pos_->dequeue_chunk_pos);
+ consumer_pos_->dequeue_chunk_poll_pos += chunk_size_;
+ WrapPositionIfNeeded(&consumer_pos_->dequeue_chunk_poll_pos);
}
void SamplingCircularQueue::FlushResidualRecords() {
- ConsumerPosition* cp = reinterpret_cast<ConsumerPosition*>(
- Thread::GetThreadLocal(consumer_key_));
// Eliminate producer / consumer distance.
- cp->dequeue_chunk_poll_pos = cp->dequeue_chunk_pos;
+ consumer_pos_->dequeue_chunk_poll_pos = consumer_pos_->dequeue_chunk_pos;
}