mirror of
				https://github.com/RGBCube/serenity
				synced 2025-10-31 16:52:43 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			97 lines
		
	
	
	
		
			2.1 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			97 lines
		
	
	
	
		
			2.1 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| /*
 | |
|  * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
 | |
|  *
 | |
|  * SPDX-License-Identifier: BSD-2-Clause
 | |
|  */
 | |
| 
 | |
| #include <Kernel/Arch/x86/InterruptDisabler.h>
 | |
| #include <Kernel/FileSystem/Inode.h>
 | |
| #include <Kernel/VM/InodeVMObject.h>
 | |
| #include <Kernel/VM/MemoryManager.h>
 | |
| 
 | |
| namespace Kernel {
 | |
| 
 | |
| InodeVMObject::InodeVMObject(Inode& inode, size_t size)
 | |
|     : VMObject(size)
 | |
|     , m_inode(inode)
 | |
|     , m_dirty_pages(page_count(), false)
 | |
| {
 | |
| }
 | |
| 
 | |
| InodeVMObject::InodeVMObject(const InodeVMObject& other)
 | |
|     : VMObject(other)
 | |
|     , m_inode(other.m_inode)
 | |
|     , m_dirty_pages(page_count(), false)
 | |
| {
 | |
|     for (size_t i = 0; i < page_count(); ++i)
 | |
|         m_dirty_pages.set(i, other.m_dirty_pages.get(i));
 | |
| }
 | |
| 
 | |
| InodeVMObject::~InodeVMObject()
 | |
| {
 | |
| }
 | |
| 
 | |
| size_t InodeVMObject::amount_clean() const
 | |
| {
 | |
|     size_t count = 0;
 | |
|     VERIFY(page_count() == m_dirty_pages.size());
 | |
|     for (size_t i = 0; i < page_count(); ++i) {
 | |
|         if (!m_dirty_pages.get(i) && m_physical_pages[i])
 | |
|             ++count;
 | |
|     }
 | |
|     return count * PAGE_SIZE;
 | |
| }
 | |
| 
 | |
| size_t InodeVMObject::amount_dirty() const
 | |
| {
 | |
|     size_t count = 0;
 | |
|     for (size_t i = 0; i < m_dirty_pages.size(); ++i) {
 | |
|         if (m_dirty_pages.get(i))
 | |
|             ++count;
 | |
|     }
 | |
|     return count * PAGE_SIZE;
 | |
| }
 | |
| 
 | |
| int InodeVMObject::release_all_clean_pages()
 | |
| {
 | |
|     Locker locker(m_paging_lock);
 | |
|     return release_all_clean_pages_impl();
 | |
| }
 | |
| 
 | |
| int InodeVMObject::release_all_clean_pages_impl()
 | |
| {
 | |
|     int count = 0;
 | |
|     InterruptDisabler disabler;
 | |
|     for (size_t i = 0; i < page_count(); ++i) {
 | |
|         if (!m_dirty_pages.get(i) && m_physical_pages[i]) {
 | |
|             m_physical_pages[i] = nullptr;
 | |
|             ++count;
 | |
|         }
 | |
|     }
 | |
|     for_each_region([](auto& region) {
 | |
|         region.remap();
 | |
|     });
 | |
|     return count;
 | |
| }
 | |
| 
 | |
| u32 InodeVMObject::writable_mappings() const
 | |
| {
 | |
|     u32 count = 0;
 | |
|     const_cast<InodeVMObject&>(*this).for_each_region([&](auto& region) {
 | |
|         if (region.is_writable())
 | |
|             ++count;
 | |
|     });
 | |
|     return count;
 | |
| }
 | |
| 
 | |
| u32 InodeVMObject::executable_mappings() const
 | |
| {
 | |
|     u32 count = 0;
 | |
|     const_cast<InodeVMObject&>(*this).for_each_region([&](auto& region) {
 | |
|         if (region.is_executable())
 | |
|             ++count;
 | |
|     });
 | |
|     return count;
 | |
| }
 | |
| 
 | |
| }
 | 
