Kernel: Remove the big inode lock
This moves locking to the inodes themselves which allows reducing lock times significantly. Main inodes (ext2 and tmpfs) still do contain a single big mutex that gets locked during operations but now we have the architecture to optimize these.
This commit is contained in:
@@ -2,6 +2,7 @@
|
||||
|
||||
#include <BAN/HashMap.h>
|
||||
#include <kernel/FS/Inode.h>
|
||||
#include <kernel/Lock/Mutex.h>
|
||||
|
||||
#include <sys/epoll.h>
|
||||
|
||||
@@ -90,6 +91,7 @@ namespace Kernel
|
||||
};
|
||||
|
||||
private:
|
||||
Mutex m_mutex;
|
||||
ThreadBlocker m_thread_blocker;
|
||||
SpinLock m_ready_lock;
|
||||
BAN::HashMap<BAN::RefPtr<Inode>, uint32_t> m_ready_events;
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <kernel/FS/Inode.h>
|
||||
#include <kernel/Lock/Mutex.h>
|
||||
|
||||
namespace Kernel
|
||||
{
|
||||
@@ -44,8 +45,9 @@ namespace Kernel
|
||||
|
||||
private:
|
||||
const bool m_is_semaphore;
|
||||
uint64_t m_value;
|
||||
BAN::Atomic<uint64_t> m_value;
|
||||
|
||||
Mutex m_mutex;
|
||||
ThreadBlocker m_thread_blocker;
|
||||
};
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#include <BAN/StringView.h>
|
||||
#include <kernel/FS/Ext2/Definitions.h>
|
||||
#include <kernel/FS/Inode.h>
|
||||
#include <kernel/Lock/Mutex.h>
|
||||
|
||||
namespace Kernel
|
||||
{
|
||||
@@ -110,6 +111,9 @@ namespace Kernel
|
||||
Ext2::Inode m_inode;
|
||||
const uint32_t m_ino;
|
||||
|
||||
// TODO: try to reduce locking or replace this with rwlock(?)
|
||||
Mutex m_lock;
|
||||
|
||||
friend class Ext2FS;
|
||||
friend class BAN::RefPtr<Ext2Inode>;
|
||||
};
|
||||
|
||||
@@ -10,7 +10,6 @@
|
||||
|
||||
#include <kernel/Credentials.h>
|
||||
#include <kernel/Debug.h>
|
||||
#include <kernel/Lock/Mutex.h>
|
||||
|
||||
#include <dirent.h>
|
||||
#include <sys/socket.h>
|
||||
@@ -183,11 +182,10 @@ namespace Kernel
|
||||
|
||||
virtual BAN::ErrorOr<long> ioctl_impl(int, void*) { return BAN::Error::from_errno(ENOTSUP); }
|
||||
|
||||
protected:
|
||||
mutable PriorityMutex m_mutex;
|
||||
|
||||
private:
|
||||
SpinLock m_shared_region_lock;
|
||||
BAN::WeakPtr<SharedFileData> m_shared_region;
|
||||
|
||||
SpinLock m_epoll_lock;
|
||||
BAN::LinkedList<class Epoll*> m_epolls;
|
||||
friend class Epoll;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <BAN/Array.h>
|
||||
#include <kernel/FS/Inode.h>
|
||||
#include <kernel/Lock/Mutex.h>
|
||||
#include <kernel/Memory/ByteRingBuffer.h>
|
||||
#include <kernel/ThreadBlocker.h>
|
||||
|
||||
@@ -53,6 +53,8 @@ namespace Kernel
|
||||
timespec m_atime {};
|
||||
timespec m_mtime {};
|
||||
timespec m_ctime {};
|
||||
|
||||
Mutex m_mutex;
|
||||
ThreadBlocker m_thread_blocker;
|
||||
|
||||
BAN::UniqPtr<ByteRingBuffer> m_buffer;
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#include <BAN/Optional.h>
|
||||
#include <kernel/FS/Inode.h>
|
||||
#include <kernel/FS/TmpFS/Definitions.h>
|
||||
#include <kernel/Lock/Mutex.h>
|
||||
|
||||
namespace Kernel
|
||||
{
|
||||
@@ -53,22 +54,25 @@ namespace Kernel
|
||||
virtual BAN::ErrorOr<void> fsync_impl() override { return {}; }
|
||||
|
||||
void sync();
|
||||
virtual BAN::ErrorOr<void> prepare_unlink() { return {}; };
|
||||
virtual BAN::ErrorOr<void> prepare_unlink_no_lock() { return {}; };
|
||||
|
||||
void free_all_blocks();
|
||||
void free_indirect_blocks(size_t block, uint32_t depth);
|
||||
void free_indirect_blocks_no_lock(size_t block, uint32_t depth);
|
||||
|
||||
BAN::Optional<size_t> block_index(size_t data_block_index);
|
||||
BAN::Optional<size_t> block_index_from_indirect(size_t block, size_t index, uint32_t depth);
|
||||
BAN::Optional<size_t> block_index_from_indirect_no_lock(size_t block, size_t index, uint32_t depth);
|
||||
|
||||
BAN::ErrorOr<size_t> block_index_with_allocation(size_t data_block_index);
|
||||
BAN::ErrorOr<size_t> block_index_from_indirect_with_allocation(size_t& block, size_t index, uint32_t depth);
|
||||
BAN::ErrorOr<size_t> block_index_from_indirect_with_allocation_no_lock(size_t& block, size_t index, uint32_t depth);
|
||||
|
||||
protected:
|
||||
TmpFileSystem& m_fs;
|
||||
TmpInodeInfo m_inode_info;
|
||||
const ino_t m_ino;
|
||||
|
||||
// TODO: try to reduce locking or replace this with rwlock(?)
|
||||
Mutex m_lock;
|
||||
|
||||
// has to be able to increase link count
|
||||
friend class TmpDirectoryInode;
|
||||
};
|
||||
@@ -149,7 +153,7 @@ namespace Kernel
|
||||
protected:
|
||||
TmpDirectoryInode(TmpFileSystem&, ino_t, const TmpInodeInfo&);
|
||||
|
||||
virtual BAN::ErrorOr<void> prepare_unlink() override;
|
||||
virtual BAN::ErrorOr<void> prepare_unlink_no_lock() override;
|
||||
|
||||
protected:
|
||||
virtual BAN::ErrorOr<BAN::RefPtr<Inode>> find_inode_impl(BAN::StringView) override final;
|
||||
|
||||
@@ -46,7 +46,7 @@ namespace Kernel
|
||||
uint32_t lock_depth() const override { return m_lock_depth; }
|
||||
|
||||
private:
|
||||
SpinLock& m_lock;
|
||||
Lock& m_lock;
|
||||
uint32_t m_lock_depth { 0 };
|
||||
InterruptState m_state;
|
||||
const pid_t m_locker;
|
||||
|
||||
@@ -181,6 +181,7 @@ namespace Kernel
|
||||
|
||||
uint64_t m_time_wait_start_ms { 0 };
|
||||
|
||||
mutable Mutex m_mutex;
|
||||
ThreadBlocker m_thread_blocker;
|
||||
|
||||
RecvWindowInfo m_recv_window;
|
||||
|
||||
@@ -66,9 +66,12 @@ namespace Kernel
|
||||
SpinLock m_packet_lock;
|
||||
ThreadBlocker m_packet_thread_blocker;
|
||||
|
||||
SpinLock m_peer_address_lock;
|
||||
sockaddr_storage m_peer_address {};
|
||||
socklen_t m_peer_address_len { 0 };
|
||||
|
||||
Mutex m_bind_lock;
|
||||
|
||||
friend class BAN::RefPtr<UDPSocket>;
|
||||
};
|
||||
|
||||
|
||||
@@ -43,15 +43,16 @@ namespace Kernel
|
||||
UnixDomainSocket(Socket::Type, const Socket::Info&);
|
||||
~UnixDomainSocket();
|
||||
|
||||
bool is_bound() const { return !m_bound_file.canonical_path.empty(); }
|
||||
bool is_bound_to_unused() const { return !m_bound_file.inode; }
|
||||
bool is_bound() const;
|
||||
bool is_bound_to_unused() const;
|
||||
BAN::ErrorOr<void> bind_to_unused_if_not_bound();
|
||||
|
||||
bool is_streaming() const;
|
||||
|
||||
private:
|
||||
struct ConnectionInfo
|
||||
{
|
||||
bool listening { false };
|
||||
BAN::Atomic<bool> listening { false };
|
||||
BAN::Atomic<bool> connection_done { false };
|
||||
mutable BAN::Atomic<bool> target_closed { false };
|
||||
BAN::WeakPtr<UnixDomainSocket> connection;
|
||||
@@ -62,6 +63,7 @@ namespace Kernel
|
||||
|
||||
struct ConnectionlessInfo
|
||||
{
|
||||
SpinLock lock;
|
||||
BAN::String peer_address;
|
||||
};
|
||||
|
||||
@@ -76,7 +78,9 @@ namespace Kernel
|
||||
BAN::ErrorOr<size_t> add_packet(const msghdr&, PacketInfo&&, bool dont_block);
|
||||
|
||||
private:
|
||||
const Socket::Type m_socket_type;
|
||||
const Socket::Type m_socket_type;
|
||||
|
||||
mutable Mutex m_bind_mutex;
|
||||
VirtualFileSystem::File m_bound_file;
|
||||
|
||||
BAN::Variant<ConnectionInfo, ConnectionlessInfo> m_info;
|
||||
|
||||
@@ -67,7 +67,7 @@ namespace Kernel
|
||||
bool putchar_impl(uint8_t ch) override;
|
||||
|
||||
bool can_write_impl() const override;
|
||||
bool has_hungup_impl() const override { return !m_master.valid(); }
|
||||
bool has_hungup_impl() const override { return master_has_closed(); }
|
||||
|
||||
private:
|
||||
PseudoTerminalSlave(BAN::String&& name, uint32_t number, mode_t, uid_t, gid_t);
|
||||
|
||||
@@ -46,12 +46,14 @@ namespace Kernel
|
||||
|
||||
static void keyboard_task(void*);
|
||||
static void initialize_devices();
|
||||
|
||||
bool should_receive_input() const { return m_tty_ctrl.receive_input; }
|
||||
void on_key_event(LibInput::RawKeyEvent);
|
||||
void on_key_event(LibInput::KeyEvent);
|
||||
void handle_input_byte(uint8_t);
|
||||
|
||||
void get_termios(termios* termios) { *termios = m_termios; }
|
||||
// FIXME: validate termios
|
||||
BAN::ErrorOr<void> set_termios(const termios* termios) { m_termios = *termios; return {}; }
|
||||
void get_termios(termios*);
|
||||
BAN::ErrorOr<void> set_termios(const termios*);
|
||||
|
||||
virtual bool is_tty() const override { return true; }
|
||||
|
||||
@@ -85,9 +87,6 @@ namespace Kernel
|
||||
bool putchar(uint8_t ch);
|
||||
void do_backspace();
|
||||
|
||||
protected:
|
||||
termios m_termios;
|
||||
|
||||
private:
|
||||
const dev_t m_rdev;
|
||||
|
||||
@@ -95,23 +94,27 @@ namespace Kernel
|
||||
|
||||
struct tty_ctrl_t
|
||||
{
|
||||
bool draw_graphics { true };
|
||||
bool receive_input { true };
|
||||
ThreadBlocker thread_blocker;
|
||||
BAN::Atomic<bool> draw_graphics { true };
|
||||
BAN::Atomic<bool> receive_input { true };
|
||||
};
|
||||
tty_ctrl_t m_tty_ctrl;
|
||||
|
||||
struct Buffer
|
||||
{
|
||||
BAN::UniqPtr<ByteRingBuffer> buffer;
|
||||
bool flush { false };
|
||||
BAN::Atomic<bool> flush { false };
|
||||
ThreadBlocker thread_blocker;
|
||||
};
|
||||
Buffer m_output;
|
||||
|
||||
winsize m_winsize {};
|
||||
|
||||
SpinLock m_termios_lock;
|
||||
termios m_termios;
|
||||
|
||||
protected:
|
||||
Mutex m_mutex;
|
||||
|
||||
RecursiveSpinLock m_write_lock;
|
||||
ThreadBlocker m_write_blocker;
|
||||
};
|
||||
|
||||
@@ -62,8 +62,8 @@ namespace Kernel
|
||||
Mutex m_command_mutex;
|
||||
|
||||
BAN::Atomic<bool> m_has_initialized_leds { false };
|
||||
uint8_t m_led_state { 0b0001 };
|
||||
uint8_t m_rumble_strength { 0x00 };
|
||||
BAN::Atomic<uint8_t> m_led_state { 0b0001 };
|
||||
BAN::Atomic<uint8_t> m_rumble_strength { 0x00 };
|
||||
|
||||
friend class BAN::RefPtr<USBJoystick>;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user