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

Side by Side Diff: src/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/circular-queue.h ('k') | src/circular-queue-inl.h » ('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 // 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 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
45 // each other's chunks and helps eviction of produced data from 45 // each other's chunks and helps eviction of produced data from
46 // the CPU cache (having that chunk size is bigger than the cache.) 46 // the CPU cache (having that chunk size is bigger than the cache.)
47 producer_consumer_distance_(2 * chunk_size_), 47 producer_consumer_distance_(2 * chunk_size_),
48 buffer_(NewArray<Cell>(buffer_size_ + 1)) { 48 buffer_(NewArray<Cell>(buffer_size_ + 1)) {
49 ASSERT(buffer_size_in_chunks > 2); 49 ASSERT(buffer_size_in_chunks > 2);
50 // Only need to keep the first cell of a chunk clean. 50 // Only need to keep the first cell of a chunk clean.
51 for (int i = 0; i < buffer_size_; i += chunk_size_) { 51 for (int i = 0; i < buffer_size_; i += chunk_size_) {
52 buffer_[i] = kClear; 52 buffer_[i] = kClear;
53 } 53 }
54 buffer_[buffer_size_] = kEnd; 54 buffer_[buffer_size_] = kEnd;
55
56 // Layout producer and consumer position pointers each on their own
57 // cache lines to avoid cache lines thrashing due to simultaneous
58 // updates of positions by different processor cores.
59 const int positions_size =
60 RoundUp(1, kProcessorCacheLineSize) +
61 RoundUp(sizeof(ProducerPosition), kProcessorCacheLineSize) +
62 RoundUp(sizeof(ConsumerPosition), kProcessorCacheLineSize);
63 positions_ = NewArray<byte>(positions_size);
64
65 producer_pos_ = reinterpret_cast<ProducerPosition*>(
66 RoundUp(positions_, kProcessorCacheLineSize));
67 producer_pos_->enqueue_pos = buffer_;
68
69 consumer_pos_ = reinterpret_cast<ConsumerPosition*>(
70 reinterpret_cast<byte*>(producer_pos_) + kProcessorCacheLineSize);
71 ASSERT(reinterpret_cast<byte*>(consumer_pos_ + 1) <=
72 positions_ + positions_size);
73 consumer_pos_->dequeue_chunk_pos = buffer_;
74 consumer_pos_->dequeue_chunk_poll_pos = buffer_ + producer_consumer_distance_;
75 consumer_pos_->dequeue_pos = NULL;
55 } 76 }
56 77
57 78
58 SamplingCircularQueue::~SamplingCircularQueue() { 79 SamplingCircularQueue::~SamplingCircularQueue() {
80 DeleteArray(positions_);
59 DeleteArray(buffer_); 81 DeleteArray(buffer_);
60 } 82 }
61 83
62 84
63 void SamplingCircularQueue::SetUpProducer() {
64 producer_key_ = Thread::CreateThreadLocalKey();
65 Thread::SetThreadLocal(producer_key_, buffer_);
66 }
67
68
69 void SamplingCircularQueue::TearDownProducer() {
70 Thread::DeleteThreadLocalKey(producer_key_);
71 }
72
73
74 void SamplingCircularQueue::SetUpConsumer() {
75 consumer_key_ = Thread::CreateThreadLocalKey();
76 ConsumerPosition* cp = new ConsumerPosition;
77 cp->dequeue_chunk_pos = buffer_;
78 cp->dequeue_chunk_poll_pos = buffer_ + producer_consumer_distance_;
79 cp->dequeue_pos = NULL;
80 Thread::SetThreadLocal(consumer_key_, cp);
81 }
82
83
84 void SamplingCircularQueue::TearDownConsumer() {
85 delete reinterpret_cast<ConsumerPosition*>(
86 Thread::GetThreadLocal(consumer_key_));
87 Thread::DeleteThreadLocalKey(consumer_key_);
88 }
89
90
91 void* SamplingCircularQueue::StartDequeue() { 85 void* SamplingCircularQueue::StartDequeue() {
92 ConsumerPosition* cp = reinterpret_cast<ConsumerPosition*>( 86 if (consumer_pos_->dequeue_pos != NULL) {
93 Thread::GetThreadLocal(consumer_key_)); 87 return consumer_pos_->dequeue_pos;
94 if (cp->dequeue_pos != NULL) {
95 return cp->dequeue_pos;
96 } else { 88 } else {
97 if (*cp->dequeue_chunk_poll_pos != kClear) { 89 if (*consumer_pos_->dequeue_chunk_poll_pos != kClear) {
98 cp->dequeue_pos = cp->dequeue_chunk_pos; 90 consumer_pos_->dequeue_pos = consumer_pos_->dequeue_chunk_pos;
99 cp->dequeue_end_pos = cp->dequeue_pos + chunk_size_; 91 consumer_pos_->dequeue_end_pos = consumer_pos_->dequeue_pos + chunk_size_;
100 return cp->dequeue_pos; 92 return consumer_pos_->dequeue_pos;
101 } else { 93 } else {
102 return NULL; 94 return NULL;
103 } 95 }
104 } 96 }
105 } 97 }
106 98
107 99
108 void SamplingCircularQueue::FinishDequeue() { 100 void SamplingCircularQueue::FinishDequeue() {
109 ConsumerPosition* cp = reinterpret_cast<ConsumerPosition*>( 101 consumer_pos_->dequeue_pos += record_size_;
110 Thread::GetThreadLocal(consumer_key_)); 102 if (consumer_pos_->dequeue_pos < consumer_pos_->dequeue_end_pos) return;
111 cp->dequeue_pos += record_size_;
112 if (cp->dequeue_pos < cp->dequeue_end_pos) return;
113 // Move to next chunk. 103 // Move to next chunk.
114 cp->dequeue_pos = NULL; 104 consumer_pos_->dequeue_pos = NULL;
115 *cp->dequeue_chunk_pos = kClear; 105 *consumer_pos_->dequeue_chunk_pos = kClear;
116 cp->dequeue_chunk_pos += chunk_size_; 106 consumer_pos_->dequeue_chunk_pos += chunk_size_;
117 WrapPositionIfNeeded(&cp->dequeue_chunk_pos); 107 WrapPositionIfNeeded(&consumer_pos_->dequeue_chunk_pos);
118 cp->dequeue_chunk_poll_pos += chunk_size_; 108 consumer_pos_->dequeue_chunk_poll_pos += chunk_size_;
119 WrapPositionIfNeeded(&cp->dequeue_chunk_poll_pos); 109 WrapPositionIfNeeded(&consumer_pos_->dequeue_chunk_poll_pos);
120 } 110 }
121 111
122 112
123 void SamplingCircularQueue::FlushResidualRecords() { 113 void SamplingCircularQueue::FlushResidualRecords() {
124 ConsumerPosition* cp = reinterpret_cast<ConsumerPosition*>(
125 Thread::GetThreadLocal(consumer_key_));
126 // Eliminate producer / consumer distance. 114 // Eliminate producer / consumer distance.
127 cp->dequeue_chunk_poll_pos = cp->dequeue_chunk_pos; 115 consumer_pos_->dequeue_chunk_poll_pos = consumer_pos_->dequeue_chunk_pos;
128 } 116 }
129 117
130 118
131 } } // namespace v8::internal 119 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/circular-queue.h ('k') | src/circular-queue-inl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698