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 |