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

Side by Side Diff: gpu/command_buffer/service/sync_point_manager.cc

Issue 1568563002: Added a way for sync point clients to issue out of order waits. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Allow WaitOutOfOrder if no client order data Created 4 years, 11 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
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium 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 #include "gpu/command_buffer/service/sync_point_manager.h" 5 #include "gpu/command_buffer/service/sync_point_manager.h"
6 6
7 #include <limits.h> 7 #include <limits.h>
8 #include <stddef.h> 8 #include <stddef.h>
9 #include <stdint.h> 9 #include <stdint.h>
10 10
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
57 const uint32_t order_num = sync_point_manager->GenerateOrderNumber(); 57 const uint32_t order_num = sync_point_manager->GenerateOrderNumber();
58 base::AutoLock auto_lock(lock_); 58 base::AutoLock auto_lock(lock_);
59 unprocessed_order_num_ = order_num; 59 unprocessed_order_num_ = order_num;
60 return order_num; 60 return order_num;
61 } 61 }
62 62
63 void SyncPointOrderData::BeginProcessingOrderNumber(uint32_t order_num) { 63 void SyncPointOrderData::BeginProcessingOrderNumber(uint32_t order_num) {
64 DCHECK(processing_thread_checker_.CalledOnValidThread()); 64 DCHECK(processing_thread_checker_.CalledOnValidThread());
65 DCHECK_GE(order_num, current_order_num_); 65 DCHECK_GE(order_num, current_order_num_);
66 current_order_num_ = order_num; 66 current_order_num_ = order_num;
67 paused_ = false;
67 68
68 // Catch invalid waits which were waiting on fence syncs that do not exist. 69 // Catch invalid waits which were waiting on fence syncs that do not exist.
69 // When we begin processing an order number, we should release any fence 70 // When we begin processing an order number, we should release any fence
70 // syncs which were enqueued but the order number never existed. 71 // syncs which were enqueued but the order number never existed.
71 // Release without the lock to avoid possible deadlocks. 72 // Release without the lock to avoid possible deadlocks.
72 std::vector<OrderFence> ensure_releases; 73 std::vector<OrderFence> ensure_releases;
73 { 74 {
74 base::AutoLock auto_lock(lock_); 75 base::AutoLock auto_lock(lock_);
75 while (!order_fence_queue_.empty()) { 76 while (!order_fence_queue_.empty()) {
76 const OrderFence& order_fence = order_fence_queue_.top(); 77 const OrderFence& order_fence = order_fence_queue_.top();
77 if (order_fence_queue_.top().order_num < order_num) { 78 if (order_fence_queue_.top().order_num < order_num) {
78 ensure_releases.push_back(order_fence); 79 ensure_releases.push_back(order_fence);
79 order_fence_queue_.pop(); 80 order_fence_queue_.pop();
80 continue; 81 continue;
81 } 82 }
82 break; 83 break;
83 } 84 }
84 } 85 }
85 86
86 for (OrderFence& order_fence : ensure_releases) { 87 for (OrderFence& order_fence : ensure_releases) {
87 order_fence.client_state->EnsureReleased(order_fence.fence_release); 88 order_fence.client_state->EnsureReleased(order_fence.fence_release);
88 } 89 }
89 } 90 }
90 91
92 void SyncPointOrderData::PauseProcessingOrderNumber(uint32_t order_num) {
93 DCHECK(processing_thread_checker_.CalledOnValidThread());
94 DCHECK_EQ(current_order_num_, order_num);
95 DCHECK(!paused_);
96 paused_ = true;
97 }
98
91 void SyncPointOrderData::FinishProcessingOrderNumber(uint32_t order_num) { 99 void SyncPointOrderData::FinishProcessingOrderNumber(uint32_t order_num) {
92 DCHECK(processing_thread_checker_.CalledOnValidThread()); 100 DCHECK(processing_thread_checker_.CalledOnValidThread());
93 DCHECK_EQ(current_order_num_, order_num); 101 DCHECK_EQ(current_order_num_, order_num);
102 DCHECK(!paused_);
94 103
95 // Catch invalid waits which were waiting on fence syncs that do not exist. 104 // Catch invalid waits which were waiting on fence syncs that do not exist.
96 // When we end processing an order number, we should release any fence syncs 105 // When we end processing an order number, we should release any fence syncs
97 // which were suppose to be released during this order number. 106 // which were suppose to be released during this order number.
98 // Release without the lock to avoid possible deadlocks. 107 // Release without the lock to avoid possible deadlocks.
99 std::vector<OrderFence> ensure_releases; 108 std::vector<OrderFence> ensure_releases;
100 { 109 {
101 base::AutoLock auto_lock(lock_); 110 base::AutoLock auto_lock(lock_);
102 DCHECK_GT(order_num, processed_order_num_); 111 DCHECK_GT(order_num, processed_order_num_);
103 processed_order_num_ = order_num; 112 processed_order_num_ = order_num;
(...skipping 17 matching lines...) Expand all
121 SyncPointOrderData::OrderFence::OrderFence( 130 SyncPointOrderData::OrderFence::OrderFence(
122 uint32_t order, 131 uint32_t order,
123 uint64_t release, 132 uint64_t release,
124 scoped_refptr<SyncPointClientState> state) 133 scoped_refptr<SyncPointClientState> state)
125 : order_num(order), fence_release(release), client_state(state) {} 134 : order_num(order), fence_release(release), client_state(state) {}
126 135
127 SyncPointOrderData::OrderFence::~OrderFence() {} 136 SyncPointOrderData::OrderFence::~OrderFence() {}
128 137
129 SyncPointOrderData::SyncPointOrderData() 138 SyncPointOrderData::SyncPointOrderData()
130 : current_order_num_(0), 139 : current_order_num_(0),
140 paused_(false),
131 destroyed_(false), 141 destroyed_(false),
132 processed_order_num_(0), 142 processed_order_num_(0),
133 unprocessed_order_num_(0) {} 143 unprocessed_order_num_(0) {}
134 144
135 SyncPointOrderData::~SyncPointOrderData() {} 145 SyncPointOrderData::~SyncPointOrderData() {}
136 146
137 bool SyncPointOrderData::ValidateReleaseOrderNumber( 147 bool SyncPointOrderData::ValidateReleaseOrderNumber(
138 scoped_refptr<SyncPointClientState> client_state, 148 scoped_refptr<SyncPointClientState> client_state,
139 uint32_t wait_order_num, 149 uint32_t wait_order_num,
140 uint64_t fence_release) { 150 uint64_t fence_release) {
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
235 245
236 fence_sync_release_ = release; 246 fence_sync_release_ = release;
237 while (!release_callback_queue_.empty() && 247 while (!release_callback_queue_.empty() &&
238 release_callback_queue_.top().release_count <= release) { 248 release_callback_queue_.top().release_count <= release) {
239 callback_list->push_back(release_callback_queue_.top().callback_closure); 249 callback_list->push_back(release_callback_queue_.top().callback_closure);
240 release_callback_queue_.pop(); 250 release_callback_queue_.pop();
241 } 251 }
242 } 252 }
243 253
244 SyncPointClient::~SyncPointClient() { 254 SyncPointClient::~SyncPointClient() {
245 // Release all fences on destruction. 255 if (namespace_id_ != gpu::CommandBufferNamespace::INVALID) {
246 ReleaseFenceSync(UINT64_MAX); 256 // Release all fences on destruction.
257 client_state_->ReleaseFenceSync(UINT64_MAX);
247 258
248 sync_point_manager_->DestroySyncPointClient(namespace_id_, client_id_); 259 sync_point_manager_->DestroySyncPointClient(namespace_id_, client_id_);
260 }
249 } 261 }
250 262
251 bool SyncPointClient::Wait(SyncPointClientState* release_state, 263 bool SyncPointClient::Wait(SyncPointClientState* release_state,
252 uint64_t release_count, 264 uint64_t release_count,
253 const base::Closure& wait_complete_callback) { 265 const base::Closure& wait_complete_callback) {
266 // Validate that this Wait call is between BeginProcessingOrderNumber() and
267 // FinishProcessingOrderNumber(), or else we may deadlock.
268 DCHECK(client_state_->order_data()->IsProcessingOrderNumber());
269
254 const uint32_t wait_order_number = 270 const uint32_t wait_order_number =
255 client_state_->order_data()->current_order_num(); 271 client_state_->order_data()->current_order_num();
256 272
257 // If waiting on self or wait was invalid, call the callback and return false. 273 // If waiting on self or wait was invalid, call the callback and return false.
258 if (client_state_ == release_state || 274 if (client_state_ == release_state ||
259 !release_state->WaitForRelease(wait_order_number, release_count, 275 !release_state->WaitForRelease(wait_order_number, release_count,
260 wait_complete_callback)) { 276 wait_complete_callback)) {
261 wait_complete_callback.Run(); 277 wait_complete_callback.Run();
262 return false; 278 return false;
263 } 279 }
264 return true; 280 return true;
265 } 281 }
266 282
267 bool SyncPointClient::WaitNonThreadSafe( 283 bool SyncPointClient::WaitNonThreadSafe(
268 SyncPointClientState* release_state, 284 SyncPointClientState* release_state,
269 uint64_t release_count, 285 uint64_t release_count,
270 scoped_refptr<base::SingleThreadTaskRunner> runner, 286 scoped_refptr<base::SingleThreadTaskRunner> runner,
271 const base::Closure& wait_complete_callback) { 287 const base::Closure& wait_complete_callback) {
272 return Wait(release_state, release_count, 288 return Wait(release_state, release_count,
273 base::Bind(&RunOnThread, runner, wait_complete_callback)); 289 base::Bind(&RunOnThread, runner, wait_complete_callback));
274 } 290 }
275 291
276 void SyncPointClient::ReleaseFenceSync(uint64_t release) { 292 bool SyncPointClient::WaitOutOfOrder(
277 client_state_->ReleaseFenceSync(release); 293 SyncPointClientState* release_state,
278 } 294 uint64_t release_count,
295 const base::Closure& wait_complete_callback) {
296 // Validate that this Wait call is not between BeginProcessingOrderNumber()
297 // and FinishProcessingOrderNumber(), or else we may deadlock.
298 DCHECK(!client_state_ ||
299 !client_state_->order_data()->IsProcessingOrderNumber());
279 300
280 SyncPointClient::SyncPointClient(SyncPointManager* sync_point_manager,
281 scoped_refptr<SyncPointOrderData> order_data,
282 CommandBufferNamespace namespace_id,
283 uint64_t client_id)
284 : sync_point_manager_(sync_point_manager),
285 client_state_(new SyncPointClientState(order_data)),
286 namespace_id_(namespace_id),
287 client_id_(client_id) {}
288
289 bool SyncPointClientWaiter::Wait(SyncPointClientState* release_state,
290 uint64_t release_count,
291 const base::Closure& wait_complete_callback) {
292 // No order number associated with the current execution context, using 301 // No order number associated with the current execution context, using
293 // UINT32_MAX will just assume the release is in the SyncPointClientState's 302 // UINT32_MAX will just assume the release is in the SyncPointClientState's
294 // order numbers to be executed. 303 // order numbers to be executed.
295 if (!release_state->WaitForRelease(UINT32_MAX, release_count, 304 if (!release_state->WaitForRelease(UINT32_MAX, release_count,
296 wait_complete_callback)) { 305 wait_complete_callback)) {
297 wait_complete_callback.Run(); 306 wait_complete_callback.Run();
298 return false; 307 return false;
299 } 308 }
300 return true; 309 return true;
301 } 310 }
302 311
303 bool SyncPointClientWaiter::WaitNonThreadSafe( 312 bool SyncPointClient::WaitOutOfOrderNonThreadSafe(
304 SyncPointClientState* release_state, 313 SyncPointClientState* release_state,
305 uint64_t release_count, 314 uint64_t release_count,
306 scoped_refptr<base::SingleThreadTaskRunner> runner, 315 scoped_refptr<base::SingleThreadTaskRunner> runner,
307 const base::Closure& wait_complete_callback) { 316 const base::Closure& wait_complete_callback) {
308 return Wait(release_state, release_count, 317 return WaitOutOfOrder(
309 base::Bind(&RunOnThread, runner, wait_complete_callback)); 318 release_state, release_count,
319 base::Bind(&RunOnThread, runner, wait_complete_callback));
310 } 320 }
311 321
322 void SyncPointClient::ReleaseFenceSync(uint64_t release) {
323 // Validate that this Release call is between BeginProcessingOrderNumber() and
324 // FinishProcessingOrderNumber(), or else we may deadlock.
325 DCHECK(client_state_->order_data()->IsProcessingOrderNumber());
326 client_state_->ReleaseFenceSync(release);
327 }
328
329 SyncPointClient::SyncPointClient()
330 : sync_point_manager_(nullptr),
331 namespace_id_(gpu::CommandBufferNamespace::INVALID),
332 client_id_(0) {}
333
334 SyncPointClient::SyncPointClient(SyncPointManager* sync_point_manager,
335 scoped_refptr<SyncPointOrderData> order_data,
336 CommandBufferNamespace namespace_id,
337 uint64_t client_id)
338 : sync_point_manager_(sync_point_manager),
339 client_state_(new SyncPointClientState(order_data)),
340 namespace_id_(namespace_id),
341 client_id_(client_id) {}
342
312 SyncPointManager::SyncPointManager(bool allow_threaded_wait) 343 SyncPointManager::SyncPointManager(bool allow_threaded_wait)
313 : allow_threaded_wait_(allow_threaded_wait), 344 : allow_threaded_wait_(allow_threaded_wait),
314 // To reduce the risk that a sync point created in a previous GPU process 345 // To reduce the risk that a sync point created in a previous GPU process
315 // will be in flight in the next GPU process, randomize the starting sync 346 // will be in flight in the next GPU process, randomize the starting sync
316 // point number. http://crbug.com/373452 347 // point number. http://crbug.com/373452
317 next_sync_point_(base::RandInt(1, kMaxSyncBase)), 348 next_sync_point_(base::RandInt(1, kMaxSyncBase)),
318 retire_cond_var_(&lock_) { 349 retire_cond_var_(&lock_) {
319 global_order_num_.GetNext(); 350 global_order_num_.GetNext();
320 } 351 }
321 352
(...skipping 13 matching lines...) Expand all
335 366
336 ClientMap& client_map = client_maps_[namespace_id]; 367 ClientMap& client_map = client_maps_[namespace_id];
337 std::pair<ClientMap::iterator, bool> result = client_map.insert( 368 std::pair<ClientMap::iterator, bool> result = client_map.insert(
338 std::make_pair(client_id, new SyncPointClient(this, order_data, 369 std::make_pair(client_id, new SyncPointClient(this, order_data,
339 namespace_id, client_id))); 370 namespace_id, client_id)));
340 DCHECK(result.second); 371 DCHECK(result.second);
341 372
342 return make_scoped_ptr(result.first->second); 373 return make_scoped_ptr(result.first->second);
343 } 374 }
344 375
376 scoped_ptr<SyncPointClient> SyncPointManager::CreateSyncPointClientWaiter() {
377 return make_scoped_ptr(new SyncPointClient);
378 }
379
345 scoped_refptr<SyncPointClientState> SyncPointManager::GetSyncPointClientState( 380 scoped_refptr<SyncPointClientState> SyncPointManager::GetSyncPointClientState(
346 CommandBufferNamespace namespace_id, uint64_t client_id) { 381 CommandBufferNamespace namespace_id, uint64_t client_id) {
347 if (namespace_id >= 0) { 382 if (namespace_id >= 0) {
348 DCHECK_LT(static_cast<size_t>(namespace_id), arraysize(client_maps_)); 383 DCHECK_LT(static_cast<size_t>(namespace_id), arraysize(client_maps_));
349 base::AutoLock auto_lock(client_maps_lock_); 384 base::AutoLock auto_lock(client_maps_lock_);
350 ClientMap& client_map = client_maps_[namespace_id]; 385 ClientMap& client_map = client_maps_[namespace_id];
351 ClientMap::iterator it = client_map.find(client_id); 386 ClientMap::iterator it = client_map.find(client_id);
352 if (it != client_map.end()) { 387 if (it != client_map.end()) {
353 return it->second->client_state(); 388 return it->second->client_state();
354 } 389 }
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
437 DCHECK_LT(static_cast<size_t>(namespace_id), arraysize(client_maps_)); 472 DCHECK_LT(static_cast<size_t>(namespace_id), arraysize(client_maps_));
438 473
439 base::AutoLock auto_lock(client_maps_lock_); 474 base::AutoLock auto_lock(client_maps_lock_);
440 ClientMap& client_map = client_maps_[namespace_id]; 475 ClientMap& client_map = client_maps_[namespace_id];
441 ClientMap::iterator it = client_map.find(client_id); 476 ClientMap::iterator it = client_map.find(client_id);
442 DCHECK(it != client_map.end()); 477 DCHECK(it != client_map.end());
443 client_map.erase(it); 478 client_map.erase(it);
444 } 479 }
445 480
446 } // namespace gpu 481 } // namespace gpu
OLDNEW
« no previous file with comments | « gpu/command_buffer/service/sync_point_manager.h ('k') | gpu/command_buffer/service/sync_point_manager_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698