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 | |
331 base::CheckedNumeric<size_t> checked_bytes_allocated = bytes_allocated_; | 328 base::CheckedNumeric<size_t> checked_bytes_allocated = bytes_allocated_; |
332 checked_bytes_allocated += memory->mapped_size(); | 329 checked_bytes_allocated += memory->mapped_size(); |
333 if (!checked_bytes_allocated.IsValid()) { | 330 if (!checked_bytes_allocated.IsValid()) { |
334 *shared_memory_handle = base::SharedMemory::NULLHandle(); | 331 *shared_memory_handle = base::SharedMemory::NULLHandle(); |
335 return; | 332 return; |
336 } | 333 } |
337 | 334 |
338 bytes_allocated_ = checked_bytes_allocated.ValueOrDie(); | 335 bytes_allocated_ = checked_bytes_allocated.ValueOrDie(); |
339 BytesAllocatedChanged(bytes_allocated_); | 336 BytesAllocatedChanged(bytes_allocated_); |
340 | 337 |
| 338 #if !defined(DISCARDABLE_SHARED_MEMORY_SHRINKING) |
| 339 // Close file descriptor to avoid running out. |
| 340 memory->Close(); |
| 341 #endif |
| 342 |
341 scoped_refptr<MemorySegment> segment(new MemorySegment(memory.Pass())); | 343 scoped_refptr<MemorySegment> segment(new MemorySegment(memory.Pass())); |
342 process_segments[id] = segment.get(); | 344 process_segments[id] = segment.get(); |
343 segments_.push_back(segment.get()); | 345 segments_.push_back(segment.get()); |
344 std::push_heap(segments_.begin(), segments_.end(), CompareMemoryUsageTime); | 346 std::push_heap(segments_.begin(), segments_.end(), CompareMemoryUsageTime); |
345 | 347 |
346 if (bytes_allocated_ > memory_limit_) | 348 if (bytes_allocated_ > memory_limit_) |
347 ScheduleEnforceMemoryPolicy(); | 349 ScheduleEnforceMemoryPolicy(); |
348 } | 350 } |
349 | 351 |
350 void HostDiscardableSharedMemoryManager::DeletedDiscardableSharedMemory( | 352 void HostDiscardableSharedMemoryManager::DeletedDiscardableSharedMemory( |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
422 // Stop eviction attempts when the LRU segment is currently in use. | 424 // Stop eviction attempts when the LRU segment is currently in use. |
423 if (segments_.front()->memory()->last_known_usage() >= current_time) | 425 if (segments_.front()->memory()->last_known_usage() >= current_time) |
424 break; | 426 break; |
425 | 427 |
426 std::pop_heap(segments_.begin(), segments_.end(), CompareMemoryUsageTime); | 428 std::pop_heap(segments_.begin(), segments_.end(), CompareMemoryUsageTime); |
427 scoped_refptr<MemorySegment> segment = segments_.back(); | 429 scoped_refptr<MemorySegment> segment = segments_.back(); |
428 segments_.pop_back(); | 430 segments_.pop_back(); |
429 | 431 |
430 // Attempt to purge LRU segment. When successful, released the memory. | 432 // Attempt to purge LRU segment. When successful, released the memory. |
431 if (segment->memory()->Purge(current_time)) { | 433 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 |
432 ReleaseMemory(segment->memory()); | 443 ReleaseMemory(segment->memory()); |
433 continue; | 444 continue; |
434 } | 445 } |
435 | 446 |
436 // Add memory segment (with updated usage timestamp) back on heap after | 447 // Add memory segment (with updated usage timestamp) back on heap after |
437 // failed attempt to purge it. | 448 // failed attempt to purge it. |
438 segments_.push_back(segment.get()); | 449 segments_.push_back(segment.get()); |
439 std::push_heap(segments_.begin(), segments_.end(), CompareMemoryUsageTime); | 450 std::push_heap(segments_.begin(), segments_.end(), CompareMemoryUsageTime); |
440 } | 451 } |
441 | 452 |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
481 | 492 |
482 enforce_memory_policy_pending_ = true; | 493 enforce_memory_policy_pending_ = true; |
483 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( | 494 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( |
484 FROM_HERE, | 495 FROM_HERE, |
485 base::Bind(&HostDiscardableSharedMemoryManager::EnforceMemoryPolicy, | 496 base::Bind(&HostDiscardableSharedMemoryManager::EnforceMemoryPolicy, |
486 weak_ptr_factory_.GetWeakPtr()), | 497 weak_ptr_factory_.GetWeakPtr()), |
487 base::TimeDelta::FromMilliseconds(kEnforceMemoryPolicyDelayMs)); | 498 base::TimeDelta::FromMilliseconds(kEnforceMemoryPolicyDelayMs)); |
488 } | 499 } |
489 | 500 |
490 } // namespace content | 501 } // namespace content |
OLD | NEW |