1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-25 16:57:35 +00:00

Kernel: Make self-contained locking smart pointers their own classes

Until now, our kernel has reimplemented a number of AK classes to
provide automatic internal locking:

- RefPtr
- NonnullRefPtr
- WeakPtr
- Weakable

This patch renames the Kernel classes so that they can coexist with
the original AK classes:

- RefPtr => LockRefPtr
- NonnullRefPtr => NonnullLockRefPtr
- WeakPtr => LockWeakPtr
- Weakable => LockWeakable

The goal here is to eventually get rid of the Lock* classes in favor of
using external locking.
This commit is contained in:
Andreas Kling 2022-08-19 20:53:40 +02:00
parent e475263113
commit 11eee67b85
360 changed files with 1703 additions and 1672 deletions

View file

@ -10,12 +10,9 @@
#include <AK/HashMap.h>
#include <AK/IntrusiveList.h>
#include <AK/IntrusiveListRelaxedConst.h>
#include <AK/NonnullRefPtrVector.h>
#include <AK/OwnPtr.h>
#include <AK/Userspace.h>
#include <AK/Variant.h>
#include <AK/WeakPtr.h>
#include <AK/Weakable.h>
#include <Kernel/API/POSIX/sys/resource.h>
#include <Kernel/API/Syscall.h>
#include <Kernel/Assertions.h>
@ -25,6 +22,9 @@
#include <Kernel/FileSystem/UnveilNode.h>
#include <Kernel/Forward.h>
#include <Kernel/FutexQueue.h>
#include <Kernel/Library/LockWeakPtr.h>
#include <Kernel/Library/LockWeakable.h>
#include <Kernel/Library/NonnullLockRefPtrVector.h>
#include <Kernel/Locking/Mutex.h>
#include <Kernel/Locking/MutexProtected.h>
#include <Kernel/Memory/AddressSpace.h>
@ -103,7 +103,7 @@ struct LoadResult;
class Process final
: public ListedRefCounted<Process, LockType::Spinlock>
, public Weakable<Process> {
, public LockWeakable<Process> {
class ProtectedValues {
public:
@ -188,19 +188,19 @@ public:
};
template<typename EntryFunction>
static RefPtr<Process> create_kernel_process(RefPtr<Thread>& first_thread, NonnullOwnPtr<KString> name, EntryFunction entry, u32 affinity = THREAD_AFFINITY_DEFAULT, RegisterProcess do_register = RegisterProcess::Yes)
static LockRefPtr<Process> create_kernel_process(LockRefPtr<Thread>& first_thread, NonnullOwnPtr<KString> name, EntryFunction entry, u32 affinity = THREAD_AFFINITY_DEFAULT, RegisterProcess do_register = RegisterProcess::Yes)
{
auto* entry_func = new EntryFunction(move(entry));
return create_kernel_process(first_thread, move(name), &Process::kernel_process_trampoline<EntryFunction>, entry_func, affinity, do_register);
}
static RefPtr<Process> create_kernel_process(RefPtr<Thread>& first_thread, NonnullOwnPtr<KString> name, void (*entry)(void*), void* entry_data = nullptr, u32 affinity = THREAD_AFFINITY_DEFAULT, RegisterProcess do_register = RegisterProcess::Yes);
static ErrorOr<NonnullRefPtr<Process>> try_create_user_process(RefPtr<Thread>& first_thread, StringView path, UserID, GroupID, NonnullOwnPtrVector<KString> arguments, NonnullOwnPtrVector<KString> environment, TTY*);
static LockRefPtr<Process> create_kernel_process(LockRefPtr<Thread>& first_thread, NonnullOwnPtr<KString> name, void (*entry)(void*), void* entry_data = nullptr, u32 affinity = THREAD_AFFINITY_DEFAULT, RegisterProcess do_register = RegisterProcess::Yes);
static ErrorOr<NonnullLockRefPtr<Process>> try_create_user_process(LockRefPtr<Thread>& first_thread, StringView path, UserID, GroupID, NonnullOwnPtrVector<KString> arguments, NonnullOwnPtrVector<KString> environment, TTY*);
static void register_new(Process&);
~Process();
RefPtr<Thread> create_kernel_thread(void (*entry)(void*), void* entry_data, u32 priority, NonnullOwnPtr<KString> name, u32 affinity = THREAD_AFFINITY_DEFAULT, bool joinable = true);
LockRefPtr<Thread> create_kernel_thread(void (*entry)(void*), void* entry_data, u32 priority, NonnullOwnPtr<KString> name, u32 affinity = THREAD_AFFINITY_DEFAULT, bool joinable = true);
bool is_profiling() const { return m_profiling; }
void set_profiling(bool profiling) { m_profiling = profiling; }
@ -217,7 +217,7 @@ public:
bool is_kernel_process() const { return m_is_kernel_process; }
bool is_user_process() const { return !m_is_kernel_process; }
static RefPtr<Process> from_pid(ProcessID);
static LockRefPtr<Process> from_pid(ProcessID);
static SessionID get_sid_from_pgid(ProcessGroupID pgid);
StringView name() const { return m_name->view(); }
@ -450,7 +450,7 @@ public:
u32 m_ticks_in_user_for_dead_children { 0 };
u32 m_ticks_in_kernel_for_dead_children { 0 };
NonnullRefPtr<Custody> current_directory();
NonnullLockRefPtr<Custody> current_directory();
Custody* executable() { return m_executable.ptr(); }
Custody const* executable() const { return m_executable.ptr(); }
@ -461,7 +461,7 @@ public:
ErrorOr<void> exec(NonnullOwnPtr<KString> path, NonnullOwnPtrVector<KString> arguments, NonnullOwnPtrVector<KString> environment, Thread*& new_main_thread, u32& prev_flags, int recursion_depth = 0);
ErrorOr<LoadResult> load(NonnullRefPtr<OpenFileDescription> main_program_description, RefPtr<OpenFileDescription> interpreter_description, const ElfW(Ehdr) & main_program_header);
ErrorOr<LoadResult> load(NonnullLockRefPtr<OpenFileDescription> main_program_description, LockRefPtr<OpenFileDescription> interpreter_description, const ElfW(Ehdr) & main_program_header);
bool is_superuser() const { return euid() == 0; }
@ -532,7 +532,7 @@ public:
ErrorOr<void> set_coredump_property(NonnullOwnPtr<KString> key, NonnullOwnPtr<KString> value);
ErrorOr<void> try_set_coredump_property(StringView key, StringView value);
NonnullRefPtrVector<Thread> const& threads_for_coredump(Badge<Coredump>) const { return m_threads_for_coredump; }
NonnullLockRefPtrVector<Thread> const& threads_for_coredump(Badge<Coredump>) const { return m_threads_for_coredump; }
PerformanceEventBuffer* perf_events() { return m_perf_event_buffer; }
PerformanceEventBuffer const* perf_events() const { return m_perf_event_buffer; }
@ -557,9 +557,9 @@ private:
bool add_thread(Thread&);
bool remove_thread(Thread&);
Process(NonnullOwnPtr<KString> name, UserID, GroupID, ProcessID ppid, bool is_kernel_process, RefPtr<Custody> current_directory, RefPtr<Custody> executable, TTY* tty, UnveilNode unveil_tree);
static ErrorOr<NonnullRefPtr<Process>> try_create(RefPtr<Thread>& first_thread, NonnullOwnPtr<KString> name, UserID, GroupID, ProcessID ppid, bool is_kernel_process, RefPtr<Custody> current_directory = nullptr, RefPtr<Custody> executable = nullptr, TTY* = nullptr, Process* fork_parent = nullptr);
ErrorOr<void> attach_resources(NonnullOwnPtr<Memory::AddressSpace>&&, RefPtr<Thread>& first_thread, Process* fork_parent);
Process(NonnullOwnPtr<KString> name, UserID, GroupID, ProcessID ppid, bool is_kernel_process, LockRefPtr<Custody> current_directory, LockRefPtr<Custody> executable, TTY* tty, UnveilNode unveil_tree);
static ErrorOr<NonnullLockRefPtr<Process>> try_create(LockRefPtr<Thread>& first_thread, NonnullOwnPtr<KString> name, UserID, GroupID, ProcessID ppid, bool is_kernel_process, LockRefPtr<Custody> current_directory = nullptr, LockRefPtr<Custody> executable = nullptr, TTY* = nullptr, Process* fork_parent = nullptr);
ErrorOr<void> attach_resources(NonnullOwnPtr<Memory::AddressSpace>&&, LockRefPtr<Thread>& first_thread, Process* fork_parent);
static ProcessID allocate_pid();
void kill_threads_except_self();
@ -569,19 +569,19 @@ private:
bool create_perf_events_buffer_if_needed();
void delete_perf_events_buffer();
ErrorOr<void> do_exec(NonnullRefPtr<OpenFileDescription> main_program_description, NonnullOwnPtrVector<KString> arguments, NonnullOwnPtrVector<KString> environment, RefPtr<OpenFileDescription> interpreter_description, Thread*& new_main_thread, u32& prev_flags, const ElfW(Ehdr) & main_program_header);
ErrorOr<void> do_exec(NonnullLockRefPtr<OpenFileDescription> main_program_description, NonnullOwnPtrVector<KString> arguments, NonnullOwnPtrVector<KString> environment, LockRefPtr<OpenFileDescription> interpreter_description, Thread*& new_main_thread, u32& prev_flags, const ElfW(Ehdr) & main_program_header);
ErrorOr<FlatPtr> do_write(OpenFileDescription&, UserOrKernelBuffer const&, size_t);
ErrorOr<FlatPtr> do_statvfs(FileSystem const& path, Custody const*, statvfs* buf);
ErrorOr<RefPtr<OpenFileDescription>> find_elf_interpreter_for_executable(StringView path, ElfW(Ehdr) const& main_executable_header, size_t main_executable_header_size, size_t file_size);
ErrorOr<LockRefPtr<OpenFileDescription>> find_elf_interpreter_for_executable(StringView path, ElfW(Ehdr) const& main_executable_header, size_t main_executable_header_size, size_t file_size);
ErrorOr<void> do_kill(Process&, int signal);
ErrorOr<void> do_killpg(ProcessGroupID pgrp, int signal);
ErrorOr<void> do_killall(int signal);
ErrorOr<void> do_killself(int signal);
ErrorOr<siginfo_t> do_waitid(Variant<Empty, NonnullRefPtr<Process>, NonnullRefPtr<ProcessGroup>> waitee, int options);
ErrorOr<siginfo_t> do_waitid(Variant<Empty, NonnullLockRefPtr<Process>, NonnullLockRefPtr<ProcessGroup>> waitee, int options);
static ErrorOr<NonnullOwnPtr<KString>> get_syscall_path_argument(Userspace<char const*> user_path, size_t path_length);
static ErrorOr<NonnullOwnPtr<KString>> get_syscall_path_argument(Syscall::StringArgument const&);
@ -598,7 +598,7 @@ private:
ErrorOr<FlatPtr> read_impl(int fd, Userspace<u8*> buffer, size_t size);
public:
NonnullRefPtr<ProcessProcFSTraits> procfs_traits() const { return *m_procfs_traits; }
NonnullLockRefPtr<ProcessProcFSTraits> procfs_traits() const { return *m_procfs_traits; }
ErrorOr<void> procfs_get_fds_stats(KBufferBuilder& builder) const;
ErrorOr<void> procfs_get_perf_events(KBufferBuilder& builder) const;
ErrorOr<void> procfs_get_unveil_stats(KBufferBuilder& builder) const;
@ -610,11 +610,11 @@ public:
mode_t binary_link_required_mode() const;
ErrorOr<void> procfs_get_thread_stack(ThreadID thread_id, KBufferBuilder& builder) const;
ErrorOr<void> traverse_stacks_directory(FileSystemID, Function<ErrorOr<void>(FileSystem::DirectoryEntryView const&)> callback) const;
ErrorOr<NonnullRefPtr<Inode>> lookup_stacks_directory(ProcFS const&, StringView name) const;
ErrorOr<NonnullLockRefPtr<Inode>> lookup_stacks_directory(ProcFS const&, StringView name) const;
ErrorOr<size_t> procfs_get_file_description_link(unsigned fd, KBufferBuilder& builder) const;
ErrorOr<void> traverse_file_descriptions_directory(FileSystemID, Function<ErrorOr<void>(FileSystem::DirectoryEntryView const&)> callback) const;
ErrorOr<NonnullRefPtr<Inode>> lookup_file_descriptions_directory(ProcFS const&, StringView name) const;
ErrorOr<NonnullRefPtr<Inode>> lookup_children_directory(ProcFS const&, StringView name) const;
ErrorOr<NonnullLockRefPtr<Inode>> lookup_file_descriptions_directory(ProcFS const&, StringView name) const;
ErrorOr<NonnullLockRefPtr<Inode>> lookup_children_directory(ProcFS const&, StringView name) const;
ErrorOr<void> traverse_children_directory(FileSystemID, Function<ErrorOr<void>(FileSystem::DirectoryEntryView const&)> callback) const;
ErrorOr<size_t> procfs_get_child_proccess_link(ProcessID child_pid, KBufferBuilder& builder) const;
@ -634,7 +634,7 @@ private:
OwnPtr<Memory::AddressSpace> m_space;
RefPtr<ProcessGroup> m_pg;
LockRefPtr<ProcessGroup> m_pg;
AtomicEdgeAction<u32> m_protected_data_refs;
void protect_data();
@ -666,10 +666,10 @@ public:
void set_flags(u32 flags) { m_flags = flags; }
void clear();
void set(NonnullRefPtr<OpenFileDescription>&&, u32 flags = 0);
void set(NonnullLockRefPtr<OpenFileDescription>&&, u32 flags = 0);
private:
RefPtr<OpenFileDescription> m_description;
LockRefPtr<OpenFileDescription> m_description;
bool m_is_allocated { false };
u32 m_flags { 0 };
};
@ -720,7 +720,7 @@ public:
m_fds_metadatas.clear();
}
ErrorOr<NonnullRefPtr<OpenFileDescription>> open_file_description(int fd) const;
ErrorOr<NonnullLockRefPtr<OpenFileDescription>> open_file_description(int fd) const;
private:
static constexpr size_t s_max_open_file_descriptors { FD_SETSIZE };
@ -769,13 +769,13 @@ public:
class ProcessProcFSTraits : public ProcFSExposedComponent {
public:
static ErrorOr<NonnullRefPtr<ProcessProcFSTraits>> try_create(Badge<Process>, WeakPtr<Process> process)
static ErrorOr<NonnullLockRefPtr<ProcessProcFSTraits>> try_create(Badge<Process>, LockWeakPtr<Process> process)
{
return adopt_nonnull_ref_or_enomem(new (nothrow) ProcessProcFSTraits(move(process)));
return adopt_nonnull_lock_ref_or_enomem(new (nothrow) ProcessProcFSTraits(move(process)));
}
virtual InodeIndex component_index() const override;
virtual ErrorOr<NonnullRefPtr<Inode>> to_inode(ProcFS const& procfs_instance) const override;
virtual ErrorOr<NonnullLockRefPtr<Inode>> to_inode(ProcFS const& procfs_instance) const override;
virtual ErrorOr<void> traverse_as_directory(FileSystemID, Function<ErrorOr<void>(FileSystem::DirectoryEntryView const&)>) const override;
virtual mode_t required_mode() const override { return 0555; }
@ -783,25 +783,25 @@ public:
virtual GroupID owner_group() const override;
private:
explicit ProcessProcFSTraits(WeakPtr<Process> process)
explicit ProcessProcFSTraits(LockWeakPtr<Process> process)
: m_process(move(process))
{
}
// NOTE: We need to weakly hold on to the process, because otherwise
// we would be creating a reference cycle.
WeakPtr<Process> m_process;
LockWeakPtr<Process> m_process;
};
MutexProtected<OpenFileDescriptions>& fds() { return m_fds; }
MutexProtected<OpenFileDescriptions> const& fds() const { return m_fds; }
ErrorOr<NonnullRefPtr<OpenFileDescription>> open_file_description(int fd)
ErrorOr<NonnullLockRefPtr<OpenFileDescription>> open_file_description(int fd)
{
return m_fds.with_shared([fd](auto& fds) { return fds.open_file_description(fd); });
}
ErrorOr<NonnullRefPtr<OpenFileDescription>> open_file_description(int fd) const
ErrorOr<NonnullLockRefPtr<OpenFileDescription>> open_file_description(int fd) const
{
return m_fds.with_shared([fd](auto& fds) { return fds.open_file_description(fd); });
}
@ -825,23 +825,23 @@ private:
Atomic<bool, AK::MemoryOrder::memory_order_relaxed> m_is_stopped { false };
bool m_should_generate_coredump { false };
RefPtr<Custody> m_executable;
LockRefPtr<Custody> m_executable;
SpinlockProtected<RefPtr<Custody>> m_current_directory;
SpinlockProtected<LockRefPtr<Custody>> m_current_directory;
NonnullOwnPtrVector<KString> m_arguments;
NonnullOwnPtrVector<KString> m_environment;
RefPtr<TTY> m_tty;
LockRefPtr<TTY> m_tty;
WeakPtr<Memory::Region> m_master_tls_region;
LockWeakPtr<Memory::Region> m_master_tls_region;
size_t m_master_tls_size { 0 };
size_t m_master_tls_alignment { 0 };
Mutex m_big_lock { "Process"sv, Mutex::MutexBehavior::BigLock };
Mutex m_ptrace_lock { "ptrace"sv };
RefPtr<Timer> m_alarm_timer;
LockRefPtr<Timer> m_alarm_timer;
SpinlockProtected<UnveilData> m_unveil_data;
@ -860,9 +860,9 @@ private:
};
SpinlockProtected<Array<CoredumpProperty, 4>> m_coredump_properties { LockRank::None };
NonnullRefPtrVector<Thread> m_threads_for_coredump;
NonnullLockRefPtrVector<Thread> m_threads_for_coredump;
mutable RefPtr<ProcessProcFSTraits> m_procfs_traits;
mutable LockRefPtr<ProcessProcFSTraits> m_procfs_traits;
struct SignalActionData {
VirtualAddress handler_or_sigaction;
int flags { 0 };