| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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 "components/discardable_memory/service/discardable_shared_memory_manage
r.h" | 5 #include "components/discardable_memory/service/discardable_shared_memory_manage
r.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <utility> | 8 #include <utility> |
| 9 | 9 |
| 10 #include "base/atomic_sequence_num.h" | 10 #include "base/atomic_sequence_num.h" |
| (...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 206 } | 206 } |
| 207 | 207 |
| 208 DiscardableSharedMemoryManager* DiscardableSharedMemoryManager::current() { | 208 DiscardableSharedMemoryManager* DiscardableSharedMemoryManager::current() { |
| 209 return g_discardable_shared_memory_manager.Pointer(); | 209 return g_discardable_shared_memory_manager.Pointer(); |
| 210 } | 210 } |
| 211 | 211 |
| 212 std::unique_ptr<base::DiscardableMemory> | 212 std::unique_ptr<base::DiscardableMemory> |
| 213 DiscardableSharedMemoryManager::AllocateLockedDiscardableMemory(size_t size) { | 213 DiscardableSharedMemoryManager::AllocateLockedDiscardableMemory(size_t size) { |
| 214 DCHECK_NE(size, 0u); | 214 DCHECK_NE(size, 0u); |
| 215 | 215 |
| 216 DiscardableSharedMemoryId new_id = | 216 int32_t new_id = g_next_discardable_shared_memory_id.GetNext(); |
| 217 g_next_discardable_shared_memory_id.GetNext(); | |
| 218 base::ProcessHandle current_process_handle = base::GetCurrentProcessHandle(); | |
| 219 | 217 |
| 220 // Note: Use DiscardableSharedMemoryHeap for in-process allocation | 218 // Note: Use DiscardableSharedMemoryHeap for in-process allocation |
| 221 // of discardable memory if the cost of each allocation is too high. | 219 // of discardable memory if the cost of each allocation is too high. |
| 222 base::SharedMemoryHandle handle; | 220 base::SharedMemoryHandle handle; |
| 223 AllocateLockedDiscardableSharedMemory( | 221 AllocateLockedDiscardableSharedMemory(kInvalidUniqueClientID, size, new_id, |
| 224 current_process_handle, kInvalidUniqueClientID, size, new_id, &handle); | 222 &handle); |
| 225 std::unique_ptr<base::DiscardableSharedMemory> memory( | 223 std::unique_ptr<base::DiscardableSharedMemory> memory( |
| 226 new base::DiscardableSharedMemory(handle)); | 224 new base::DiscardableSharedMemory(handle)); |
| 227 if (!memory->Map(size)) | 225 if (!memory->Map(size)) |
| 228 base::TerminateBecauseOutOfMemory(size); | 226 base::TerminateBecauseOutOfMemory(size); |
| 229 // Close file descriptor to avoid running out. | 227 // Close file descriptor to avoid running out. |
| 230 memory->Close(); | 228 memory->Close(); |
| 231 return base::MakeUnique<DiscardableMemoryImpl>( | 229 return base::MakeUnique<DiscardableMemoryImpl>( |
| 232 std::move(memory), | 230 std::move(memory), |
| 233 base::Bind( | 231 base::Bind( |
| 234 &DiscardableSharedMemoryManager::DeletedDiscardableSharedMemory, | 232 &DiscardableSharedMemoryManager::DeletedDiscardableSharedMemory, |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 301 static_cast<uint64_t>(resident_size)); | 299 static_cast<uint64_t>(resident_size)); |
| 302 } | 300 } |
| 303 #endif // defined(COUNT_RESIDENT_BYTES_SUPPORTED) | 301 #endif // defined(COUNT_RESIDENT_BYTES_SUPPORTED) |
| 304 } | 302 } |
| 305 } | 303 } |
| 306 return true; | 304 return true; |
| 307 } | 305 } |
| 308 | 306 |
| 309 void DiscardableSharedMemoryManager:: | 307 void DiscardableSharedMemoryManager:: |
| 310 AllocateLockedDiscardableSharedMemoryForClient( | 308 AllocateLockedDiscardableSharedMemoryForClient( |
| 311 base::ProcessHandle process_handle, | |
| 312 int client_id, | 309 int client_id, |
| 313 size_t size, | 310 size_t size, |
| 314 DiscardableSharedMemoryId id, | 311 int32_t id, |
| 315 base::SharedMemoryHandle* shared_memory_handle) { | 312 base::SharedMemoryHandle* shared_memory_handle) { |
| 316 AllocateLockedDiscardableSharedMemory(process_handle, client_id, size, id, | 313 AllocateLockedDiscardableSharedMemory(client_id, size, id, |
| 317 shared_memory_handle); | 314 shared_memory_handle); |
| 318 } | 315 } |
| 319 | 316 |
| 320 void DiscardableSharedMemoryManager::ClientDeletedDiscardableSharedMemory( | 317 void DiscardableSharedMemoryManager::ClientDeletedDiscardableSharedMemory( |
| 321 DiscardableSharedMemoryId id, | 318 int32_t id, |
| 322 int client_id) { | 319 int client_id) { |
| 323 DeletedDiscardableSharedMemory(id, client_id); | 320 DeletedDiscardableSharedMemory(id, client_id); |
| 324 } | 321 } |
| 325 | 322 |
| 326 void DiscardableSharedMemoryManager::ClientRemoved(int client_id) { | 323 void DiscardableSharedMemoryManager::ClientRemoved(int client_id) { |
| 327 base::AutoLock lock(lock_); | 324 base::AutoLock lock(lock_); |
| 328 | 325 |
| 329 auto it = clients_.find(client_id); | 326 auto it = clients_.find(client_id); |
| 330 if (it == clients_.end()) | 327 if (it == clients_.end()) |
| 331 return; | 328 return; |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 373 case base::MemoryState::SUSPENDED: | 370 case base::MemoryState::SUSPENDED: |
| 374 // Note that SUSPENDED never occurs in the main browser process so far. | 371 // Note that SUSPENDED never occurs in the main browser process so far. |
| 375 // Fall through. | 372 // Fall through. |
| 376 case base::MemoryState::UNKNOWN: | 373 case base::MemoryState::UNKNOWN: |
| 377 NOTREACHED(); | 374 NOTREACHED(); |
| 378 break; | 375 break; |
| 379 } | 376 } |
| 380 } | 377 } |
| 381 | 378 |
| 382 void DiscardableSharedMemoryManager::AllocateLockedDiscardableSharedMemory( | 379 void DiscardableSharedMemoryManager::AllocateLockedDiscardableSharedMemory( |
| 383 base::ProcessHandle process_handle, | |
| 384 int client_id, | 380 int client_id, |
| 385 size_t size, | 381 size_t size, |
| 386 DiscardableSharedMemoryId id, | 382 int32_t id, |
| 387 base::SharedMemoryHandle* shared_memory_handle) { | 383 base::SharedMemoryHandle* shared_memory_handle) { |
| 388 base::AutoLock lock(lock_); | 384 base::AutoLock lock(lock_); |
| 389 | 385 |
| 390 // Make sure |id| is not already in use. | 386 // Make sure |id| is not already in use. |
| 391 MemorySegmentMap& client_segments = clients_[client_id]; | 387 MemorySegmentMap& client_segments = clients_[client_id]; |
| 392 if (client_segments.find(id) != client_segments.end()) { | 388 if (client_segments.find(id) != client_segments.end()) { |
| 393 LOG(ERROR) << "Invalid discardable shared memory ID"; | 389 LOG(ERROR) << "Invalid discardable shared memory ID"; |
| 394 *shared_memory_handle = base::SharedMemory::NULLHandle(); | 390 *shared_memory_handle = base::SharedMemory::NULLHandle(); |
| 395 return; | 391 return; |
| 396 } | 392 } |
| (...skipping 12 matching lines...) Expand all Loading... |
| 409 if (bytes_allocated_ > limit) | 405 if (bytes_allocated_ > limit) |
| 410 ReduceMemoryUsageUntilWithinLimit(limit); | 406 ReduceMemoryUsageUntilWithinLimit(limit); |
| 411 | 407 |
| 412 std::unique_ptr<base::DiscardableSharedMemory> memory( | 408 std::unique_ptr<base::DiscardableSharedMemory> memory( |
| 413 new base::DiscardableSharedMemory); | 409 new base::DiscardableSharedMemory); |
| 414 if (!memory->CreateAndMap(size)) { | 410 if (!memory->CreateAndMap(size)) { |
| 415 *shared_memory_handle = base::SharedMemory::NULLHandle(); | 411 *shared_memory_handle = base::SharedMemory::NULLHandle(); |
| 416 return; | 412 return; |
| 417 } | 413 } |
| 418 | 414 |
| 419 if (!memory->ShareToProcess(process_handle, shared_memory_handle)) { | 415 *shared_memory_handle = base::SharedMemory::DuplicateHandle(memory->handle()); |
| 420 LOG(ERROR) << "Cannot share discardable memory segment"; | |
| 421 *shared_memory_handle = base::SharedMemory::NULLHandle(); | |
| 422 return; | |
| 423 } | |
| 424 | 416 |
| 425 // Close file descriptor to avoid running out. | 417 // Close file descriptor to avoid running out. |
| 426 memory->Close(); | 418 memory->Close(); |
| 427 | 419 |
| 428 base::CheckedNumeric<size_t> checked_bytes_allocated = bytes_allocated_; | 420 base::CheckedNumeric<size_t> checked_bytes_allocated = bytes_allocated_; |
| 429 checked_bytes_allocated += memory->mapped_size(); | 421 checked_bytes_allocated += memory->mapped_size(); |
| 430 if (!checked_bytes_allocated.IsValid()) { | 422 if (!checked_bytes_allocated.IsValid()) { |
| 431 *shared_memory_handle = base::SharedMemory::NULLHandle(); | 423 *shared_memory_handle = base::SharedMemory::NULLHandle(); |
| 432 return; | 424 return; |
| 433 } | 425 } |
| 434 | 426 |
| 435 bytes_allocated_ = checked_bytes_allocated.ValueOrDie(); | 427 bytes_allocated_ = checked_bytes_allocated.ValueOrDie(); |
| 436 BytesAllocatedChanged(bytes_allocated_); | 428 BytesAllocatedChanged(bytes_allocated_); |
| 437 | 429 |
| 438 scoped_refptr<MemorySegment> segment(new MemorySegment(std::move(memory))); | 430 scoped_refptr<MemorySegment> segment(new MemorySegment(std::move(memory))); |
| 439 client_segments[id] = segment.get(); | 431 client_segments[id] = segment.get(); |
| 440 segments_.push_back(segment.get()); | 432 segments_.push_back(segment.get()); |
| 441 std::push_heap(segments_.begin(), segments_.end(), CompareMemoryUsageTime); | 433 std::push_heap(segments_.begin(), segments_.end(), CompareMemoryUsageTime); |
| 442 | 434 |
| 443 if (bytes_allocated_ > memory_limit_) | 435 if (bytes_allocated_ > memory_limit_) |
| 444 ScheduleEnforceMemoryPolicy(); | 436 ScheduleEnforceMemoryPolicy(); |
| 445 } | 437 } |
| 446 | 438 |
| 447 void DiscardableSharedMemoryManager::DeletedDiscardableSharedMemory( | 439 void DiscardableSharedMemoryManager::DeletedDiscardableSharedMemory( |
| 448 DiscardableSharedMemoryId id, | 440 int32_t id, |
| 449 int client_id) { | 441 int client_id) { |
| 450 base::AutoLock lock(lock_); | 442 base::AutoLock lock(lock_); |
| 451 | 443 |
| 452 MemorySegmentMap& client_segments = clients_[client_id]; | 444 MemorySegmentMap& client_segments = clients_[client_id]; |
| 453 | 445 |
| 454 MemorySegmentMap::iterator segment_it = client_segments.find(id); | 446 MemorySegmentMap::iterator segment_it = client_segments.find(id); |
| 455 if (segment_it == client_segments.end()) { | 447 if (segment_it == client_segments.end()) { |
| 456 LOG(ERROR) << "Invalid discardable shared memory ID"; | 448 LOG(ERROR) << "Invalid discardable shared memory ID"; |
| 457 return; | 449 return; |
| 458 } | 450 } |
| (...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 581 return; | 573 return; |
| 582 | 574 |
| 583 enforce_memory_policy_pending_ = true; | 575 enforce_memory_policy_pending_ = true; |
| 584 DCHECK(enforce_memory_policy_task_runner_); | 576 DCHECK(enforce_memory_policy_task_runner_); |
| 585 enforce_memory_policy_task_runner_->PostDelayedTask( | 577 enforce_memory_policy_task_runner_->PostDelayedTask( |
| 586 FROM_HERE, enforce_memory_policy_callback_, | 578 FROM_HERE, enforce_memory_policy_callback_, |
| 587 base::TimeDelta::FromMilliseconds(kEnforceMemoryPolicyDelayMs)); | 579 base::TimeDelta::FromMilliseconds(kEnforceMemoryPolicyDelayMs)); |
| 588 } | 580 } |
| 589 | 581 |
| 590 } // namespace discardable_memory | 582 } // namespace discardable_memory |
| OLD | NEW |