Serenity Operating System
at master 71 lines 2.7 kB view raw
1/* 2 * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org> 3 * 4 * SPDX-License-Identifier: BSD-2-Clause 5 */ 6 7#include <Kernel/Memory/AnonymousVMObject.h> 8#include <Kernel/Memory/InodeVMObject.h> 9#include <Kernel/Memory/MemoryManager.h> 10#include <Kernel/Process.h> 11 12namespace Kernel { 13 14ErrorOr<FlatPtr> Process::sys$purge(int mode) 15{ 16 VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this); 17 TRY(require_no_promises()); 18 auto credentials = this->credentials(); 19 if (!credentials->is_superuser()) 20 return EPERM; 21 size_t purged_page_count = 0; 22 if (mode & PURGE_ALL_VOLATILE) { 23 Vector<NonnullLockRefPtr<Memory::AnonymousVMObject>> vmobjects; 24 { 25 ErrorOr<void> result; 26 Memory::MemoryManager::for_each_vmobject([&](auto& vmobject) { 27 if (vmobject.is_anonymous()) { 28 // In the event that the append fails, only attempt to continue 29 // the purge if we have already appended something successfully. 30 if (auto append_result = vmobjects.try_append(static_cast<Memory::AnonymousVMObject&>(vmobject)); append_result.is_error() && vmobjects.is_empty()) { 31 result = append_result.release_error(); 32 return IterationDecision::Break; 33 } 34 } 35 return IterationDecision::Continue; 36 }); 37 38 if (result.is_error()) 39 return result.release_error(); 40 } 41 for (auto& vmobject : vmobjects) { 42 purged_page_count += vmobject->purge(); 43 } 44 } 45 if (mode & PURGE_ALL_CLEAN_INODE) { 46 Vector<NonnullLockRefPtr<Memory::InodeVMObject>> vmobjects; 47 { 48 ErrorOr<void> result; 49 Memory::MemoryManager::for_each_vmobject([&](auto& vmobject) { 50 if (vmobject.is_inode()) { 51 // In the event that the append fails, only attempt to continue 52 // the purge if we have already appended something successfully. 53 if (auto append_result = vmobjects.try_append(static_cast<Memory::InodeVMObject&>(vmobject)); append_result.is_error() && vmobjects.is_empty()) { 54 result = append_result.release_error(); 55 return IterationDecision::Break; 56 } 57 } 58 return IterationDecision::Continue; 59 }); 60 61 if (result.is_error()) 62 return result.release_error(); 63 } 64 for (auto& vmobject : vmobjects) { 65 purged_page_count += vmobject->release_all_clean_pages(); 66 } 67 } 68 return purged_page_count; 69} 70 71}