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
This commit is contained in:
Bananymous 2025-08-21 02:56:17 +03:00
parent fb61cab70d
commit 350ae90bb6
2 changed files with 19 additions and 23 deletions

View File

@ -350,14 +350,6 @@ namespace Kernel
BAN::UniqPtr<PageTable> m_page_table; BAN::UniqPtr<PageTable> m_page_table;
BAN::RefPtr<TTY> m_controlling_terminal; BAN::RefPtr<TTY> m_controlling_terminal;
struct futex_t
{
ThreadBlocker blocker;
uint32_t waiters { 0 };
uint32_t to_wakeup { 0 };
};
BAN::HashMap<paddr_t, BAN::UniqPtr<futex_t>> m_futexes;
friend class Thread; friend class Thread;
}; };

View File

@ -37,6 +37,15 @@ namespace Kernel
static BAN::Vector<Process*> s_processes; static BAN::Vector<Process*> s_processes;
static RecursiveSpinLock s_process_lock; static RecursiveSpinLock s_process_lock;
struct futex_t
{
ThreadBlocker blocker;
uint32_t waiters { 0 };
uint32_t to_wakeup { 0 };
};
static BAN::HashMap<paddr_t, BAN::UniqPtr<futex_t>> s_futexes;
static Mutex s_futex_lock;
static void for_each_process(const BAN::Function<BAN::Iteration(Process&)>& callback) static void for_each_process(const BAN::Function<BAN::Iteration(Process&)>& callback)
{ {
SpinLockGuard _(s_process_lock); SpinLockGuard _(s_process_lock);
@ -2720,17 +2729,12 @@ namespace Kernel
if (vaddr % 4) if (vaddr % 4)
return BAN::Error::from_errno(EINVAL); return BAN::Error::from_errno(EINVAL);
const bool is_private = (op & FUTEX_PRIVATE);
const bool is_realtime = (op & FUTEX_REALTIME); const bool is_realtime = (op & FUTEX_REALTIME);
op &= ~(FUTEX_PRIVATE | FUTEX_REALTIME); op &= ~(FUTEX_PRIVATE | FUTEX_REALTIME);
if (!is_private) // TODO: possibly optimize private futexes?
{
dwarnln("TODO: shared futex");
return BAN::Error::from_errno(ENOTSUP);
}
LockGuard _(m_process_lock); LockGuard _(s_futex_lock);
auto* buffer_region = TRY(validate_and_pin_pointer_access(addr, sizeof(uint32_t), false)); auto* buffer_region = TRY(validate_and_pin_pointer_access(addr, sizeof(uint32_t), false));
BAN::ScopeGuard pin_guard([&] { if (buffer_region) buffer_region->unpin(); }); 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); return SystemTimer::get().ns_since_boot() + (abs_ns - real_ns);
}()); }());
auto it = m_futexes.find(paddr); auto it = s_futexes.find(paddr);
if (it == m_futexes.end()) if (it == s_futexes.end())
it = TRY(m_futexes.emplace(paddr, TRY(BAN::UniqPtr<futex_t>::create()))); it = TRY(s_futexes.emplace(paddr, TRY(BAN::UniqPtr<futex_t>::create())));
futex_t* const futex = it->value.ptr(); futex_t* const futex = it->value.ptr();
futex->waiters++; futex->waiters++;
BAN::ScopeGuard _([futex, paddr, this] { BAN::ScopeGuard _([futex, paddr] {
if (--futex->waiters == 0) if (--futex->waiters == 0)
m_futexes.remove(paddr); s_futexes.remove(paddr);
}); });
for (;;) 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) if (BAN::atomic_load(*addr) == val || futex->to_wakeup == 0)
continue; continue;
futex->to_wakeup--; futex->to_wakeup--;
@ -2783,8 +2787,8 @@ namespace Kernel
} }
case FUTEX_WAKE: case FUTEX_WAKE:
{ {
auto it = m_futexes.find(paddr); auto it = s_futexes.find(paddr);
if (it == m_futexes.end()) if (it == s_futexes.end())
return 0; return 0;
futex_t* const futex = it->value.ptr(); futex_t* const futex = it->value.ptr();