| 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 "content/common/host_discardable_shared_memory_manager.h" | 5 #include "content/common/host_discardable_shared_memory_manager.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 | 8 |
| 9 #include "base/atomic_sequence_num.h" | 9 #include "base/atomic_sequence_num.h" |
| 10 #include "base/bind.h" | 10 #include "base/bind.h" |
| (...skipping 307 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 318 *shared_memory_handle = base::SharedMemory::NULLHandle(); | 318 *shared_memory_handle = base::SharedMemory::NULLHandle(); |
| 319 return; | 319 return; |
| 320 } | 320 } |
| 321 | 321 |
| 322 if (!memory->ShareToProcess(process_handle, shared_memory_handle)) { | 322 if (!memory->ShareToProcess(process_handle, shared_memory_handle)) { |
| 323 LOG(ERROR) << "Cannot share discardable memory segment"; | 323 LOG(ERROR) << "Cannot share discardable memory segment"; |
| 324 *shared_memory_handle = base::SharedMemory::NULLHandle(); | 324 *shared_memory_handle = base::SharedMemory::NULLHandle(); |
| 325 return; | 325 return; |
| 326 } | 326 } |
| 327 | 327 |
| 328 // Close file descriptor to avoid running out. |
| 329 memory->Close(); |
| 330 |
| 328 base::CheckedNumeric<size_t> checked_bytes_allocated = bytes_allocated_; | 331 base::CheckedNumeric<size_t> checked_bytes_allocated = bytes_allocated_; |
| 329 checked_bytes_allocated += memory->mapped_size(); | 332 checked_bytes_allocated += memory->mapped_size(); |
| 330 if (!checked_bytes_allocated.IsValid()) { | 333 if (!checked_bytes_allocated.IsValid()) { |
| 331 *shared_memory_handle = base::SharedMemory::NULLHandle(); | 334 *shared_memory_handle = base::SharedMemory::NULLHandle(); |
| 332 return; | 335 return; |
| 333 } | 336 } |
| 334 | 337 |
| 335 bytes_allocated_ = checked_bytes_allocated.ValueOrDie(); | 338 bytes_allocated_ = checked_bytes_allocated.ValueOrDie(); |
| 336 BytesAllocatedChanged(bytes_allocated_); | 339 BytesAllocatedChanged(bytes_allocated_); |
| 337 | 340 |
| 338 #if !defined(DISCARDABLE_SHARED_MEMORY_SHRINKING) | |
| 339 // Close file descriptor to avoid running out. | |
| 340 memory->Close(); | |
| 341 #endif | |
| 342 | |
| 343 scoped_refptr<MemorySegment> segment(new MemorySegment(memory.Pass())); | 341 scoped_refptr<MemorySegment> segment(new MemorySegment(memory.Pass())); |
| 344 process_segments[id] = segment.get(); | 342 process_segments[id] = segment.get(); |
| 345 segments_.push_back(segment.get()); | 343 segments_.push_back(segment.get()); |
| 346 std::push_heap(segments_.begin(), segments_.end(), CompareMemoryUsageTime); | 344 std::push_heap(segments_.begin(), segments_.end(), CompareMemoryUsageTime); |
| 347 | 345 |
| 348 if (bytes_allocated_ > memory_limit_) | 346 if (bytes_allocated_ > memory_limit_) |
| 349 ScheduleEnforceMemoryPolicy(); | 347 ScheduleEnforceMemoryPolicy(); |
| 350 } | 348 } |
| 351 | 349 |
| 352 void HostDiscardableSharedMemoryManager::DeletedDiscardableSharedMemory( | 350 void HostDiscardableSharedMemoryManager::DeletedDiscardableSharedMemory( |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 422 break; | 420 break; |
| 423 | 421 |
| 424 // Stop eviction attempts when the LRU segment is currently in use. | 422 // Stop eviction attempts when the LRU segment is currently in use. |
| 425 if (segments_.front()->memory()->last_known_usage() >= current_time) | 423 if (segments_.front()->memory()->last_known_usage() >= current_time) |
| 426 break; | 424 break; |
| 427 | 425 |
| 428 std::pop_heap(segments_.begin(), segments_.end(), CompareMemoryUsageTime); | 426 std::pop_heap(segments_.begin(), segments_.end(), CompareMemoryUsageTime); |
| 429 scoped_refptr<MemorySegment> segment = segments_.back(); | 427 scoped_refptr<MemorySegment> segment = segments_.back(); |
| 430 segments_.pop_back(); | 428 segments_.pop_back(); |
| 431 | 429 |
| 430 // Simply drop the reference and continue if memory has already been |
| 431 // unmapped. This happens when a memory segment has been deleted by |
| 432 // the client. |
| 433 if (!segment->memory()->mapped_size()) |
| 434 continue; |
| 435 |
| 432 // Attempt to purge LRU segment. When successful, released the memory. | 436 // Attempt to purge LRU segment. When successful, released the memory. |
| 433 if (segment->memory()->Purge(current_time)) { | 437 if (segment->memory()->Purge(current_time)) { |
| 434 #if defined(DISCARDABLE_SHARED_MEMORY_SHRINKING) | |
| 435 size_t size = segment->memory()->mapped_size(); | |
| 436 DCHECK_GE(bytes_allocated_, size); | |
| 437 bytes_allocated_ -= size; | |
| 438 // Shrink memory segment. This will immediately release the memory to | |
| 439 // the OS. | |
| 440 segment->memory()->Shrink(); | |
| 441 DCHECK_EQ(segment->memory()->mapped_size(), 0u); | |
| 442 #endif | |
| 443 ReleaseMemory(segment->memory()); | 438 ReleaseMemory(segment->memory()); |
| 444 continue; | 439 continue; |
| 445 } | 440 } |
| 446 | 441 |
| 447 // Add memory segment (with updated usage timestamp) back on heap after | 442 // Add memory segment (with updated usage timestamp) back on heap after |
| 448 // failed attempt to purge it. | 443 // failed attempt to purge it. |
| 449 segments_.push_back(segment.get()); | 444 segments_.push_back(segment.get()); |
| 450 std::push_heap(segments_.begin(), segments_.end(), CompareMemoryUsageTime); | 445 std::push_heap(segments_.begin(), segments_.end(), CompareMemoryUsageTime); |
| 451 } | 446 } |
| 452 | 447 |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 492 | 487 |
| 493 enforce_memory_policy_pending_ = true; | 488 enforce_memory_policy_pending_ = true; |
| 494 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( | 489 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( |
| 495 FROM_HERE, | 490 FROM_HERE, |
| 496 base::Bind(&HostDiscardableSharedMemoryManager::EnforceMemoryPolicy, | 491 base::Bind(&HostDiscardableSharedMemoryManager::EnforceMemoryPolicy, |
| 497 weak_ptr_factory_.GetWeakPtr()), | 492 weak_ptr_factory_.GetWeakPtr()), |
| 498 base::TimeDelta::FromMilliseconds(kEnforceMemoryPolicyDelayMs)); | 493 base::TimeDelta::FromMilliseconds(kEnforceMemoryPolicyDelayMs)); |
| 499 } | 494 } |
| 500 | 495 |
| 501 } // namespace content | 496 } // namespace content |
| OLD | NEW |