Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 |
| 11 #include "base/bind.h" | 11 #include "base/bind.h" |
| 12 #include "base/location.h" | 12 #include "base/location.h" |
| 13 #include "base/logging.h" | 13 #include "base/logging.h" |
| 14 #include "base/memory/ptr_util.h" | |
| 14 #include "base/memory/ref_counted.h" | 15 #include "base/memory/ref_counted.h" |
| 15 #include "base/single_thread_task_runner.h" | 16 #include "base/single_thread_task_runner.h" |
| 16 | 17 |
| 17 namespace gpu { | 18 namespace gpu { |
| 18 | 19 |
| 19 namespace { | 20 namespace { |
| 20 | 21 |
| 21 void RunOnThread(scoped_refptr<base::SingleThreadTaskRunner> task_runner, | 22 void RunOnThread(scoped_refptr<base::SingleThreadTaskRunner> task_runner, |
| 22 const base::Closure& callback) { | 23 const base::Closure& callback) { |
| 23 if (task_runner->BelongsToCurrentThread()) { | 24 if (task_runner->BelongsToCurrentThread()) { |
| 24 callback.Run(); | 25 callback.Run(); |
| 25 } else { | 26 } else { |
| 26 task_runner->PostTask(FROM_HERE, callback); | 27 task_runner->PostTask(FROM_HERE, callback); |
| 27 } | 28 } |
| 28 } | 29 } |
| 29 | 30 |
| 30 } // namespace | 31 } // namespace |
| 31 | 32 |
| 32 scoped_refptr<SyncPointOrderData> SyncPointOrderData::Create() { | 33 SyncPointOrderData::OrderFence::OrderFence( |
| 33 return new SyncPointOrderData; | 34 uint32_t order, |
| 35 uint64_t release, | |
| 36 const base::Closure& callback, | |
| 37 scoped_refptr<SyncPointClientState> state) | |
| 38 : order_num(order), | |
| 39 fence_release(release), | |
| 40 release_callback(callback), | |
| 41 client_state(std::move(state)) {} | |
| 42 | |
| 43 SyncPointOrderData::OrderFence::OrderFence(const OrderFence& other) = default; | |
| 44 | |
| 45 SyncPointOrderData::OrderFence::~OrderFence() {} | |
| 46 | |
| 47 SyncPointOrderData::SyncPointOrderData(SyncPointManager* sync_point_manager, | |
| 48 SequenceId sequence_id) | |
| 49 : sync_point_manager_(sync_point_manager), sequence_id_(sequence_id) {} | |
| 50 | |
| 51 SyncPointOrderData::~SyncPointOrderData() { | |
| 52 DCHECK(destroyed_); | |
| 34 } | 53 } |
| 35 | 54 |
| 36 void SyncPointOrderData::Destroy() { | 55 void SyncPointOrderData::Destroy() { |
| 37 // Because of circular references between the SyncPointOrderData and | 56 // Because of circular references between the SyncPointOrderData and |
| 38 // SyncPointClientState, we must remove the references on destroy. Releasing | 57 // SyncPointClientState, we must remove the references on destroy. Releasing |
| 39 // the fence syncs in the order fence queue would be redundant at this point | 58 // the fence syncs in the order fence queue would be redundant at this point |
| 40 // because they are assumed to be released on the destruction of the | 59 // because they are assumed to be released on the destruction of the |
| 41 // SyncPointClient. | 60 // SyncPointClientState. |
| 42 base::AutoLock auto_lock(lock_); | 61 base::AutoLock auto_lock(lock_); |
| 62 DCHECK(!destroyed_); | |
| 43 destroyed_ = true; | 63 destroyed_ = true; |
| 44 while (!order_fence_queue_.empty()) { | 64 while (!order_fence_queue_.empty()) { |
| 45 order_fence_queue_.pop(); | 65 order_fence_queue_.pop(); |
| 46 } | 66 } |
| 67 sync_point_manager_->DestroyedSyncPointOrderData(sequence_id_); | |
| 47 } | 68 } |
| 48 | 69 |
| 49 uint32_t SyncPointOrderData::GenerateUnprocessedOrderNumber( | 70 uint32_t SyncPointOrderData::GenerateUnprocessedOrderNumber() { |
| 50 SyncPointManager* sync_point_manager) { | |
| 51 const uint32_t order_num = sync_point_manager->GenerateOrderNumber(); | |
| 52 base::AutoLock auto_lock(lock_); | 71 base::AutoLock auto_lock(lock_); |
| 53 unprocessed_order_num_ = order_num; | 72 DCHECK(!destroyed_); |
| 54 return order_num; | 73 unprocessed_order_num_ = sync_point_manager_->GenerateOrderNumber(); |
| 74 return unprocessed_order_num_; | |
| 55 } | 75 } |
| 56 | 76 |
| 57 void SyncPointOrderData::BeginProcessingOrderNumber(uint32_t order_num) { | 77 void SyncPointOrderData::BeginProcessingOrderNumber(uint32_t order_num) { |
| 58 DCHECK(processing_thread_checker_.CalledOnValidThread()); | 78 DCHECK(processing_thread_checker_.CalledOnValidThread()); |
| 59 DCHECK_GE(order_num, current_order_num_); | 79 DCHECK_GE(order_num, current_order_num_); |
| 60 // Use thread-safe accessors here because |processed_order_num_| and | 80 // Use thread-safe accessors here because |processed_order_num_| and |
| 61 // |unprocessed_order_num_| are protected by a lock. | 81 // |unprocessed_order_num_| are protected by a lock. |
| 62 DCHECK_GT(order_num, processed_order_num()); | 82 DCHECK_GT(order_num, processed_order_num()); |
| 63 DCHECK_LE(order_num, unprocessed_order_num()); | 83 DCHECK_LE(order_num, unprocessed_order_num()); |
| 64 current_order_num_ = order_num; | 84 current_order_num_ = order_num; |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 120 break; | 140 break; |
| 121 } | 141 } |
| 122 } | 142 } |
| 123 | 143 |
| 124 for (OrderFence& order_fence : ensure_releases) { | 144 for (OrderFence& order_fence : ensure_releases) { |
| 125 order_fence.client_state->EnsureWaitReleased(order_fence.fence_release, | 145 order_fence.client_state->EnsureWaitReleased(order_fence.fence_release, |
| 126 order_fence.release_callback); | 146 order_fence.release_callback); |
| 127 } | 147 } |
| 128 } | 148 } |
| 129 | 149 |
| 130 SyncPointOrderData::OrderFence::OrderFence( | |
| 131 uint32_t order, | |
| 132 uint64_t release, | |
| 133 const base::Closure& callback, | |
| 134 scoped_refptr<SyncPointClientState> state) | |
| 135 : order_num(order), | |
| 136 fence_release(release), | |
| 137 release_callback(callback), | |
| 138 client_state(std::move(state)) {} | |
| 139 | |
| 140 SyncPointOrderData::OrderFence::OrderFence(const OrderFence& other) = default; | |
| 141 | |
| 142 SyncPointOrderData::OrderFence::~OrderFence() {} | |
| 143 | |
| 144 SyncPointOrderData::SyncPointOrderData() {} | |
| 145 | |
| 146 SyncPointOrderData::~SyncPointOrderData() {} | |
| 147 | |
| 148 bool SyncPointOrderData::ValidateReleaseOrderNumber( | 150 bool SyncPointOrderData::ValidateReleaseOrderNumber( |
| 149 scoped_refptr<SyncPointClientState> client_state, | 151 scoped_refptr<SyncPointClientState> client_state, |
| 150 uint32_t wait_order_num, | 152 uint32_t wait_order_num, |
| 151 uint64_t fence_release, | 153 uint64_t fence_release, |
| 152 const base::Closure& release_callback) { | 154 const base::Closure& release_callback) { |
| 153 base::AutoLock auto_lock(lock_); | 155 base::AutoLock auto_lock(lock_); |
| 154 if (destroyed_) | 156 if (destroyed_) |
| 155 return false; | 157 return false; |
| 156 | 158 |
| 157 // Release should have a possible unprocessed order number lower than the wait | 159 // Release should have a possible unprocessed order number lower than the wait |
| (...skipping 19 matching lines...) Expand all Loading... | |
| 177 uint64_t release, | 179 uint64_t release, |
| 178 const base::Closure& callback) | 180 const base::Closure& callback) |
| 179 : release_count(release), callback_closure(callback) {} | 181 : release_count(release), callback_closure(callback) {} |
| 180 | 182 |
| 181 SyncPointClientState::ReleaseCallback::ReleaseCallback( | 183 SyncPointClientState::ReleaseCallback::ReleaseCallback( |
| 182 const ReleaseCallback& other) = default; | 184 const ReleaseCallback& other) = default; |
| 183 | 185 |
| 184 SyncPointClientState::ReleaseCallback::~ReleaseCallback() {} | 186 SyncPointClientState::ReleaseCallback::~ReleaseCallback() {} |
| 185 | 187 |
| 186 SyncPointClientState::SyncPointClientState( | 188 SyncPointClientState::SyncPointClientState( |
| 187 scoped_refptr<SyncPointOrderData> order_data) | 189 SyncPointManager* sync_point_manager, |
| 188 : order_data_(std::move(order_data)) {} | 190 scoped_refptr<SyncPointOrderData> order_data, |
| 191 CommandBufferNamespace namespace_id, | |
| 192 CommandBufferId command_buffer_id) | |
| 193 : sync_point_manager_(sync_point_manager), | |
| 194 order_data_(std::move(order_data)), | |
| 195 namespace_id_(namespace_id), | |
| 196 command_buffer_id_(command_buffer_id) {} | |
| 189 | 197 |
| 190 SyncPointClientState::~SyncPointClientState() {} | 198 SyncPointClientState::~SyncPointClientState() { |
| 199 DCHECK_EQ(UINT64_MAX, fence_sync_release_); | |
| 200 } | |
| 201 | |
| 202 void SyncPointClientState::Destroy() { | |
| 203 // Release all fences on destruction. | |
| 204 ReleaseFenceSyncHelper(UINT64_MAX); | |
| 205 DCHECK(sync_point_manager_); // not destroyed | |
| 206 sync_point_manager_->DestroyedSyncPointClientState(namespace_id_, | |
| 207 command_buffer_id_); | |
| 208 sync_point_manager_ = nullptr; | |
| 209 } | |
| 210 | |
| 211 bool SyncPointClientState::Wait(const SyncToken& sync_token, | |
| 212 const base::Closure& callback) { | |
| 213 DCHECK(sync_point_manager_); // not destroyed | |
| 214 // Validate that this Wait call is between BeginProcessingOrderNumber() and | |
| 215 // FinishProcessingOrderNumber(), or else we may deadlock. | |
| 216 DCHECK(order_data_->IsProcessingOrderNumber()); | |
| 217 if (sync_token.namespace_id() == namespace_id_ && | |
| 218 sync_token.command_buffer_id() == command_buffer_id_) { | |
| 219 return false; | |
| 220 } | |
| 221 uint32_t wait_order_number = order_data_->current_order_num(); | |
| 222 return sync_point_manager_->Wait(sync_token, wait_order_number, callback); | |
| 223 } | |
| 224 | |
| 225 bool SyncPointClientState::WaitNonThreadSafe( | |
| 226 const SyncToken& sync_token, | |
| 227 scoped_refptr<base::SingleThreadTaskRunner> task_runner, | |
| 228 const base::Closure& callback) { | |
| 229 return Wait(sync_token, base::Bind(&RunOnThread, task_runner, callback)); | |
| 230 } | |
| 191 | 231 |
| 192 bool SyncPointClientState::IsFenceSyncReleased(uint64_t release) { | 232 bool SyncPointClientState::IsFenceSyncReleased(uint64_t release) { |
| 193 base::AutoLock lock(fence_sync_lock_); | 233 base::AutoLock lock(fence_sync_lock_); |
| 194 return release <= fence_sync_release_; | 234 return release <= fence_sync_release_; |
| 195 } | 235 } |
| 196 | 236 |
| 197 bool SyncPointClientState::WaitForRelease(uint64_t release, | 237 bool SyncPointClientState::WaitForRelease(uint64_t release, |
| 198 uint32_t wait_order_num, | 238 uint32_t wait_order_num, |
| 199 const base::Closure& callback) { | 239 const base::Closure& callback) { |
| 200 // Lock must be held the whole time while we validate otherwise it could be | 240 // Lock must be held the whole time while we validate otherwise it could be |
| 201 // released while we are checking. | 241 // released while we are checking. |
| 202 { | 242 { |
| 203 base::AutoLock auto_lock(fence_sync_lock_); | 243 base::AutoLock auto_lock(fence_sync_lock_); |
| 204 if (release > fence_sync_release_ && | 244 if (release > fence_sync_release_ && |
| 205 order_data_->ValidateReleaseOrderNumber(this, wait_order_num, release, | 245 order_data_->ValidateReleaseOrderNumber(this, wait_order_num, release, |
| 206 callback)) { | 246 callback)) { |
| 207 // Add the callback which will be called upon release. | 247 // Add the callback which will be called upon release. |
| 208 release_callback_queue_.push(ReleaseCallback(release, callback)); | 248 release_callback_queue_.push(ReleaseCallback(release, callback)); |
| 209 return true; | 249 return true; |
| 210 } | 250 } |
| 211 } | 251 } |
| 212 // Already released, do not run the callback. | 252 // Already released, do not run the callback. |
| 213 return false; | 253 return false; |
| 214 } | 254 } |
| 215 | 255 |
| 216 void SyncPointClientState::ReleaseFenceSync(uint64_t release) { | 256 void SyncPointClientState::ReleaseFenceSync(uint64_t release) { |
| 257 // Validate that this Release call is between BeginProcessingOrderNumber() and | |
| 258 // FinishProcessingOrderNumber(), or else we may deadlock. | |
| 259 DCHECK(order_data_->IsProcessingOrderNumber()); | |
| 260 ReleaseFenceSyncHelper(release); | |
| 261 } | |
| 262 | |
| 263 void SyncPointClientState::ReleaseFenceSyncHelper(uint64_t release) { | |
| 217 // Call callbacks without the lock to avoid possible deadlocks. | 264 // Call callbacks without the lock to avoid possible deadlocks. |
| 218 std::vector<base::Closure> callback_list; | 265 std::vector<base::Closure> callback_list; |
| 219 { | 266 { |
| 220 base::AutoLock auto_lock(fence_sync_lock_); | 267 base::AutoLock auto_lock(fence_sync_lock_); |
| 221 | 268 |
| 222 DLOG_IF(ERROR, release <= fence_sync_release_) | 269 DLOG_IF(ERROR, release <= fence_sync_release_) |
| 223 << "Client submitted fence releases out of order."; | 270 << "Client submitted fence releases out of order."; |
| 224 fence_sync_release_ = release; | 271 fence_sync_release_ = release; |
| 225 | 272 |
| 226 while (!release_callback_queue_.empty() && | 273 while (!release_callback_queue_.empty() && |
| 227 release_callback_queue_.top().release_count <= release) { | 274 release_callback_queue_.top().release_count <= release) { |
| 228 callback_list.push_back(release_callback_queue_.top().callback_closure); | 275 callback_list.push_back(release_callback_queue_.top().callback_closure); |
| 229 release_callback_queue_.pop(); | 276 release_callback_queue_.pop(); |
| 230 } | 277 } |
| 231 } | 278 } |
| 232 | 279 |
| 233 for (const base::Closure& closure : callback_list) { | 280 for (const base::Closure& closure : callback_list) |
| 234 closure.Run(); | 281 closure.Run(); |
| 235 } | |
| 236 } | 282 } |
| 237 | 283 |
| 238 void SyncPointClientState::EnsureWaitReleased(uint64_t release, | 284 void SyncPointClientState::EnsureWaitReleased(uint64_t release, |
| 239 const base::Closure& callback) { | 285 const base::Closure& callback) { |
| 240 // Call callbacks without the lock to avoid possible deadlocks. | 286 // Call callbacks without the lock to avoid possible deadlocks. |
| 241 bool call_callback = false; | 287 bool call_callback = false; |
| 242 { | 288 { |
| 243 base::AutoLock auto_lock(fence_sync_lock_); | 289 base::AutoLock auto_lock(fence_sync_lock_); |
| 244 if (release <= fence_sync_release_) | 290 if (release <= fence_sync_release_) |
| 245 return; | 291 return; |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 266 release_callback_queue_.push(popped_callback); | 312 release_callback_queue_.push(popped_callback); |
| 267 } | 313 } |
| 268 } | 314 } |
| 269 | 315 |
| 270 if (call_callback) { | 316 if (call_callback) { |
| 271 // This effectively releases the wait without releasing the fence. | 317 // This effectively releases the wait without releasing the fence. |
| 272 callback.Run(); | 318 callback.Run(); |
| 273 } | 319 } |
| 274 } | 320 } |
| 275 | 321 |
| 276 SyncPointClient::SyncPointClient(SyncPointManager* sync_point_manager, | |
| 277 scoped_refptr<SyncPointOrderData> order_data, | |
| 278 CommandBufferNamespace namespace_id, | |
| 279 CommandBufferId command_buffer_id) | |
| 280 : sync_point_manager_(sync_point_manager), | |
| 281 order_data_(std::move(order_data)), | |
| 282 client_state_(new SyncPointClientState(order_data_)), | |
| 283 namespace_id_(namespace_id), | |
| 284 command_buffer_id_(command_buffer_id) { | |
| 285 sync_point_manager_->RegisterSyncPointClient(client_state_, namespace_id, | |
| 286 command_buffer_id); | |
| 287 } | |
| 288 | |
| 289 SyncPointClient::~SyncPointClient() { | |
| 290 // Release all fences on destruction. | |
| 291 client_state_->ReleaseFenceSync(UINT64_MAX); | |
| 292 sync_point_manager_->DeregisterSyncPointClient(namespace_id_, | |
| 293 command_buffer_id_); | |
| 294 } | |
| 295 | |
| 296 bool SyncPointClient::Wait(const SyncToken& sync_token, | |
| 297 const base::Closure& callback) { | |
| 298 // Validate that this Wait call is between BeginProcessingOrderNumber() and | |
| 299 // FinishProcessingOrderNumber(), or else we may deadlock. | |
| 300 DCHECK(order_data_->IsProcessingOrderNumber()); | |
| 301 if (sync_token.namespace_id() == namespace_id_ && | |
| 302 sync_token.command_buffer_id() == command_buffer_id_) { | |
| 303 return false; | |
| 304 } | |
| 305 uint32_t wait_order_number = order_data_->current_order_num(); | |
| 306 return sync_point_manager_->Wait(sync_token, wait_order_number, callback); | |
| 307 } | |
| 308 | |
| 309 bool SyncPointClient::WaitNonThreadSafe( | |
| 310 const SyncToken& sync_token, | |
| 311 scoped_refptr<base::SingleThreadTaskRunner> task_runner, | |
| 312 const base::Closure& callback) { | |
| 313 return Wait(sync_token, base::Bind(&RunOnThread, task_runner, callback)); | |
| 314 } | |
| 315 | |
| 316 void SyncPointClient::ReleaseFenceSync(uint64_t release) { | |
| 317 // Validate that this Release call is between BeginProcessingOrderNumber() and | |
| 318 // FinishProcessingOrderNumber(), or else we may deadlock. | |
| 319 DCHECK(order_data_->IsProcessingOrderNumber()); | |
| 320 client_state_->ReleaseFenceSync(release); | |
| 321 } | |
| 322 | |
| 323 SyncPointManager::SyncPointManager() { | 322 SyncPointManager::SyncPointManager() { |
| 324 global_order_num_.GetNext(); | 323 order_num_generator_.GetNext(); |
| 325 } | 324 } |
| 326 | 325 |
| 327 SyncPointManager::~SyncPointManager() { | 326 SyncPointManager::~SyncPointManager() { |
| 327 DCHECK(order_data_map_.empty()); | |
| 328 for (const ClientStateMap& client_state_map : client_state_maps_) | 328 for (const ClientStateMap& client_state_map : client_state_maps_) |
| 329 DCHECK(client_state_map.empty()); | 329 DCHECK(client_state_map.empty()); |
| 330 } | 330 } |
| 331 | 331 |
| 332 scoped_refptr<SyncPointOrderData> SyncPointManager::CreateSyncPointOrderData() { | |
| 333 base::AutoLock auto_lock(lock_); | |
| 334 SequenceId sequence_id = SequenceId::FromUnsafeValue(next_sequence_id_++); | |
| 335 scoped_refptr<SyncPointOrderData> order_data = | |
| 336 new SyncPointOrderData(this, sequence_id); | |
| 337 DCHECK(!order_data_map_.count(sequence_id)); | |
| 338 order_data_map_.insert(std::make_pair(sequence_id, order_data)); | |
| 339 return order_data; | |
| 340 } | |
| 341 | |
| 342 void SyncPointManager::DestroyedSyncPointOrderData(SequenceId sequence_id) { | |
| 343 base::AutoLock auto_lock(lock_); | |
| 344 DCHECK(order_data_map_.count(sequence_id)); | |
| 345 order_data_map_.erase(sequence_id); | |
| 346 } | |
| 347 | |
| 348 scoped_refptr<SyncPointClientState> | |
| 349 SyncPointManager::CreateSyncPointClientState( | |
| 350 CommandBufferNamespace namespace_id, | |
| 351 CommandBufferId command_buffer_id, | |
| 352 SequenceId sequence_id) { | |
| 353 scoped_refptr<SyncPointOrderData> order_data = | |
| 354 GetSyncPointOrderData(sequence_id); | |
| 355 | |
| 356 scoped_refptr<SyncPointClientState> client_state = new SyncPointClientState( | |
| 357 this, order_data, namespace_id, command_buffer_id); | |
| 358 | |
| 359 { | |
| 360 base::AutoLock auto_lock(lock_); | |
| 361 DCHECK_GE(namespace_id, 0); | |
| 362 DCHECK_LT(static_cast<size_t>(namespace_id), arraysize(client_state_maps_)); | |
| 363 DCHECK(!client_state_maps_[namespace_id].count(command_buffer_id)); | |
| 364 client_state_maps_[namespace_id].insert( | |
| 365 std::make_pair(command_buffer_id, client_state)); | |
| 366 } | |
| 367 | |
| 368 return client_state; | |
| 369 } | |
| 370 | |
| 371 void SyncPointManager::DestroyedSyncPointClientState( | |
| 372 CommandBufferNamespace namespace_id, | |
| 373 CommandBufferId command_buffer_id) { | |
| 374 base::AutoLock auto_lock(lock_); | |
| 375 DCHECK_GE(namespace_id, 0); | |
| 376 DCHECK_LT(static_cast<size_t>(namespace_id), arraysize(client_state_maps_)); | |
| 377 DCHECK(client_state_maps_[namespace_id].count(command_buffer_id)); | |
| 378 client_state_maps_[namespace_id].erase(command_buffer_id); | |
| 379 } | |
| 380 | |
| 332 bool SyncPointManager::IsSyncTokenReleased(const SyncToken& sync_token) { | 381 bool SyncPointManager::IsSyncTokenReleased(const SyncToken& sync_token) { |
| 333 scoped_refptr<SyncPointClientState> release_state = GetSyncPointClientState( | 382 scoped_refptr<SyncPointClientState> release_state = GetSyncPointClientState( |
| 334 sync_token.namespace_id(), sync_token.command_buffer_id()); | 383 sync_token.namespace_id(), sync_token.command_buffer_id()); |
| 335 if (release_state) | 384 if (release_state) |
| 336 return release_state->IsFenceSyncReleased(sync_token.release_count()); | 385 return release_state->IsFenceSyncReleased(sync_token.release_count()); |
| 337 return true; | 386 return true; |
| 338 } | 387 } |
| 339 | 388 |
| 389 SequenceId SyncPointManager::GetSyncTokenReleaseSequenceId( | |
| 390 const SyncToken& sync_token) { | |
| 391 scoped_refptr<SyncPointClientState> client_state = GetSyncPointClientState( | |
| 392 sync_token.namespace_id(), sync_token.command_buffer_id()); | |
| 393 if (client_state) | |
| 394 return client_state->sequence_id(); | |
| 395 return SequenceId(); | |
| 396 } | |
| 397 | |
| 398 uint32_t SyncPointManager::GetProcessedOrderNum() const { | |
| 399 // Copy order data map to prevent deadlock. | |
|
piman
2017/03/20 21:30:23
That seems expensive... Which lock order inversion
sunnyps
2017/03/20 21:40:34
Yes, it's the inversion in Destroy. I've changed D
| |
| 400 OrderDataMap order_data_map; | |
| 401 { | |
| 402 base::AutoLock auto_lock(lock_); | |
| 403 order_data_map = order_data_map_; | |
| 404 } | |
| 405 uint32_t processed_order_num = 0; | |
| 406 for (const auto& kv : order_data_map) { | |
| 407 processed_order_num = | |
| 408 std::max(processed_order_num, kv.second->processed_order_num()); | |
| 409 } | |
| 410 return processed_order_num; | |
| 411 } | |
| 412 | |
| 413 uint32_t SyncPointManager::GetUnprocessedOrderNum() const { | |
| 414 // Copy order data map to prevent deadlock. | |
| 415 OrderDataMap order_data_map; | |
| 416 { | |
| 417 base::AutoLock auto_lock(lock_); | |
| 418 order_data_map = order_data_map_; | |
| 419 } | |
| 420 uint32_t unprocessed_order_num = 0; | |
| 421 for (const auto& kv : order_data_map) { | |
| 422 unprocessed_order_num = | |
| 423 std::max(unprocessed_order_num, kv.second->unprocessed_order_num()); | |
| 424 } | |
| 425 return unprocessed_order_num; | |
| 426 } | |
| 427 | |
| 340 bool SyncPointManager::Wait(const SyncToken& sync_token, | 428 bool SyncPointManager::Wait(const SyncToken& sync_token, |
| 341 uint32_t wait_order_num, | 429 uint32_t wait_order_num, |
| 342 const base::Closure& callback) { | 430 const base::Closure& callback) { |
| 343 scoped_refptr<SyncPointClientState> release_state = GetSyncPointClientState( | 431 scoped_refptr<SyncPointClientState> release_state = GetSyncPointClientState( |
| 344 sync_token.namespace_id(), sync_token.command_buffer_id()); | 432 sync_token.namespace_id(), sync_token.command_buffer_id()); |
| 345 if (release_state && | 433 if (release_state && |
| 346 release_state->WaitForRelease(sync_token.release_count(), wait_order_num, | 434 release_state->WaitForRelease(sync_token.release_count(), wait_order_num, |
| 347 callback)) { | 435 callback)) { |
| 348 return true; | 436 return true; |
| 349 } | 437 } |
| (...skipping 19 matching lines...) Expand all Loading... | |
| 369 } | 457 } |
| 370 | 458 |
| 371 bool SyncPointManager::WaitOutOfOrderNonThreadSafe( | 459 bool SyncPointManager::WaitOutOfOrderNonThreadSafe( |
| 372 const SyncToken& trusted_sync_token, | 460 const SyncToken& trusted_sync_token, |
| 373 scoped_refptr<base::SingleThreadTaskRunner> task_runner, | 461 scoped_refptr<base::SingleThreadTaskRunner> task_runner, |
| 374 const base::Closure& callback) { | 462 const base::Closure& callback) { |
| 375 return WaitOutOfOrder(trusted_sync_token, | 463 return WaitOutOfOrder(trusted_sync_token, |
| 376 base::Bind(&RunOnThread, task_runner, callback)); | 464 base::Bind(&RunOnThread, task_runner, callback)); |
| 377 } | 465 } |
| 378 | 466 |
| 379 void SyncPointManager::RegisterSyncPointClient( | |
| 380 scoped_refptr<SyncPointClientState> client_state, | |
| 381 CommandBufferNamespace namespace_id, | |
| 382 CommandBufferId command_buffer_id) { | |
| 383 DCHECK_GE(namespace_id, 0); | |
| 384 DCHECK_LT(static_cast<size_t>(namespace_id), arraysize(client_state_maps_)); | |
| 385 | |
| 386 base::AutoLock auto_lock(client_state_maps_lock_); | |
| 387 DCHECK(!client_state_maps_[namespace_id].count(command_buffer_id)); | |
| 388 client_state_maps_[namespace_id].insert( | |
| 389 std::make_pair(command_buffer_id, std::move(client_state))); | |
| 390 } | |
| 391 | |
| 392 void SyncPointManager::DeregisterSyncPointClient( | |
| 393 CommandBufferNamespace namespace_id, | |
| 394 CommandBufferId command_buffer_id) { | |
| 395 DCHECK_GE(namespace_id, 0); | |
| 396 DCHECK_LT(static_cast<size_t>(namespace_id), arraysize(client_state_maps_)); | |
| 397 | |
| 398 base::AutoLock auto_lock(client_state_maps_lock_); | |
| 399 DCHECK(client_state_maps_[namespace_id].count(command_buffer_id)); | |
| 400 client_state_maps_[namespace_id].erase(command_buffer_id); | |
| 401 } | |
| 402 | |
| 403 uint32_t SyncPointManager::GenerateOrderNumber() { | 467 uint32_t SyncPointManager::GenerateOrderNumber() { |
| 404 return global_order_num_.GetNext(); | 468 return order_num_generator_.GetNext(); |
| 405 } | 469 } |
| 406 | 470 |
| 407 scoped_refptr<SyncPointClientState> SyncPointManager::GetSyncPointClientState( | 471 scoped_refptr<SyncPointClientState> SyncPointManager::GetSyncPointClientState( |
| 408 CommandBufferNamespace namespace_id, | 472 CommandBufferNamespace namespace_id, |
| 409 CommandBufferId command_buffer_id) { | 473 CommandBufferId command_buffer_id) { |
| 410 if (namespace_id >= 0) { | 474 if (namespace_id >= 0) { |
| 411 DCHECK_LT(static_cast<size_t>(namespace_id), arraysize(client_state_maps_)); | 475 DCHECK_LT(static_cast<size_t>(namespace_id), arraysize(client_state_maps_)); |
| 412 base::AutoLock auto_lock(client_state_maps_lock_); | 476 base::AutoLock auto_lock(lock_); |
| 413 ClientStateMap& client_state_map = client_state_maps_[namespace_id]; | 477 ClientStateMap& client_state_map = client_state_maps_[namespace_id]; |
| 414 auto it = client_state_map.find(command_buffer_id); | 478 auto it = client_state_map.find(command_buffer_id); |
| 415 if (it != client_state_map.end()) | 479 if (it != client_state_map.end()) |
| 416 return it->second; | 480 return it->second; |
| 417 } | 481 } |
| 418 return nullptr; | 482 return nullptr; |
| 419 } | 483 } |
| 420 | 484 |
| 485 scoped_refptr<SyncPointOrderData> SyncPointManager::GetSyncPointOrderData( | |
| 486 SequenceId sequence_id) { | |
| 487 base::AutoLock auto_lock(lock_); | |
| 488 auto it = order_data_map_.find(sequence_id); | |
| 489 if (it != order_data_map_.end()) | |
| 490 return it->second; | |
| 491 return nullptr; | |
| 492 } | |
| 493 | |
| 421 } // namespace gpu | 494 } // namespace gpu |
| OLD | NEW |