From 350ae90bb6e047cfd4bb011058bfc245826b156f Mon Sep 17 00:00:00 2001 From: Bananymous Date: Thu, 21 Aug 2025 02:56:17 +0300 Subject: [PATCH] Kernel: Make all futexes shared Some stuff tries to use shared futexes so make them all shared. Private futexes would be faster as they are process specific but supporting both would need some reworks --- kernel/include/kernel/Process.h | 8 -------- kernel/kernel/Process.cpp | 34 ++++++++++++++++++--------------- 2 files changed, 19 insertions(+), 23 deletions(-) diff --git a/kernel/include/kernel/Process.h b/kernel/include/kernel/Process.h index 200a30ff..031e1620 100644 --- a/kernel/include/kernel/Process.h +++ b/kernel/include/kernel/Process.h @@ -350,14 +350,6 @@ namespace Kernel BAN::UniqPtr m_page_table; BAN::RefPtr m_controlling_terminal; - struct futex_t - { - ThreadBlocker blocker; - uint32_t waiters { 0 }; - uint32_t to_wakeup { 0 }; - }; - BAN::HashMap> m_futexes; - friend class Thread; }; diff --git a/kernel/kernel/Process.cpp b/kernel/kernel/Process.cpp index 3122d934..8ddfe24b 100644 --- a/kernel/kernel/Process.cpp +++ b/kernel/kernel/Process.cpp @@ -37,6 +37,15 @@ namespace Kernel static BAN::Vector s_processes; static RecursiveSpinLock s_process_lock; + struct futex_t + { + ThreadBlocker blocker; + uint32_t waiters { 0 }; + uint32_t to_wakeup { 0 }; + }; + static BAN::HashMap> s_futexes; + static Mutex s_futex_lock; + static void for_each_process(const BAN::Function& callback) { SpinLockGuard _(s_process_lock); @@ -2720,17 +2729,12 @@ namespace Kernel if (vaddr % 4) return BAN::Error::from_errno(EINVAL); - const bool is_private = (op & FUTEX_PRIVATE); const bool is_realtime = (op & FUTEX_REALTIME); op &= ~(FUTEX_PRIVATE | FUTEX_REALTIME); - if (!is_private) - { - dwarnln("TODO: shared futex"); - return BAN::Error::from_errno(ENOTSUP); - } + // TODO: possibly optimize private futexes? - LockGuard _(m_process_lock); + LockGuard _(s_futex_lock); auto* buffer_region = TRY(validate_and_pin_pointer_access(addr, sizeof(uint32_t), false)); BAN::ScopeGuard pin_guard([&] { if (buffer_region) buffer_region->unpin(); }); @@ -2761,20 +2765,20 @@ namespace Kernel return SystemTimer::get().ns_since_boot() + (abs_ns - real_ns); }()); - auto it = m_futexes.find(paddr); - if (it == m_futexes.end()) - it = TRY(m_futexes.emplace(paddr, TRY(BAN::UniqPtr::create()))); + auto it = s_futexes.find(paddr); + if (it == s_futexes.end()) + it = TRY(s_futexes.emplace(paddr, TRY(BAN::UniqPtr::create()))); futex_t* const futex = it->value.ptr(); futex->waiters++; - BAN::ScopeGuard _([futex, paddr, this] { + BAN::ScopeGuard _([futex, paddr] { if (--futex->waiters == 0) - m_futexes.remove(paddr); + s_futexes.remove(paddr); }); for (;;) { - TRY(Thread::current().block_or_eintr_or_waketime_ns(futex->blocker, wake_time_ns, true, &m_process_lock)); + TRY(Thread::current().block_or_eintr_or_waketime_ns(futex->blocker, wake_time_ns, true, &s_futex_lock)); if (BAN::atomic_load(*addr) == val || futex->to_wakeup == 0) continue; futex->to_wakeup--; @@ -2783,8 +2787,8 @@ namespace Kernel } case FUTEX_WAKE: { - auto it = m_futexes.find(paddr); - if (it == m_futexes.end()) + auto it = s_futexes.find(paddr); + if (it == s_futexes.end()) return 0; futex_t* const futex = it->value.ptr();