/* * Copyright (c) 2018-2020, Andreas Kling * * SPDX-License-Identifier: BSD-2-Clause */ #pragma once #include #include #include #include #include #include #include namespace Kernel { class Inode; class PhysicalPage; class VMObjectDeletedHandler { public: virtual ~VMObjectDeletedHandler() = default; virtual void vmobject_deleted(VMObject&) = 0; }; class VMObject : public RefCounted , public Weakable , public InlineLinkedListNode { 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(); } const Vector>& physical_pages() const { return m_physical_pages; } Vector>& physical_pages() { return m_physical_pages; } size_t size() const { return m_physical_pages.size() * PAGE_SIZE; } virtual const char* class_name() const = 0; // For InlineLinkedListNode VMObject* m_next { nullptr }; VMObject* m_prev { nullptr }; 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: VMObject(); explicit VMObject(size_t); explicit VMObject(const VMObject&); template void for_each_region(Callback); Vector> 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; }; }