diff options
Diffstat (limited to 'Kernel')
45 files changed, 187 insertions, 258 deletions
diff --git a/Kernel/CommandLine.cpp b/Kernel/CommandLine.cpp index 259fb557f6..7f40aa18e9 100644 --- a/Kernel/CommandLine.cpp +++ b/Kernel/CommandLine.cpp @@ -38,6 +38,7 @@ const CommandLine& kernel_command_line() void CommandLine::initialize(const String& string) { + ASSERT(!s_the); s_the = new CommandLine(string); } diff --git a/Kernel/Console.cpp b/Kernel/Console.cpp index 8c8261fd73..e511a2d876 100644 --- a/Kernel/Console.cpp +++ b/Kernel/Console.cpp @@ -24,6 +24,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +#include <AK/Singleton.h> #include <Kernel/Console.h> #include <Kernel/IO.h> #include <Kernel/kstdio.h> @@ -32,24 +33,27 @@ // Bytes output to 0xE9 end up on the Bochs console. It's very handy. #define CONSOLE_OUT_TO_E9 -static Console* s_the; +static AK::Singleton<Console> s_the; static Kernel::SpinLock g_console_lock; +void Console::initialize() +{ + s_the.ensure_instance(); +} + Console& Console::the() { - ASSERT(s_the); return *s_the; } bool Console::is_initialized() { - return s_the != nullptr; + return s_the.is_initialized(); } Console::Console() : CharacterDevice(5, 1) { - s_the = this; } Console::~Console() diff --git a/Kernel/Console.h b/Kernel/Console.h index e58733f49e..f06ebf2a6a 100644 --- a/Kernel/Console.h +++ b/Kernel/Console.h @@ -34,6 +34,7 @@ class Console final : public Kernel::CharacterDevice { AK_MAKE_ETERNAL public: static Console& the(); + static void initialize(); static bool is_initialized(); Console(); diff --git a/Kernel/Devices/BXVGADevice.cpp b/Kernel/Devices/BXVGADevice.cpp index 1e3a4b5168..c9f1732260 100644 --- a/Kernel/Devices/BXVGADevice.cpp +++ b/Kernel/Devices/BXVGADevice.cpp @@ -25,6 +25,7 @@ */ #include <AK/Checked.h> +#include <AK/Singleton.h> #include <Kernel/Devices/BXVGADevice.h> #include <Kernel/IO.h> #include <Kernel/PCI/Access.h> @@ -56,7 +57,12 @@ namespace Kernel { #define VBE_DISPI_ENABLED 0x01 #define VBE_DISPI_LFB_ENABLED 0x40 -static BXVGADevice* s_the; +static AK::Singleton<BXVGADevice> s_the; + +void BXVGADevice::initialize() +{ + s_the.ensure_instance(); +} BXVGADevice& BXVGADevice::the() { @@ -67,7 +73,6 @@ BXVGADevice::BXVGADevice() : BlockDevice(29, 0) { - s_the = this; m_framebuffer_address = PhysicalAddress(find_framebuffer_address()); set_safe_resolution(); } diff --git a/Kernel/Devices/BXVGADevice.h b/Kernel/Devices/BXVGADevice.h index cdc2016942..213fc1617c 100644 --- a/Kernel/Devices/BXVGADevice.h +++ b/Kernel/Devices/BXVGADevice.h @@ -36,6 +36,7 @@ namespace Kernel { class BXVGADevice final : public BlockDevice { AK_MAKE_ETERNAL public: + static void initialize(); static BXVGADevice& the(); BXVGADevice(); diff --git a/Kernel/Devices/Device.cpp b/Kernel/Devices/Device.cpp index e0a49a8631..934c587ba6 100644 --- a/Kernel/Devices/Device.cpp +++ b/Kernel/Devices/Device.cpp @@ -24,18 +24,17 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +#include <AK/Singleton.h> #include <Kernel/Devices/Device.h> #include <Kernel/FileSystem/InodeMetadata.h> #include <LibC/errno_numbers.h> namespace Kernel { -static HashMap<u32, Device*>* s_all_devices; +static AK::Singleton<HashMap<u32, Device*>> s_all_devices; HashMap<u32, Device*>& Device::all_devices() { - if (s_all_devices == nullptr) - s_all_devices = new HashMap<u32, Device*>; return *s_all_devices; } diff --git a/Kernel/Devices/KeyboardDevice.cpp b/Kernel/Devices/KeyboardDevice.cpp index ac1d5ac349..531c488a9f 100644 --- a/Kernel/Devices/KeyboardDevice.cpp +++ b/Kernel/Devices/KeyboardDevice.cpp @@ -26,6 +26,7 @@ #include <AK/Assertions.h> #include <AK/ByteBuffer.h> +#include <AK/Singleton.h> #include <AK/StringView.h> #include <AK/Types.h> #include <Kernel/Arch/i386/CPU.h> @@ -335,11 +336,15 @@ void KeyboardDevice::handle_irq(const RegisterState&) } } -static KeyboardDevice* s_the; +static AK::Singleton<KeyboardDevice> s_the; + +void KeyboardDevice::initialize() +{ + s_the.ensure_instance(); +} KeyboardDevice& KeyboardDevice::the() { - ASSERT(s_the); return *s_the; } @@ -347,8 +352,6 @@ KeyboardDevice::KeyboardDevice() : IRQHandler(IRQ_KEYBOARD) , CharacterDevice(85, 1) { - s_the = this; - // Empty the buffer of any pending data. // I don't care what you've been pressing until now! while (IO::in8(I8042_STATUS) & I8042_BUFFER_FULL) diff --git a/Kernel/Devices/KeyboardDevice.h b/Kernel/Devices/KeyboardDevice.h index 94dfb8f02e..74a53a0da6 100644 --- a/Kernel/Devices/KeyboardDevice.h +++ b/Kernel/Devices/KeyboardDevice.h @@ -45,6 +45,7 @@ class KeyboardDevice final : public IRQHandler public: using Event = KeyEvent; + static void initialize(); static KeyboardDevice& the(); virtual ~KeyboardDevice() override; diff --git a/Kernel/Devices/NullDevice.cpp b/Kernel/Devices/NullDevice.cpp index 517e1cff18..5c6a5c59c5 100644 --- a/Kernel/Devices/NullDevice.cpp +++ b/Kernel/Devices/NullDevice.cpp @@ -25,22 +25,26 @@ */ #include "NullDevice.h" +#include <AK/Singleton.h> #include <AK/StdLibExtras.h> namespace Kernel { -static NullDevice* s_the; +static AK::Singleton<NullDevice> s_the; + +void NullDevice::initialize() +{ + s_the.ensure_instance(); +} NullDevice& NullDevice::the() { - ASSERT(s_the); return *s_the; } NullDevice::NullDevice() : CharacterDevice(1, 3) { - s_the = this; } NullDevice::~NullDevice() diff --git a/Kernel/Devices/NullDevice.h b/Kernel/Devices/NullDevice.h index a1cf7ce0b6..c7968258f7 100644 --- a/Kernel/Devices/NullDevice.h +++ b/Kernel/Devices/NullDevice.h @@ -36,6 +36,7 @@ public: NullDevice(); virtual ~NullDevice() override; + static void initialize(); static NullDevice& the(); private: diff --git a/Kernel/Devices/PATAChannel.cpp b/Kernel/Devices/PATAChannel.cpp index e380acd2e6..172816ea1b 100644 --- a/Kernel/Devices/PATAChannel.cpp +++ b/Kernel/Devices/PATAChannel.cpp @@ -25,6 +25,7 @@ */ #include <AK/ByteBuffer.h> +#include <AK/Singleton.h> #include <AK/StringView.h> #include <Kernel/Devices/PATAChannel.h> #include <Kernel/Devices/PATADiskDevice.h> @@ -106,13 +107,12 @@ namespace Kernel { #define PCI_Mass_Storage_Class 0x1 #define PCI_IDE_Controller_Subclass 0x1 + +static AK::Singleton<Lock> s_pata_lock; + static Lock& s_lock() { - static Lock* lock; - if (!lock) - lock = new Lock; - - return *lock; + return *s_pata_lock; }; OwnPtr<PATAChannel> PATAChannel::create(ChannelType type, bool force_pio) diff --git a/Kernel/Devices/PS2MouseDevice.cpp b/Kernel/Devices/PS2MouseDevice.cpp index 47f876515b..65fcc33264 100644 --- a/Kernel/Devices/PS2MouseDevice.cpp +++ b/Kernel/Devices/PS2MouseDevice.cpp @@ -25,6 +25,7 @@ */ #include <AK/Memory.h> +#include <AK/Singleton.h> #include <Kernel/Devices/PS2MouseDevice.h> #include <Kernel/Devices/VMWareBackdoor.h> #include <Kernel/IO.h> @@ -56,13 +57,12 @@ namespace Kernel { //#define PS2MOUSE_DEBUG -static PS2MouseDevice* s_the; +static AK::Singleton<PS2MouseDevice> s_the; PS2MouseDevice::PS2MouseDevice() : IRQHandler(IRQ_MOUSE) , CharacterDevice(10, 1) { - s_the = this; initialize(); } @@ -70,6 +70,11 @@ PS2MouseDevice::~PS2MouseDevice() { } +void PS2MouseDevice::create() +{ + s_the.ensure_instance(); +} + PS2MouseDevice& PS2MouseDevice::the() { return *s_the; diff --git a/Kernel/Devices/PS2MouseDevice.h b/Kernel/Devices/PS2MouseDevice.h index 62c5c13aa4..10f382f43d 100644 --- a/Kernel/Devices/PS2MouseDevice.h +++ b/Kernel/Devices/PS2MouseDevice.h @@ -40,6 +40,7 @@ public: PS2MouseDevice(); virtual ~PS2MouseDevice() override; + static void create(); static PS2MouseDevice& the(); // ^CharacterDevice diff --git a/Kernel/Devices/SB16.cpp b/Kernel/Devices/SB16.cpp index b1ad67bd5a..8d7406f39b 100644 --- a/Kernel/Devices/SB16.cpp +++ b/Kernel/Devices/SB16.cpp @@ -25,6 +25,7 @@ */ #include <AK/Memory.h> +#include <AK/Singleton.h> #include <AK/StringView.h> #include <Kernel/Devices/SB16.h> #include <Kernel/Thread.h> @@ -76,13 +77,12 @@ void SB16::set_sample_rate(uint16_t hz) dsp_write((u8)hz); } -static SB16* s_the; +static AK::Singleton<SB16> s_the; SB16::SB16() : IRQHandler(SB16_DEFAULT_IRQ) , CharacterDevice(42, 42) // ### ? { - s_the = this; initialize(); } @@ -90,6 +90,11 @@ SB16::~SB16() { } +void SB16::create() +{ + s_the.ensure_instance(); +} + SB16& SB16::the() { return *s_the; diff --git a/Kernel/Devices/SB16.h b/Kernel/Devices/SB16.h index 2f2ce81b54..e0d5ba7ca3 100644 --- a/Kernel/Devices/SB16.h +++ b/Kernel/Devices/SB16.h @@ -42,6 +42,7 @@ public: SB16(); virtual ~SB16() override; + static void create(); static SB16& the(); // ^CharacterDevice diff --git a/Kernel/Devices/VMWareBackdoor.cpp b/Kernel/Devices/VMWareBackdoor.cpp index 20efb8e8fe..d1686da6c5 100644 --- a/Kernel/Devices/VMWareBackdoor.cpp +++ b/Kernel/Devices/VMWareBackdoor.cpp @@ -25,6 +25,8 @@ */ #include <AK/Assertions.h> +#include <AK/OwnPtr.h> +#include <AK/Singleton.h> #include <AK/String.h> #include <Kernel/Arch/i386/CPU.h> #include <Kernel/CommandLine.h> @@ -80,33 +82,40 @@ inline void vmware_high_bandwidth_get(VMWareCommand& command) : "+a"(command.ax), "+b"(command.bx), "+c"(command.cx), "+d"(command.dx), "+S"(command.si), "+D"(command.di)); } -static VMWareBackdoor* s_vmware_backdoor; - -static bool detect_presence() +class VMWareBackdoorDetector { - VMWareCommand command; - command.bx = ~VMWARE_MAGIC; - command.command = VMWARE_CMD_GETVERSION; - vmware_out(command); - if (command.bx != VMWARE_MAGIC || command.ax == 0xFFFFFFFF) - return false; - return true; -} +public: + VMWareBackdoorDetector() + { + if (detect_presence()) + m_backdoor = make<VMWareBackdoor>(); + } -VMWareBackdoor* VMWareBackdoor::initialize() -{ - ASSERT(s_vmware_backdoor == nullptr); - if (!detect_presence()) - return nullptr; + VMWareBackdoor* get_instance() + { + return m_backdoor.ptr(); + } - s_vmware_backdoor = new VMWareBackdoor; - klog() << "VMWare backdoor opened."; - return s_vmware_backdoor; -} +private: + static bool detect_presence() + { + VMWareCommand command; + command.bx = ~VMWARE_MAGIC; + command.command = VMWARE_CMD_GETVERSION; + vmware_out(command); + if (command.bx != VMWARE_MAGIC || command.ax == 0xFFFFFFFF) + return false; + return true; + } + + OwnPtr<VMWareBackdoor> m_backdoor; +}; + +static AK::Singleton<VMWareBackdoorDetector> s_vmware_backdoor; VMWareBackdoor* VMWareBackdoor::the() { - return s_vmware_backdoor; + return s_vmware_backdoor->get_instance(); } VMWareBackdoor::VMWareBackdoor() diff --git a/Kernel/Devices/VMWareBackdoor.h b/Kernel/Devices/VMWareBackdoor.h index 1325253390..ffe4b752a6 100644 --- a/Kernel/Devices/VMWareBackdoor.h +++ b/Kernel/Devices/VMWareBackdoor.h @@ -63,9 +63,9 @@ class VMWareBackdoor { AK_MAKE_ETERNAL; public: + VMWareBackdoor(); static VMWareBackdoor* the(); - static VMWareBackdoor* initialize(); bool vmmouse_is_absolute() const; void enable_absolute_vmmouse(); void disable_absolute_vmmouse(); @@ -76,7 +76,6 @@ public: private: void send_high_bandwidth(VMWareCommand& command); void get_high_bandwidth(VMWareCommand& command); - VMWareBackdoor(); bool detect_vmmouse(); bool m_vmmouse_absolute { false }; }; diff --git a/Kernel/FileSystem/DevPtsFS.cpp b/Kernel/FileSystem/DevPtsFS.cpp index ac060d026b..7ee4d28aa0 100644 --- a/Kernel/FileSystem/DevPtsFS.cpp +++ b/Kernel/FileSystem/DevPtsFS.cpp @@ -24,6 +24,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +#include <AK/Singleton.h> #include <AK/StringBuilder.h> #include <AK/StringView.h> #include <Kernel/FileSystem/DevPtsFS.h> @@ -45,14 +46,10 @@ DevPtsFS::~DevPtsFS() { } -static HashTable<unsigned>* ptys; +static AK::Singleton<HashTable<unsigned>> s_ptys; bool DevPtsFS::initialize() { - if (ptys == nullptr) { - ptys = new HashTable<unsigned>(); - } - m_root_inode = adopt(*new DevPtsFSInode(*this, 1)); m_root_inode->m_metadata.inode = { fsid(), 1 }; m_root_inode->m_metadata.mode = 0040555; @@ -104,12 +101,12 @@ RefPtr<Inode> DevPtsFS::get_inode(InodeIdentifier inode_id) const void DevPtsFS::register_slave_pty(SlavePTY& slave_pty) { - ptys->set(slave_pty.index()); + s_ptys->set(slave_pty.index()); } void DevPtsFS::unregister_slave_pty(SlavePTY& slave_pty) { - ptys->remove(slave_pty.index()); + s_ptys->remove(slave_pty.index()); } DevPtsFSInode::DevPtsFSInode(DevPtsFS& fs, unsigned index) @@ -144,7 +141,7 @@ KResult DevPtsFSInode::traverse_as_directory(Function<bool(const FS::DirectoryEn callback({ ".", identifier(), 0 }); callback({ "..", identifier(), 0 }); - for (unsigned pty_index : *ptys) { + for (unsigned pty_index : *s_ptys) { String name = String::number(pty_index); InodeIdentifier identifier = { fsid(), pty_index_to_inode_index(pty_index) }; callback({ name, identifier, 0 }); @@ -157,7 +154,7 @@ KResultOr<size_t> DevPtsFSInode::directory_entry_count() const { ASSERT(identifier().index() == 1); - return 2 + ptys->size(); + return 2 + s_ptys->size(); } RefPtr<Inode> DevPtsFSInode::lookup(StringView name) @@ -170,7 +167,7 @@ RefPtr<Inode> DevPtsFSInode::lookup(StringView name) auto& fs = static_cast<DevPtsFS&>(this->fs()); auto pty_index = name.to_uint(); - if (pty_index.has_value() && ptys->contains(pty_index.value())) { + if (pty_index.has_value() && s_ptys->contains(pty_index.value())) { return fs.get_inode({ fsid(), pty_index_to_inode_index(pty_index.value()) }); } diff --git a/Kernel/FileSystem/FIFO.cpp b/Kernel/FileSystem/FIFO.cpp index 9881b6916b..3b22a45c6a 100644 --- a/Kernel/FileSystem/FIFO.cpp +++ b/Kernel/FileSystem/FIFO.cpp @@ -25,6 +25,7 @@ */ #include <AK/HashTable.h> +#include <AK/Singleton.h> #include <AK/StdLibExtras.h> #include <AK/StringView.h> #include <Kernel/FileSystem/FIFO.h> @@ -37,11 +38,10 @@ namespace Kernel { +static AK::Singleton<Lockable<HashTable<FIFO*>>> s_table; + static Lockable<HashTable<FIFO*>>& all_fifos() { - static Lockable<HashTable<FIFO*>>* s_table; - if (!s_table) - s_table = new Lockable<HashTable<FIFO*>>; return *s_table; } diff --git a/Kernel/FileSystem/FileSystem.cpp b/Kernel/FileSystem/FileSystem.cpp index e4ed6fd98b..49f1b284f3 100644 --- a/Kernel/FileSystem/FileSystem.cpp +++ b/Kernel/FileSystem/FileSystem.cpp @@ -26,6 +26,7 @@ #include <AK/Assertions.h> #include <AK/HashMap.h> +#include <AK/Singleton.h> #include <AK/StringBuilder.h> #include <AK/StringView.h> #include <Kernel/FileSystem/FileSystem.h> @@ -37,12 +38,10 @@ namespace Kernel { static u32 s_lastFileSystemID; -static HashMap<u32, FS*>* s_fs_map; +static AK::Singleton<HashMap<u32, FS*>> s_fs_map; static HashMap<u32, FS*>& all_fses() { - if (!s_fs_map) - s_fs_map = new HashMap<u32, FS*>(); return *s_fs_map; } diff --git a/Kernel/FileSystem/Inode.cpp b/Kernel/FileSystem/Inode.cpp index 127ad174f6..e78f87bf59 100644 --- a/Kernel/FileSystem/Inode.cpp +++ b/Kernel/FileSystem/Inode.cpp @@ -25,6 +25,7 @@ */ #include <AK/NonnullRefPtrVector.h> +#include <AK/Singleton.h> #include <AK/StringBuilder.h> #include <AK/StringView.h> #include <Kernel/FileSystem/Custody.h> @@ -38,15 +39,13 @@ namespace Kernel { static SpinLock s_all_inodes_lock; +static AK::Singleton<InlineLinkedList<Inode>> s_list; InlineLinkedList<Inode>& Inode::all_with_lock() { ASSERT(s_all_inodes_lock.is_locked()); - static InlineLinkedList<Inode>* list; - if (!list) - list = new InlineLinkedList<Inode>; - return *list; + return *s_list; } void Inode::sync() diff --git a/Kernel/FileSystem/VirtualFileSystem.cpp b/Kernel/FileSystem/VirtualFileSystem.cpp index 5febd7c5e6..ea06d462c3 100644 --- a/Kernel/FileSystem/VirtualFileSystem.cpp +++ b/Kernel/FileSystem/VirtualFileSystem.cpp @@ -25,6 +25,7 @@ */ #include <AK/LexicalPath.h> +#include <AK/Singleton.h> #include <AK/StringBuilder.h> #include <Kernel/Devices/BlockDevice.h> #include <Kernel/FileSystem/Custody.h> @@ -40,13 +41,17 @@ namespace Kernel { -static VFS* s_the; +static AK::Singleton<VFS> s_the; static constexpr int symlink_recursion_limit { 5 }; // FIXME: increase? static constexpr int root_mount_flags = MS_NODEV | MS_NOSUID | MS_RDONLY; +void VFS::initialize() +{ + s_the.ensure_instance(); +} + VFS& VFS::the() { - ASSERT(s_the); return *s_the; } @@ -55,7 +60,6 @@ VFS::VFS() #ifdef VFS_DEBUG klog() << "VFS: Constructing VFS"; #endif - s_the = this; } VFS::~VFS() diff --git a/Kernel/FileSystem/VirtualFileSystem.h b/Kernel/FileSystem/VirtualFileSystem.h index 35b17e0da8..1969327698 100644 --- a/Kernel/FileSystem/VirtualFileSystem.h +++ b/Kernel/FileSystem/VirtualFileSystem.h @@ -78,6 +78,7 @@ public: int m_flags; }; + static void initialize(); static VFS& the(); VFS(); diff --git a/Kernel/Interrupts/APIC.cpp b/Kernel/Interrupts/APIC.cpp index 32fc0045de..23af86d11f 100644 --- a/Kernel/Interrupts/APIC.cpp +++ b/Kernel/Interrupts/APIC.cpp @@ -26,6 +26,7 @@ #include <AK/Assertions.h> #include <AK/Memory.h> +#include <AK/Singleton.h> #include <AK/StringView.h> #include <AK/Types.h> #include <Kernel/ACPI/Parser.h> @@ -68,7 +69,7 @@ namespace Kernel { -static APIC* s_apic; +static AK::Singleton<APIC> s_apic; class APICIPIInterruptHandler final : public GenericInterruptHandler { public: @@ -132,7 +133,7 @@ private: bool APIC::initialized() { - return (s_apic != nullptr); + return s_apic.is_initialized(); } APIC& APIC::the() @@ -144,7 +145,7 @@ APIC& APIC::the() void APIC::initialize() { ASSERT(!APIC::initialized()); - s_apic = new APIC(); + s_apic.ensure_instance(); } PhysicalAddress APIC::get_base() diff --git a/Kernel/Net/IPv4Socket.cpp b/Kernel/Net/IPv4Socket.cpp index 6e4fcfcbfa..09e56114ea 100644 --- a/Kernel/Net/IPv4Socket.cpp +++ b/Kernel/Net/IPv4Socket.cpp @@ -24,6 +24,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +#include <AK/Singleton.h> #include <AK/StringBuilder.h> #include <Kernel/FileSystem/FileDescription.h> #include <Kernel/Net/ARP.h> @@ -45,11 +46,10 @@ namespace Kernel { +static AK::Singleton<Lockable<HashTable<IPv4Socket*>>> s_table; + Lockable<HashTable<IPv4Socket*>>& IPv4Socket::all_sockets() { - static Lockable<HashTable<IPv4Socket*>>* s_table; - if (!s_table) - s_table = new Lockable<HashTable<IPv4Socket*>>; return *s_table; } diff --git a/Kernel/Net/LocalSocket.cpp b/Kernel/Net/LocalSocket.cpp index 92f333ad23..ca7863bd9c 100644 --- a/Kernel/Net/LocalSocket.cpp +++ b/Kernel/Net/LocalSocket.cpp @@ -24,6 +24,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +#include <AK/Singleton.h> #include <AK/StringBuilder.h> #include <Kernel/FileSystem/FileDescription.h> #include <Kernel/FileSystem/VirtualFileSystem.h> @@ -37,11 +38,10 @@ namespace Kernel { +static AK::Singleton<Lockable<InlineLinkedList<LocalSocket>>> s_list; + Lockable<InlineLinkedList<LocalSocket>>& LocalSocket::all_sockets() { - static Lockable<InlineLinkedList<LocalSocket>>* s_list; - if (!s_list) - s_list = new Lockable<InlineLinkedList<LocalSocket>>(); return *s_list; } diff --git a/Kernel/Net/LoopbackAdapter.cpp b/Kernel/Net/LoopbackAdapter.cpp index e42ee66a5e..5728b68b34 100644 --- a/Kernel/Net/LoopbackAdapter.cpp +++ b/Kernel/Net/LoopbackAdapter.cpp @@ -24,16 +24,16 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +#include <AK/Singleton.h> #include <Kernel/Net/LoopbackAdapter.h> namespace Kernel { +static AK::Singleton<LoopbackAdapter> s_loopback; + LoopbackAdapter& LoopbackAdapter::the() { - static LoopbackAdapter* the; - if (!the) - the = new LoopbackAdapter; - return *the; + return *s_loopback; } LoopbackAdapter::LoopbackAdapter() diff --git a/Kernel/Net/LoopbackAdapter.h b/Kernel/Net/LoopbackAdapter.h index b87bb5003f..cebedfe7a3 100644 --- a/Kernel/Net/LoopbackAdapter.h +++ b/Kernel/Net/LoopbackAdapter.h @@ -33,15 +33,13 @@ namespace Kernel { class LoopbackAdapter final : public NetworkAdapter { AK_MAKE_ETERNAL public: + LoopbackAdapter(); static LoopbackAdapter& the(); virtual ~LoopbackAdapter() override; virtual void send_raw(ReadonlyBytes) override; virtual const char* class_name() const override { return "LoopbackAdapter"; } - -private: - LoopbackAdapter(); }; } diff --git a/Kernel/Net/NetworkAdapter.cpp b/Kernel/Net/NetworkAdapter.cpp index 7efa7b353e..4cfdd1cd43 100644 --- a/Kernel/Net/NetworkAdapter.cpp +++ b/Kernel/Net/NetworkAdapter.cpp @@ -25,6 +25,7 @@ */ #include <AK/HashTable.h> +#include <AK/Singleton.h> #include <AK/StringBuilder.h> #include <Kernel/Heap/kmalloc.h> #include <Kernel/Lock.h> @@ -37,12 +38,11 @@ namespace Kernel { +static AK::Singleton<Lockable<HashTable<NetworkAdapter*>>> s_table; + static Lockable<HashTable<NetworkAdapter*>>& all_adapters() { - static Lockable<HashTable<NetworkAdapter*>>* table; - if (!table) - table = new Lockable<HashTable<NetworkAdapter*>>; - return *table; + return *s_table; } void NetworkAdapter::for_each(Function<void(NetworkAdapter&)> callback) diff --git a/Kernel/Net/Routing.cpp b/Kernel/Net/Routing.cpp index b2b9786a2e..281f06ceb4 100644 --- a/Kernel/Net/Routing.cpp +++ b/Kernel/Net/Routing.cpp @@ -25,6 +25,7 @@ */ #include <AK/HashMap.h> +#include <AK/Singleton.h> #include <Kernel/Net/LoopbackAdapter.h> #include <Kernel/Net/Routing.h> #include <Kernel/Thread.h> @@ -33,12 +34,11 @@ namespace Kernel { +static AK::Singleton<Lockable<HashMap<IPv4Address, MACAddress>>> s_arp_table; + Lockable<HashMap<IPv4Address, MACAddress>>& arp_table() { - static Lockable<HashMap<IPv4Address, MACAddress>>* the; - if (!the) - the = new Lockable<HashMap<IPv4Address, MACAddress>>; - return *the; + return *s_arp_table; } bool RoutingDecision::is_zero() const diff --git a/Kernel/Net/TCPSocket.cpp b/Kernel/Net/TCPSocket.cpp index cafe48370e..b7b615c951 100644 --- a/Kernel/Net/TCPSocket.cpp +++ b/Kernel/Net/TCPSocket.cpp @@ -24,6 +24,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +#include <AK/Singleton.h> #include <AK/Time.h> #include <Kernel/Devices/RandomDevice.h> #include <Kernel/FileSystem/FileDescription.h> @@ -62,20 +63,18 @@ void TCPSocket::set_state(State new_state) } } +static AK::Singleton<Lockable<HashMap<IPv4SocketTuple, RefPtr<TCPSocket>>>> s_socket_closing; + Lockable<HashMap<IPv4SocketTuple, RefPtr<TCPSocket>>>& TCPSocket::closing_sockets() { - static Lockable<HashMap<IPv4SocketTuple, RefPtr<TCPSocket>>>* s_map; - if (!s_map) - s_map = new Lockable<HashMap<IPv4SocketTuple, RefPtr<TCPSocket>>>; - return *s_map; + return *s_socket_closing; } +static AK::Singleton<Lockable<HashMap<IPv4SocketTuple, TCPSocket*>>> s_socket_tuples; + Lockable<HashMap<IPv4SocketTuple, TCPSocket*>>& TCPSocket::sockets_by_tuple() { - static Lockable<HashMap<IPv4SocketTuple, TCPSocket*>>* s_map; - if (!s_map) - s_map = new Lockable<HashMap<IPv4SocketTuple, TCPSocket*>>; - return *s_map; + return *s_socket_tuples; } RefPtr<TCPSocket> TCPSocket::from_tuple(const IPv4SocketTuple& tuple) diff --git a/Kernel/Net/UDPSocket.cpp b/Kernel/Net/UDPSocket.cpp index 65091a37c1..c770a4e184 100644 --- a/Kernel/Net/UDPSocket.cpp +++ b/Kernel/Net/UDPSocket.cpp @@ -24,6 +24,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +#include <AK/Singleton.h> #include <Kernel/Devices/RandomDevice.h> #include <Kernel/Net/NetworkAdapter.h> #include <Kernel/Net/Routing.h> @@ -41,11 +42,10 @@ void UDPSocket::for_each(Function<void(const UDPSocket&)> callback) callback(*it.value); } +static AK::Singleton<Lockable<HashMap<u16, UDPSocket*>>> s_map; + Lockable<HashMap<u16, UDPSocket*>>& UDPSocket::sockets_by_port() { - static Lockable<HashMap<u16, UDPSocket*>>* s_map; - if (!s_map) - s_map = new Lockable<HashMap<u16, UDPSocket*>>; return *s_map; } diff --git a/Kernel/Random.cpp b/Kernel/Random.cpp index f024865a74..d8fe3469cd 100644 --- a/Kernel/Random.cpp +++ b/Kernel/Random.cpp @@ -25,6 +25,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +#include <AK/Singleton.h> #include <Kernel/Arch/i386/CPU.h> #include <Kernel/Devices/RandomDevice.h> #include <Kernel/Random.h> @@ -32,13 +33,10 @@ namespace Kernel { -static KernelRng* s_the; +static AK::Singleton<KernelRng> s_the; KernelRng& KernelRng::the() { - if (!s_the) { - s_the = new KernelRng; - } return *s_the; } diff --git a/Kernel/Random.h b/Kernel/Random.h index 6825319efc..d26f4ea0d2 100644 --- a/Kernel/Random.h +++ b/Kernel/Random.h @@ -127,6 +127,7 @@ class KernelRng : public Lockable<FortunaPRNG<Crypto::Cipher::AESCipher, Crypto: AK_MAKE_ETERNAL; public: + KernelRng(); static KernelRng& the(); void wait_for_entropy(); @@ -134,8 +135,6 @@ public: void wake_if_ready(); private: - KernelRng(); - WaitQueue m_seed_queue; }; diff --git a/Kernel/SharedBuffer.cpp b/Kernel/SharedBuffer.cpp index 1989c892db..3a9fd4e42d 100644 --- a/Kernel/SharedBuffer.cpp +++ b/Kernel/SharedBuffer.cpp @@ -24,17 +24,17 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +#include <AK/Singleton.h> #include <Kernel/Process.h> #include <Kernel/SharedBuffer.h> namespace Kernel { +static AK::Singleton<Lockable<HashMap<int, NonnullOwnPtr<SharedBuffer>>>> s_map; + Lockable<HashMap<int, NonnullOwnPtr<SharedBuffer>>>& shared_buffers() { - static Lockable<HashMap<int, NonnullOwnPtr<SharedBuffer>>>* map; - if (!map) - map = new Lockable<HashMap<int, NonnullOwnPtr<SharedBuffer>>>; - return *map; + return *s_map; } void SharedBuffer::sanity_check(const char* what) diff --git a/Kernel/Singleton.h b/Kernel/Singleton.h deleted file mode 100644 index 5271aa08ee..0000000000 --- a/Kernel/Singleton.h +++ /dev/null @@ -1,110 +0,0 @@ -/* - * Copyright (c) 2020, the SerenityOS developers. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#pragma once - -#include <AK/Atomic.h> -#include <Kernel/Arch/i386/CPU.h> - -namespace Kernel { - -template<typename T, T* (*InitFunction)()> -class Singleton { -public: - T* ptr() const - { - T* obj = AK::atomic_load(&m_obj, AK::memory_order_consume); - if (FlatPtr(obj) <= 0x1) { - // If this is the first time, see if we get to initialize it - ScopedCritical critical; - if (obj == nullptr && AK::atomic_compare_exchange_strong(&m_obj, obj, (T*)0x1, AK::memory_order_acq_rel)) { - // We're the first one - obj = InitFunction(); - AK::atomic_store(&m_obj, obj, AK::memory_order_release); - } else { - // Someone else was faster, wait until they're done - while (obj == (T*)0x1) { - Processor::wait_check(); - obj = AK::atomic_load(&m_obj, AK::memory_order_consume); - } - } - // We should always return an instance - ASSERT(obj != nullptr); - ASSERT(obj != (T*)0x1); - } - return obj; - } - - T* operator->() const - { - return ptr(); - } - - T& operator*() const - { - return *ptr(); - } - - operator T*() const - { - return ptr(); - } - - operator T&() const - { - return *ptr(); - } - - bool is_initialized() const - { - T* obj = AK::atomic_load(&m_obj, AK::memory_order_consume); - return FlatPtr(obj) > 0x1; - } - - void ensure_instance() - { - (void)ptr(); - } - -private: - mutable T* m_obj { nullptr }; // atomic -}; - -template<typename T> -struct SingletonInstanceCreator { - static T* create() - { - return new T(); - } -}; - -template<typename T> -static Singleton<T, SingletonInstanceCreator<T>::create> make_singleton() -{ - return Singleton<T, SingletonInstanceCreator<T>::create>(); -} - -} diff --git a/Kernel/TTY/PTYMultiplexer.cpp b/Kernel/TTY/PTYMultiplexer.cpp index ccc0678e43..e4b7394a9b 100644 --- a/Kernel/TTY/PTYMultiplexer.cpp +++ b/Kernel/TTY/PTYMultiplexer.cpp @@ -26,6 +26,7 @@ #include "PTYMultiplexer.h" #include "MasterPTY.h" +#include <AK/Singleton.h> #include <Kernel/FileSystem/FileDescription.h> #include <Kernel/Process.h> #include <LibC/errno_numbers.h> @@ -35,18 +36,16 @@ namespace Kernel { static const unsigned s_max_pty_pairs = 8; -static PTYMultiplexer* s_the; +static AK::Singleton<PTYMultiplexer> s_the; PTYMultiplexer& PTYMultiplexer::the() { - ASSERT(s_the); return *s_the; } PTYMultiplexer::PTYMultiplexer() : CharacterDevice(5, 2) { - s_the = this; m_freelist.ensure_capacity(s_max_pty_pairs); for (int i = s_max_pty_pairs; i > 0; --i) m_freelist.unchecked_append(i - 1); diff --git a/Kernel/TTY/PTYMultiplexer.h b/Kernel/TTY/PTYMultiplexer.h index 15bb4bdc19..17698009c5 100644 --- a/Kernel/TTY/PTYMultiplexer.h +++ b/Kernel/TTY/PTYMultiplexer.h @@ -40,6 +40,10 @@ public: PTYMultiplexer(); virtual ~PTYMultiplexer() override; + static void initialize() + { + the(); + } static PTYMultiplexer& the(); // ^CharacterDevice diff --git a/Kernel/Time/TimeManagement.cpp b/Kernel/Time/TimeManagement.cpp index d97cf26c46..5fb1b4c52a 100644 --- a/Kernel/Time/TimeManagement.cpp +++ b/Kernel/Time/TimeManagement.cpp @@ -24,6 +24,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +#include <AK/Singleton.h> #include <Kernel/ACPI/Parser.h> #include <Kernel/CommandLine.h> #include <Kernel/Scheduler.h> @@ -39,12 +40,11 @@ namespace Kernel { -static TimeManagement* s_time_management; +static AK::Singleton<TimeManagement> s_the; TimeManagement& TimeManagement::the() { - ASSERT(s_time_management); - return *s_time_management; + return *s_the; } bool TimeManagement::is_system_timer(const HardwareTimer& timer) const @@ -65,11 +65,9 @@ time_t TimeManagement::epoch_time() const void TimeManagement::initialize() { - ASSERT(!s_time_management); - if (kernel_command_line().lookup("time").value_or("modern") == "legacy") - s_time_management = new TimeManagement(false); - else - s_time_management = new TimeManagement(true); + ASSERT(!s_the.is_initialized()); + s_the.ensure_instance(); + } time_t TimeManagement::seconds_since_boot() const { @@ -90,8 +88,9 @@ time_t TimeManagement::boot_time() const return RTC::boot_time(); } -TimeManagement::TimeManagement(bool probe_non_legacy_hardware_timers) +TimeManagement::TimeManagement() { + bool probe_non_legacy_hardware_timers = !(kernel_command_line().lookup("time").value_or("modern") == "legacy"); if (ACPI::is_enabled()) { if (!ACPI::Parser::the()->x86_specific_flags().cmos_rtc_not_present) { RTC::initialize(); @@ -117,7 +116,8 @@ TimeManagement::TimeManagement(bool probe_non_legacy_hardware_timers) timeval TimeManagement::now_as_timeval() { - return { s_time_management->epoch_time(), (suseconds_t)s_time_management->ticks_this_second() * (suseconds_t)1000 }; + auto* time_management = s_the.ptr(); + return { time_management->epoch_time(), (suseconds_t)time_management->ticks_this_second() * (suseconds_t)1000 }; } Vector<HardwareTimer*> TimeManagement::scan_and_initialize_periodic_timers() diff --git a/Kernel/Time/TimeManagement.h b/Kernel/Time/TimeManagement.h index c09159cc6c..5d16060ff3 100644 --- a/Kernel/Time/TimeManagement.h +++ b/Kernel/Time/TimeManagement.h @@ -42,6 +42,7 @@ class TimeManagement { AK_MAKE_ETERNAL; public: + TimeManagement(); static bool initialized(); static void initialize(); static TimeManagement& the(); @@ -63,7 +64,6 @@ public: static timeval now_as_timeval(); private: - explicit TimeManagement(bool probe_non_legacy_hardware_timers); bool probe_and_set_legacy_hardware_timers(); bool probe_and_set_non_legacy_hardware_timers(); Vector<HardwareTimer*> scan_and_initialize_periodic_timers(); diff --git a/Kernel/TimerQueue.cpp b/Kernel/TimerQueue.cpp index cac513039f..b3f40c69c3 100644 --- a/Kernel/TimerQueue.cpp +++ b/Kernel/TimerQueue.cpp @@ -27,18 +27,17 @@ #include <AK/Function.h> #include <AK/NonnullOwnPtr.h> #include <AK/OwnPtr.h> +#include <AK/Singleton.h> #include <Kernel/Scheduler.h> #include <Kernel/Time/TimeManagement.h> #include <Kernel/TimerQueue.h> namespace Kernel { -static TimerQueue* s_the; +static AK::Singleton<TimerQueue> s_the; TimerQueue& TimerQueue::the() { - if (!s_the) - s_the = new TimerQueue; return *s_the; } diff --git a/Kernel/TimerQueue.h b/Kernel/TimerQueue.h index 449609da94..eec220462e 100644 --- a/Kernel/TimerQueue.h +++ b/Kernel/TimerQueue.h @@ -56,6 +56,7 @@ struct Timer { class TimerQueue { public: + TimerQueue(); static TimerQueue& the(); TimerId add_timer(NonnullOwnPtr<Timer>&&); @@ -64,8 +65,6 @@ public: void fire(); private: - TimerQueue(); - void update_next_timer_due(); u64 microseconds_to_ticks(u64 micro_seconds) { return micro_seconds * (m_ticks_per_second / 1'000'000); } diff --git a/Kernel/VM/MemoryManager.cpp b/Kernel/VM/MemoryManager.cpp index 4a6055d0d6..55c53e01fc 100644 --- a/Kernel/VM/MemoryManager.cpp +++ b/Kernel/VM/MemoryManager.cpp @@ -53,6 +53,10 @@ extern FlatPtr end_of_kernel_bss; namespace Kernel { +// NOTE: We can NOT use AK::Singleton for this class, because +// MemoryManager::initialize is called *before* global constructors are +// run. If we do, then AK::Singleton would get re-initialized, causing +// the memory manager to be initialized twice! static MemoryManager* s_the; RecursiveSpinLock s_mm_lock; diff --git a/Kernel/VM/PageDirectory.cpp b/Kernel/VM/PageDirectory.cpp index 838c6e104f..f126ea95a5 100644 --- a/Kernel/VM/PageDirectory.cpp +++ b/Kernel/VM/PageDirectory.cpp @@ -25,6 +25,7 @@ */ #include <AK/Memory.h> +#include <AK/Singleton.h> #include <Kernel/Process.h> #include <Kernel/Random.h> #include <Kernel/Thread.h> @@ -37,13 +38,12 @@ static const FlatPtr userspace_range_base = 0x00800000; static const FlatPtr userspace_range_ceiling = 0xbe000000; static const FlatPtr kernelspace_range_base = 0xc0800000; +static AK::Singleton<HashMap<u32, PageDirectory*>> s_cr3_map; + static HashMap<u32, PageDirectory*>& cr3_map() { ASSERT_INTERRUPTS_DISABLED(); - static HashMap<u32, PageDirectory*>* map; - if (!map) - map = new HashMap<u32, PageDirectory*>; - return *map; + return *s_cr3_map; } RefPtr<PageDirectory> PageDirectory::find_by_cr3(u32 cr3) diff --git a/Kernel/init.cpp b/Kernel/init.cpp index 608b8715a1..200d852c8a 100644 --- a/Kernel/init.cpp +++ b/Kernel/init.cpp @@ -135,10 +135,10 @@ extern "C" [[noreturn]] void init() InterruptManagement::initialize(); ACPI::initialize(); - new VFS; - new KeyboardDevice; - new PS2MouseDevice; - new Console; + VFS::initialize(); + KeyboardDevice::initialize(); + PS2MouseDevice::create(); + Console::initialize(); klog() << "Starting SerenityOS..."; @@ -146,7 +146,7 @@ extern "C" [[noreturn]] void init() TimeManagement::initialize(); - new NullDevice; + NullDevice::initialize(); if (!get_serial_debug()) new SerialDevice(SERIAL_COM1_ADDR, 64); new SerialDevice(SERIAL_COM2_ADDR, 65); @@ -228,7 +228,7 @@ void init_stage2() }); if (bxvga_found) { - new BXVGADevice; + BXVGADevice::initialize(); } else { if (multiboot_info_ptr->framebuffer_type == MULTIBOOT_FRAMEBUFFER_TYPE_RGB || multiboot_info_ptr->framebuffer_type == MULTIBOOT_FRAMEBUFFER_TYPE_EGA_TEXT) { new MBVGADevice( @@ -237,7 +237,7 @@ void init_stage2() multiboot_info_ptr->framebuffer_width, multiboot_info_ptr->framebuffer_height); } else { - new BXVGADevice; + BXVGADevice::initialize(); } } } @@ -252,9 +252,8 @@ void init_stage2() new ZeroDevice; new FullDevice; new RandomDevice; - new PTYMultiplexer; + PTYMultiplexer::initialize(); new SB16; - VMWareBackdoor::initialize(); bool force_pio = kernel_command_line().contains("force_pio"); |