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

Side by Side Diff: src/heap/page-parallel-job.h

Issue 1976133002: Check number of finished tasks in PageParallelJob. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 4 years, 7 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 | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2016 the V8 project authors. All rights reserved. 1 // Copyright 2016 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #ifndef V8_HEAP_PAGE_PARALLEL_JOB_ 5 #ifndef V8_HEAP_PAGE_PARALLEL_JOB_
6 #define V8_HEAP_PAGE_PARALLEL_JOB_ 6 #define V8_HEAP_PAGE_PARALLEL_JOB_
7 7
8 #include "src/allocation.h" 8 #include "src/allocation.h"
9 #include "src/cancelable-task.h" 9 #include "src/cancelable-task.h"
10 #include "src/utils.h" 10 #include "src/utils.h"
(...skipping 21 matching lines...) Expand all
32 // PerPageData page_data) 32 // PerPageData page_data)
33 template <typename JobTraits> 33 template <typename JobTraits>
34 class PageParallelJob { 34 class PageParallelJob {
35 public: 35 public:
36 PageParallelJob(Heap* heap, CancelableTaskManager* cancelable_task_manager) 36 PageParallelJob(Heap* heap, CancelableTaskManager* cancelable_task_manager)
37 : heap_(heap), 37 : heap_(heap),
38 cancelable_task_manager_(cancelable_task_manager), 38 cancelable_task_manager_(cancelable_task_manager),
39 items_(nullptr), 39 items_(nullptr),
40 num_items_(0), 40 num_items_(0),
41 num_tasks_(0), 41 num_tasks_(0),
42 pending_tasks_(new base::Semaphore(0)) {} 42 pending_tasks_(new base::Semaphore(0)),
43 finished_tasks_(new base::AtomicNumber<int>(0)) {}
43 44
44 ~PageParallelJob() { 45 ~PageParallelJob() {
45 Item* item = items_; 46 Item* item = items_;
46 while (item != nullptr) { 47 while (item != nullptr) {
47 Item* next = item->next; 48 Item* next = item->next;
48 delete item; 49 delete item;
49 item = next; 50 item = next;
50 } 51 }
51 delete pending_tasks_; 52 delete pending_tasks_;
53 delete finished_tasks_;
52 } 54 }
53 55
54 void AddPage(MemoryChunk* chunk, typename JobTraits::PerPageData data) { 56 void AddPage(MemoryChunk* chunk, typename JobTraits::PerPageData data) {
55 Item* item = new Item(chunk, data, items_); 57 Item* item = new Item(chunk, data, items_);
56 items_ = item; 58 items_ = item;
57 ++num_items_; 59 ++num_items_;
58 } 60 }
59 61
60 int NumberOfPages() { return num_items_; } 62 int NumberOfPages() { return num_items_; }
61 63
(...skipping 14 matching lines...) Expand all
76 V8::GetCurrentPlatform()->NumberOfAvailableBackgroundThreads())); 78 V8::GetCurrentPlatform()->NumberOfAvailableBackgroundThreads()));
77 num_tasks_ = Max(1, Min(num_tasks, max_num_tasks)); 79 num_tasks_ = Max(1, Min(num_tasks, max_num_tasks));
78 int items_per_task = (num_items_ + num_tasks_ - 1) / num_tasks_; 80 int items_per_task = (num_items_ + num_tasks_ - 1) / num_tasks_;
79 int start_index = 0; 81 int start_index = 0;
80 Task* main_task = nullptr; 82 Task* main_task = nullptr;
81 for (int i = 0; i < num_tasks_; i++, start_index += items_per_task) { 83 for (int i = 0; i < num_tasks_; i++, start_index += items_per_task) {
82 if (start_index >= num_items_) { 84 if (start_index >= num_items_) {
83 start_index -= num_items_; 85 start_index -= num_items_;
84 } 86 }
85 Task* task = new Task(heap_, items_, num_items_, start_index, 87 Task* task = new Task(heap_, items_, num_items_, start_index,
86 pending_tasks_, per_task_data_callback(i)); 88 pending_tasks_, per_task_data_callback(i), this);
87 task_ids[i] = task->id(); 89 task_ids[i] = task->id();
88 if (i > 0) { 90 if (i > 0) {
89 V8::GetCurrentPlatform()->CallOnBackgroundThread( 91 V8::GetCurrentPlatform()->CallOnBackgroundThread(
90 task, v8::Platform::kShortRunningTask); 92 task, v8::Platform::kShortRunningTask);
91 } else { 93 } else {
92 main_task = task; 94 main_task = task;
93 } 95 }
94 } 96 }
95 // Contribute on main thread. 97 // Contribute on main thread.
96 main_task->Run(); 98 main_task->Run();
97 delete main_task; 99 delete main_task;
100 int aborted_tasks = 0;
98 // Wait for background tasks. 101 // Wait for background tasks.
99 for (int i = 0; i < num_tasks_; i++) { 102 for (int i = 0; i < num_tasks_; i++) {
100 if (!cancelable_task_manager_->TryAbort(task_ids[i])) { 103 if (!cancelable_task_manager_->TryAbort(task_ids[i])) {
101 pending_tasks_->Wait(); 104 pending_tasks_->Wait();
105 } else {
106 ++aborted_tasks;
102 } 107 }
103 } 108 }
109 int finished_tasks = finished_tasks_->Value();
110 // TODO(ulan): Remove this check after investigation of crbug.com/609249.
111 CHECK_EQ(aborted_tasks + finished_tasks, num_tasks_);
104 if (JobTraits::NeedSequentialFinalization) { 112 if (JobTraits::NeedSequentialFinalization) {
105 Item* item = items_; 113 Item* item = items_;
106 while (item != nullptr) { 114 while (item != nullptr) {
107 bool success = (item->state.Value() == kFinished); 115 bool success = (item->state.Value() == kFinished);
108 JobTraits::FinalizePageSequentially(heap_, item->chunk, success, 116 JobTraits::FinalizePageSequentially(heap_, item->chunk, success,
109 item->data); 117 item->data);
110 item = item->next; 118 item = item->next;
111 } 119 }
112 } 120 }
113 } 121 }
114 122
123 void NotifyFinishedTask() { finished_tasks_->Increment(1); }
124
115 private: 125 private:
116 static const int kMaxNumberOfTasks = 10; 126 static const int kMaxNumberOfTasks = 10;
117 127
118 enum ProcessingState { kAvailable, kProcessing, kFinished, kFailed }; 128 enum ProcessingState { kAvailable, kProcessing, kFinished, kFailed };
119 129
120 struct Item : public Malloced { 130 struct Item : public Malloced {
121 Item(MemoryChunk* chunk, typename JobTraits::PerPageData data, Item* next) 131 Item(MemoryChunk* chunk, typename JobTraits::PerPageData data, Item* next)
122 : chunk(chunk), state(kAvailable), data(data), next(next) {} 132 : chunk(chunk), state(kAvailable), data(data), next(next) {}
123 MemoryChunk* chunk; 133 MemoryChunk* chunk;
124 base::AtomicValue<ProcessingState> state; 134 base::AtomicValue<ProcessingState> state;
125 typename JobTraits::PerPageData data; 135 typename JobTraits::PerPageData data;
126 Item* next; 136 Item* next;
127 }; 137 };
128 138
129 class Task : public CancelableTask { 139 class Task : public CancelableTask {
130 public: 140 public:
131 Task(Heap* heap, Item* items, int num_items, int start_index, 141 Task(Heap* heap, Item* items, int num_items, int start_index,
132 base::Semaphore* on_finish, typename JobTraits::PerTaskData data) 142 base::Semaphore* on_finish, typename JobTraits::PerTaskData data,
143 PageParallelJob<JobTraits>* job)
133 : CancelableTask(heap->isolate()), 144 : CancelableTask(heap->isolate()),
134 heap_(heap), 145 heap_(heap),
135 items_(items), 146 items_(items),
136 num_items_(num_items), 147 num_items_(num_items),
137 start_index_(start_index), 148 start_index_(start_index),
138 on_finish_(on_finish), 149 on_finish_(on_finish),
139 data_(data) {} 150 data_(data),
151 job_(job) {}
140 152
141 virtual ~Task() {} 153 virtual ~Task() {}
142 154
143 private: 155 private:
144 // v8::internal::CancelableTask overrides. 156 // v8::internal::CancelableTask overrides.
145 void RunInternal() override { 157 void RunInternal() override {
146 // Each task starts at a different index to improve parallelization. 158 // Each task starts at a different index to improve parallelization.
147 Item* current = items_; 159 Item* current = items_;
148 int skip = start_index_; 160 int skip = start_index_;
149 while (skip-- > 0) { 161 while (skip-- > 0) {
150 current = current->next; 162 current = current->next;
151 } 163 }
152 for (int i = 0; i < num_items_; i++) { 164 for (int i = 0; i < num_items_; i++) {
153 if (current->state.TrySetValue(kAvailable, kProcessing)) { 165 if (current->state.TrySetValue(kAvailable, kProcessing)) {
154 bool success = JobTraits::ProcessPageInParallel( 166 bool success = JobTraits::ProcessPageInParallel(
155 heap_, data_, current->chunk, current->data); 167 heap_, data_, current->chunk, current->data);
156 current->state.SetValue(success ? kFinished : kFailed); 168 current->state.SetValue(success ? kFinished : kFailed);
157 } 169 }
158 current = current->next; 170 current = current->next;
159 // Wrap around if needed. 171 // Wrap around if needed.
160 if (current == nullptr) { 172 if (current == nullptr) {
161 current = items_; 173 current = items_;
162 } 174 }
163 } 175 }
176 job_->NotifyFinishedTask();
164 on_finish_->Signal("PageParallelJob::Task::RunInternal"); 177 on_finish_->Signal("PageParallelJob::Task::RunInternal");
165 } 178 }
166 179
167 Heap* heap_; 180 Heap* heap_;
168 Item* items_; 181 Item* items_;
169 int num_items_; 182 int num_items_;
170 int start_index_; 183 int start_index_;
171 base::Semaphore* on_finish_; 184 base::Semaphore* on_finish_;
172 typename JobTraits::PerTaskData data_; 185 typename JobTraits::PerTaskData data_;
186 PageParallelJob<JobTraits>* job_;
173 DISALLOW_COPY_AND_ASSIGN(Task); 187 DISALLOW_COPY_AND_ASSIGN(Task);
174 }; 188 };
175 189
176 Heap* heap_; 190 Heap* heap_;
177 CancelableTaskManager* cancelable_task_manager_; 191 CancelableTaskManager* cancelable_task_manager_;
178 Item* items_; 192 Item* items_;
179 int num_items_; 193 int num_items_;
180 int num_tasks_; 194 int num_tasks_;
181 base::Semaphore* pending_tasks_; 195 base::Semaphore* pending_tasks_;
196 base::AtomicNumber<int>* finished_tasks_;
182 DISALLOW_COPY_AND_ASSIGN(PageParallelJob); 197 DISALLOW_COPY_AND_ASSIGN(PageParallelJob);
183 }; 198 };
184 199
185 } // namespace internal 200 } // namespace internal
186 } // namespace v8 201 } // namespace v8
187 202
188 #endif // V8_HEAP_PAGE_PARALLEL_JOB_ 203 #endif // V8_HEAP_PAGE_PARALLEL_JOB_
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698