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 341 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
352 break; | 352 break; |
353 | 353 |
354 // Stop eviction attempts when the LRU segment is currently in use. | 354 // Stop eviction attempts when the LRU segment is currently in use. |
355 if (segments_.front()->memory()->last_known_usage() >= current_time) | 355 if (segments_.front()->memory()->last_known_usage() >= current_time) |
356 break; | 356 break; |
357 | 357 |
358 std::pop_heap(segments_.begin(), segments_.end(), CompareMemoryUsageTime); | 358 std::pop_heap(segments_.begin(), segments_.end(), CompareMemoryUsageTime); |
359 scoped_refptr<MemorySegment> segment = segments_.back(); | 359 scoped_refptr<MemorySegment> segment = segments_.back(); |
360 segments_.pop_back(); | 360 segments_.pop_back(); |
361 | 361 |
362 // Attempt to purge and truncate LRU segment. When successful, as much | 362 // Attempt to purge LRU segment. When successful, released the memory. |
363 // memory as possible will be released to the OS. How much memory is | 363 if (segment->memory()->Purge(current_time)) { |
364 // released depends on the platform. The child process should perform | |
365 // periodic cleanup to ensure that all memory is release within a | |
366 // reasonable amount of time. | |
367 if (segment->memory()->PurgeAndTruncate(current_time)) { | |
368 ReleaseMemory(segment->memory()); | 364 ReleaseMemory(segment->memory()); |
369 continue; | 365 continue; |
370 } | 366 } |
371 | 367 |
372 // Add memory segment (with updated usage timestamp) back on heap after | 368 // Add memory segment (with updated usage timestamp) back on heap after |
373 // failed attempt to purge it. | 369 // failed attempt to purge it. |
374 segments_.push_back(segment.get()); | 370 segments_.push_back(segment.get()); |
375 std::push_heap(segments_.begin(), segments_.end(), CompareMemoryUsageTime); | 371 std::push_heap(segments_.begin(), segments_.end(), CompareMemoryUsageTime); |
376 } | 372 } |
377 | 373 |
378 if (bytes_allocated_ != bytes_allocated_before_purging) | 374 if (bytes_allocated_ != bytes_allocated_before_purging) |
379 BytesAllocatedChanged(bytes_allocated_); | 375 BytesAllocatedChanged(bytes_allocated_); |
380 } | 376 } |
381 | 377 |
382 void HostDiscardableSharedMemoryManager::ReleaseMemory( | 378 void HostDiscardableSharedMemoryManager::ReleaseMemory( |
383 base::DiscardableSharedMemory* memory) { | 379 base::DiscardableSharedMemory* memory) { |
384 lock_.AssertAcquired(); | 380 lock_.AssertAcquired(); |
385 | 381 |
386 size_t size = memory->mapped_size(); | 382 size_t size = memory->mapped_size(); |
387 DCHECK_GE(bytes_allocated_, size); | 383 DCHECK_GE(bytes_allocated_, size); |
388 bytes_allocated_ -= size; | 384 bytes_allocated_ -= size; |
389 | 385 |
386 #if defined(OS_POSIX) && !defined(OS_ANDROID) | |
danakj
2015/03/19 16:41:56
Hmm.. the only thing I like a bit less is these gu
reveman
2015/03/19 19:23:05
Added DISCARDABLE_SHARED_MEMORY_SHRINKING define t
| |
387 // Shrink memory segment. This will immediately release the memory to the OS. | |
388 memory->Shrink(); | |
389 #endif | |
390 | |
390 // This will unmap the memory segment and drop our reference. The result | 391 // This will unmap the memory segment and drop our reference. The result |
391 // is that the memory will be released to the OS if the child process is | 392 // is that the memory will be released to the OS if the child process is |
392 // no longer referencing it. | 393 // no longer referencing it. |
393 // Note: We intentionally leave the segment in the |segments| vector to | 394 // Note: We intentionally leave the segment in the |segments| vector to |
394 // avoid reconstructing the heap. The element will be removed from the heap | 395 // avoid reconstructing the heap. The element will be removed from the heap |
395 // when its last usage time is older than all other segments. | 396 // when its last usage time is older than all other segments. |
396 memory->Close(); | 397 memory->Close(); |
397 } | 398 } |
398 | 399 |
399 void HostDiscardableSharedMemoryManager::BytesAllocatedChanged( | 400 void HostDiscardableSharedMemoryManager::BytesAllocatedChanged( |
(...skipping 18 matching lines...) Expand all Loading... | |
418 | 419 |
419 enforce_memory_policy_pending_ = true; | 420 enforce_memory_policy_pending_ = true; |
420 base::MessageLoop::current()->PostDelayedTask( | 421 base::MessageLoop::current()->PostDelayedTask( |
421 FROM_HERE, | 422 FROM_HERE, |
422 base::Bind(&HostDiscardableSharedMemoryManager::EnforceMemoryPolicy, | 423 base::Bind(&HostDiscardableSharedMemoryManager::EnforceMemoryPolicy, |
423 weak_ptr_factory_.GetWeakPtr()), | 424 weak_ptr_factory_.GetWeakPtr()), |
424 base::TimeDelta::FromMilliseconds(kEnforceMemoryPolicyDelayMs)); | 425 base::TimeDelta::FromMilliseconds(kEnforceMemoryPolicyDelayMs)); |
425 } | 426 } |
426 | 427 |
427 } // namespace content | 428 } // namespace content |
OLD | NEW |