diff --git a/AK/FlyString.cpp b/AK/FlyString.cpp index fdf2eed56af..637ef9c5966 100644 --- a/AK/FlyString.cpp +++ b/AK/FlyString.cpp @@ -27,6 +27,7 @@ #include #include #include +#include #include #include #include @@ -47,12 +48,11 @@ struct FlyStringImplTraits : public AK::Traits { } }; +static AK::Singleton> s_table; + static HashTable& fly_impls() { - static HashTable* table; - if (!table) - table = new HashTable; - return *table; + return *s_table; } void FlyString::did_destroy_impl(Badge, StringImpl& impl) diff --git a/Kernel/Singleton.h b/AK/Singleton.h similarity index 85% rename from Kernel/Singleton.h rename to AK/Singleton.h index 5271aa08eee..0abfa2b2771 100644 --- a/Kernel/Singleton.h +++ b/AK/Singleton.h @@ -26,20 +26,42 @@ #pragma once +#include #include +#include +#ifdef KERNEL #include +#endif -namespace Kernel { +#ifndef __serenity__ +# include +#endif -template +namespace AK { + +template +struct SingletonInstanceCreator { + static T* create() + { + return new T(); + } +}; + +template::create> class Singleton { + AK_MAKE_NONCOPYABLE(Singleton); + AK_MAKE_NONMOVABLE(Singleton); public: + Singleton() = default; + 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; +#ifdef KERNEL + Kernel::ScopedCritical critical; +#endif 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(); @@ -47,7 +69,11 @@ public: } else { // Someone else was faster, wait until they're done while (obj == (T*)0x1) { - Processor::wait_check(); +#ifdef KERNEL + Kernel::Processor::wait_check(); +#else + // TODO: yield +#endif obj = AK::atomic_load(&m_obj, AK::memory_order_consume); } } @@ -93,18 +119,4 @@ private: mutable T* m_obj { nullptr }; // atomic }; -template -struct SingletonInstanceCreator { - static T* create() - { - return new T(); - } -}; - -template -static Singleton::create> make_singleton() -{ - return Singleton::create>(); -} - } diff --git a/Kernel/CommandLine.cpp b/Kernel/CommandLine.cpp index 259fb557f6b..7f40aa18e98 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 8c8261fd735..e511a2d8763 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 #include #include #include @@ -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 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 e58733f49e8..f06ebf2a6ac 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 1e3a4b51684..c9f17322600 100644 --- a/Kernel/Devices/BXVGADevice.cpp +++ b/Kernel/Devices/BXVGADevice.cpp @@ -25,6 +25,7 @@ */ #include +#include #include #include #include @@ -56,7 +57,12 @@ namespace Kernel { #define VBE_DISPI_ENABLED 0x01 #define VBE_DISPI_LFB_ENABLED 0x40 -static BXVGADevice* s_the; +static AK::Singleton 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 cdc2016942d..213fc1617ce 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 e0a49a8631c..934c587ba6e 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 #include #include #include namespace Kernel { -static HashMap* s_all_devices; +static AK::Singleton> s_all_devices; HashMap& Device::all_devices() { - if (s_all_devices == nullptr) - s_all_devices = new HashMap; return *s_all_devices; } diff --git a/Kernel/Devices/KeyboardDevice.cpp b/Kernel/Devices/KeyboardDevice.cpp index ac1d5ac349d..531c488a9f6 100644 --- a/Kernel/Devices/KeyboardDevice.cpp +++ b/Kernel/Devices/KeyboardDevice.cpp @@ -26,6 +26,7 @@ #include #include +#include #include #include #include @@ -335,11 +336,15 @@ void KeyboardDevice::handle_irq(const RegisterState&) } } -static KeyboardDevice* s_the; +static AK::Singleton 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 94dfb8f02e3..74a53a0da69 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 517e1cff18e..5c6a5c59c52 100644 --- a/Kernel/Devices/NullDevice.cpp +++ b/Kernel/Devices/NullDevice.cpp @@ -25,22 +25,26 @@ */ #include "NullDevice.h" +#include #include namespace Kernel { -static NullDevice* s_the; +static AK::Singleton 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 a1cf7ce0b6f..c7968258f72 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 e380acd2e69..172816ea1b3 100644 --- a/Kernel/Devices/PATAChannel.cpp +++ b/Kernel/Devices/PATAChannel.cpp @@ -25,6 +25,7 @@ */ #include +#include #include #include #include @@ -106,13 +107,12 @@ namespace Kernel { #define PCI_Mass_Storage_Class 0x1 #define PCI_IDE_Controller_Subclass 0x1 + +static AK::Singleton s_pata_lock; + static Lock& s_lock() { - static Lock* lock; - if (!lock) - lock = new Lock; - - return *lock; + return *s_pata_lock; }; OwnPtr PATAChannel::create(ChannelType type, bool force_pio) diff --git a/Kernel/Devices/PS2MouseDevice.cpp b/Kernel/Devices/PS2MouseDevice.cpp index 47f876515b7..65fcc332641 100644 --- a/Kernel/Devices/PS2MouseDevice.cpp +++ b/Kernel/Devices/PS2MouseDevice.cpp @@ -25,6 +25,7 @@ */ #include +#include #include #include #include @@ -56,13 +57,12 @@ namespace Kernel { //#define PS2MOUSE_DEBUG -static PS2MouseDevice* s_the; +static AK::Singleton 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 62c5c13aa4f..10f382f43d5 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 b1ad67bd5a4..8d7406f39b6 100644 --- a/Kernel/Devices/SB16.cpp +++ b/Kernel/Devices/SB16.cpp @@ -25,6 +25,7 @@ */ #include +#include #include #include #include @@ -76,13 +77,12 @@ void SB16::set_sample_rate(uint16_t hz) dsp_write((u8)hz); } -static SB16* s_the; +static AK::Singleton 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 2f2ce81b542..e0d5ba7ca30 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 20efb8e8fe1..d1686da6c58 100644 --- a/Kernel/Devices/VMWareBackdoor.cpp +++ b/Kernel/Devices/VMWareBackdoor.cpp @@ -25,6 +25,8 @@ */ #include +#include +#include #include #include #include @@ -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::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 m_backdoor; +}; + +static AK::Singleton 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 13252533904..ffe4b752a69 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 ac060d026ba..7ee4d28aa0e 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 #include #include #include @@ -45,14 +46,10 @@ DevPtsFS::~DevPtsFS() { } -static HashTable* ptys; +static AK::Singleton> s_ptys; bool DevPtsFS::initialize() { - if (ptys == nullptr) { - ptys = new HashTable(); - } - 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 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 DevPtsFSInode::directory_entry_count() const { ASSERT(identifier().index() == 1); - return 2 + ptys->size(); + return 2 + s_ptys->size(); } RefPtr DevPtsFSInode::lookup(StringView name) @@ -170,7 +167,7 @@ RefPtr DevPtsFSInode::lookup(StringView name) auto& fs = static_cast(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 9881b6916b8..3b22a45c6a9 100644 --- a/Kernel/FileSystem/FIFO.cpp +++ b/Kernel/FileSystem/FIFO.cpp @@ -25,6 +25,7 @@ */ #include +#include #include #include #include @@ -37,11 +38,10 @@ namespace Kernel { +static AK::Singleton>> s_table; + static Lockable>& all_fifos() { - static Lockable>* s_table; - if (!s_table) - s_table = new Lockable>; return *s_table; } diff --git a/Kernel/FileSystem/FileSystem.cpp b/Kernel/FileSystem/FileSystem.cpp index e4ed6fd98bd..49f1b284f3e 100644 --- a/Kernel/FileSystem/FileSystem.cpp +++ b/Kernel/FileSystem/FileSystem.cpp @@ -26,6 +26,7 @@ #include #include +#include #include #include #include @@ -37,12 +38,10 @@ namespace Kernel { static u32 s_lastFileSystemID; -static HashMap* s_fs_map; +static AK::Singleton> s_fs_map; static HashMap& all_fses() { - if (!s_fs_map) - s_fs_map = new HashMap(); return *s_fs_map; } diff --git a/Kernel/FileSystem/Inode.cpp b/Kernel/FileSystem/Inode.cpp index 127ad174f6a..e78f87bf598 100644 --- a/Kernel/FileSystem/Inode.cpp +++ b/Kernel/FileSystem/Inode.cpp @@ -25,6 +25,7 @@ */ #include +#include #include #include #include @@ -38,15 +39,13 @@ namespace Kernel { static SpinLock s_all_inodes_lock; +static AK::Singleton> s_list; InlineLinkedList& Inode::all_with_lock() { ASSERT(s_all_inodes_lock.is_locked()); - static InlineLinkedList* list; - if (!list) - list = new InlineLinkedList; - return *list; + return *s_list; } void Inode::sync() diff --git a/Kernel/FileSystem/VirtualFileSystem.cpp b/Kernel/FileSystem/VirtualFileSystem.cpp index 5febd7c5e65..ea06d462c33 100644 --- a/Kernel/FileSystem/VirtualFileSystem.cpp +++ b/Kernel/FileSystem/VirtualFileSystem.cpp @@ -25,6 +25,7 @@ */ #include +#include #include #include #include @@ -40,13 +41,17 @@ namespace Kernel { -static VFS* s_the; +static AK::Singleton 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 35b17e0da8a..19693276987 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 32fc0045de0..23af86d11fd 100644 --- a/Kernel/Interrupts/APIC.cpp +++ b/Kernel/Interrupts/APIC.cpp @@ -26,6 +26,7 @@ #include #include +#include #include #include #include @@ -68,7 +69,7 @@ namespace Kernel { -static APIC* s_apic; +static AK::Singleton 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 6e4fcfcbfa2..09e56114ea2 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 #include #include #include @@ -45,11 +46,10 @@ namespace Kernel { +static AK::Singleton>> s_table; + Lockable>& IPv4Socket::all_sockets() { - static Lockable>* s_table; - if (!s_table) - s_table = new Lockable>; return *s_table; } diff --git a/Kernel/Net/LocalSocket.cpp b/Kernel/Net/LocalSocket.cpp index 92f333ad232..ca7863bd9c9 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 #include #include #include @@ -37,11 +38,10 @@ namespace Kernel { +static AK::Singleton>> s_list; + Lockable>& LocalSocket::all_sockets() { - static Lockable>* s_list; - if (!s_list) - s_list = new Lockable>(); return *s_list; } diff --git a/Kernel/Net/LoopbackAdapter.cpp b/Kernel/Net/LoopbackAdapter.cpp index e42ee66a5eb..5728b68b34e 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 #include namespace Kernel { +static AK::Singleton 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 b87bb5003f9..cebedfe7a38 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 7efa7b353e4..4cfdd1cd43f 100644 --- a/Kernel/Net/NetworkAdapter.cpp +++ b/Kernel/Net/NetworkAdapter.cpp @@ -25,6 +25,7 @@ */ #include +#include #include #include #include @@ -37,12 +38,11 @@ namespace Kernel { +static AK::Singleton>> s_table; + static Lockable>& all_adapters() { - static Lockable>* table; - if (!table) - table = new Lockable>; - return *table; + return *s_table; } void NetworkAdapter::for_each(Function callback) diff --git a/Kernel/Net/Routing.cpp b/Kernel/Net/Routing.cpp index b2b9786a2ea..281f06ceb4c 100644 --- a/Kernel/Net/Routing.cpp +++ b/Kernel/Net/Routing.cpp @@ -25,6 +25,7 @@ */ #include +#include #include #include #include @@ -33,12 +34,11 @@ namespace Kernel { +static AK::Singleton>> s_arp_table; + Lockable>& arp_table() { - static Lockable>* the; - if (!the) - the = new Lockable>; - return *the; + return *s_arp_table; } bool RoutingDecision::is_zero() const diff --git a/Kernel/Net/TCPSocket.cpp b/Kernel/Net/TCPSocket.cpp index cafe48370e9..b7b615c9515 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 #include #include #include @@ -62,20 +63,18 @@ void TCPSocket::set_state(State new_state) } } +static AK::Singleton>>> s_socket_closing; + Lockable>>& TCPSocket::closing_sockets() { - static Lockable>>* s_map; - if (!s_map) - s_map = new Lockable>>; - return *s_map; + return *s_socket_closing; } +static AK::Singleton>> s_socket_tuples; + Lockable>& TCPSocket::sockets_by_tuple() { - static Lockable>* s_map; - if (!s_map) - s_map = new Lockable>; - return *s_map; + return *s_socket_tuples; } RefPtr TCPSocket::from_tuple(const IPv4SocketTuple& tuple) diff --git a/Kernel/Net/UDPSocket.cpp b/Kernel/Net/UDPSocket.cpp index 65091a37c1c..c770a4e1844 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 #include #include #include @@ -41,11 +42,10 @@ void UDPSocket::for_each(Function callback) callback(*it.value); } +static AK::Singleton>> s_map; + Lockable>& UDPSocket::sockets_by_port() { - static Lockable>* s_map; - if (!s_map) - s_map = new Lockable>; return *s_map; } diff --git a/Kernel/Random.cpp b/Kernel/Random.cpp index f024865a740..d8fe3469cda 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 #include #include #include @@ -32,13 +33,10 @@ namespace Kernel { -static KernelRng* s_the; +static AK::Singleton 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 6825319efc0..d26f4ea0d27 100644 --- a/Kernel/Random.h +++ b/Kernel/Random.h @@ -127,6 +127,7 @@ class KernelRng : public Lockable #include #include namespace Kernel { +static AK::Singleton>>> s_map; + Lockable>>& shared_buffers() { - static Lockable>>* map; - if (!map) - map = new Lockable>>; - return *map; + return *s_map; } void SharedBuffer::sanity_check(const char* what) diff --git a/Kernel/TTY/PTYMultiplexer.cpp b/Kernel/TTY/PTYMultiplexer.cpp index ccc0678e43c..e4b7394a9b9 100644 --- a/Kernel/TTY/PTYMultiplexer.cpp +++ b/Kernel/TTY/PTYMultiplexer.cpp @@ -26,6 +26,7 @@ #include "PTYMultiplexer.h" #include "MasterPTY.h" +#include #include #include #include @@ -35,18 +36,16 @@ namespace Kernel { static const unsigned s_max_pty_pairs = 8; -static PTYMultiplexer* s_the; +static AK::Singleton 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 15bb4bdc193..17698009c57 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 d97cf26c466..5fb1b4c52aa 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 #include #include #include @@ -39,12 +40,11 @@ namespace Kernel { -static TimeManagement* s_time_management; +static AK::Singleton 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 TimeManagement::scan_and_initialize_periodic_timers() diff --git a/Kernel/Time/TimeManagement.h b/Kernel/Time/TimeManagement.h index c09159cc6ce..5d16060ff3c 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 scan_and_initialize_periodic_timers(); diff --git a/Kernel/TimerQueue.cpp b/Kernel/TimerQueue.cpp index cac513039fd..b3f40c69c37 100644 --- a/Kernel/TimerQueue.cpp +++ b/Kernel/TimerQueue.cpp @@ -27,18 +27,17 @@ #include #include #include +#include #include #include #include namespace Kernel { -static TimerQueue* s_the; +static AK::Singleton 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 449609da945..eec220462e0 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&&); @@ -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 4a6055d0d65..55c53e01fce 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 838c6e104fe..f126ea95a57 100644 --- a/Kernel/VM/PageDirectory.cpp +++ b/Kernel/VM/PageDirectory.cpp @@ -25,6 +25,7 @@ */ #include +#include #include #include #include @@ -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> s_cr3_map; + static HashMap& cr3_map() { ASSERT_INTERRUPTS_DISABLED(); - static HashMap* map; - if (!map) - map = new HashMap; - return *map; + return *s_cr3_map; } RefPtr PageDirectory::find_by_cr3(u32 cr3) diff --git a/Kernel/init.cpp b/Kernel/init.cpp index 608b8715a17..200d852c8ac 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");