/* * Copyright (c) 2018-2020, Andreas Kling * * SPDX-License-Identifier: BSD-2-Clause */ #pragma once #include #include #include #include #include #include #include #include #include namespace Kernel { class VMObjectDeletedHandler { public: virtual ~VMObjectDeletedHandler() = default; virtual void vmobject_deleted(VMObject&) = 0; }; class VMObject : public RefCounted , public Weakable { friend class MemoryManager; friend class Region; public: virtual ~VMObject(); virtual RefPtr clone() = 0; virtual bool is_anonymous() const { return false; } virtual bool is_inode() const { return false; } virtual bool is_shared_inode() const { return false; } virtual bool is_private_inode() const { return false; } virtual bool is_contiguous() const { return false; } size_t page_count() const { return m_physical_pages.size(); } Span const> physical_pages() const { return m_physical_pages.span(); } Span> physical_pages() { return m_physical_pages.span(); } size_t size() const { return m_physical_pages.size() * PAGE_SIZE; } virtual StringView class_name() const = 0; ALWAYS_INLINE void ref_region() { m_regions_count++; } ALWAYS_INLINE void unref_region() { m_regions_count--; } ALWAYS_INLINE bool is_shared_by_multiple_regions() const { return m_regions_count > 1; } void register_on_deleted_handler(VMObjectDeletedHandler& handler) { m_on_deleted.set(&handler); } void unregister_on_deleted_handler(VMObjectDeletedHandler& handler) { m_on_deleted.remove(&handler); } protected: explicit VMObject(size_t); explicit VMObject(const VMObject&); template void for_each_region(Callback); IntrusiveListNode m_list_node; FixedArray> m_physical_pages; Lock m_paging_lock { "VMObject" }; mutable SpinLock m_lock; private: VMObject& operator=(const VMObject&) = delete; VMObject& operator=(VMObject&&) = delete; VMObject(VMObject&&) = delete; Atomic m_regions_count { 0 }; HashTable m_on_deleted; SpinLock m_on_deleted_lock; public: using List = IntrusiveList, &VMObject::m_list_node>; }; }