mirror of
https://github.com/RPCSX/rpcsx.git
synced 2026-04-04 14:08:37 +00:00
[orbis-kernel] Implement _umtx_op for umutex (no PI)
This commit is contained in:
parent
d273e649bd
commit
bfffd20946
4 changed files with 328 additions and 94 deletions
|
|
@ -1,16 +1,44 @@
|
|||
#pragma once
|
||||
#include "evf.hpp"
|
||||
#include "utils/LinkedNode.hpp"
|
||||
#include "utils/SharedCV.hpp"
|
||||
#include "utils/SharedMutex.hpp"
|
||||
|
||||
#include "KernelAllocator.hpp"
|
||||
#include "orbis/thread/types.hpp"
|
||||
#include <algorithm>
|
||||
#include <cstdint>
|
||||
#include <mutex>
|
||||
#include <pthread.h>
|
||||
#include <utility>
|
||||
|
||||
namespace orbis {
|
||||
struct Process;
|
||||
struct Thread;
|
||||
|
||||
struct UmtxKey {
|
||||
// TODO: may contain a reference to a shared memory
|
||||
void *addr;
|
||||
pid_t pid;
|
||||
|
||||
auto operator<=>(const UmtxKey &) const = default;
|
||||
};
|
||||
|
||||
struct UmtxCond {
|
||||
Thread *thr;
|
||||
utils::shared_cv cv;
|
||||
|
||||
UmtxCond(Thread *thr) : thr(thr) {}
|
||||
};
|
||||
|
||||
struct UmtxChain {
|
||||
utils::shared_mutex mtx;
|
||||
utils::kmultimap<UmtxKey, UmtxCond> sleep_queue;
|
||||
utils::kmultimap<UmtxKey, UmtxCond> spare_queue;
|
||||
|
||||
std::pair<const UmtxKey, UmtxCond> *enqueue(UmtxKey &key, Thread *thr);
|
||||
void erase(std::pair<const UmtxKey, UmtxCond> *obj);
|
||||
};
|
||||
|
||||
class alignas(__STDCPP_DEFAULT_NEW_ALIGNMENT__) KernelContext final {
|
||||
public:
|
||||
|
|
@ -47,6 +75,31 @@ public:
|
|||
return {};
|
||||
}
|
||||
|
||||
enum {
|
||||
c_golden_ratio_prime = 2654404609u,
|
||||
c_umtx_chains = 512,
|
||||
c_umtx_shifts = 23,
|
||||
};
|
||||
|
||||
// Use getUmtxChain0 or getUmtxChain1
|
||||
std::tuple<UmtxChain &, UmtxKey, std::unique_lock<shared_mutex>>
|
||||
getUmtxChainIndexed(int i, pid_t pid, void *ptr) {
|
||||
auto n = reinterpret_cast<std::uintptr_t>(ptr) + pid;
|
||||
n = ((n * c_golden_ratio_prime) >> c_umtx_shifts) % c_umtx_chains;
|
||||
std::unique_lock lock(m_umtx_chains[i][n].mtx);
|
||||
return {m_umtx_chains[i][n], UmtxKey{ptr, pid}, std::move(lock)};
|
||||
}
|
||||
|
||||
// Internal Umtx: Wait/Cv/Sem
|
||||
auto getUmtxChain0(pid_t pid, void *ptr) {
|
||||
return getUmtxChainIndexed(0, pid, ptr);
|
||||
}
|
||||
|
||||
// Internal Umtx: Mutex/Umtx/Rwlock
|
||||
auto getUmtxChain1(pid_t pid, void *ptr) {
|
||||
return getUmtxChainIndexed(1, pid, ptr);
|
||||
}
|
||||
|
||||
private:
|
||||
shared_mutex m_evf_mtx;
|
||||
mutable pthread_mutex_t m_heap_mtx;
|
||||
|
|
@ -55,6 +108,8 @@ private:
|
|||
utils::kmultimap<std::size_t, void *> m_free_heap;
|
||||
utils::kmultimap<std::size_t, void *> m_used_node;
|
||||
|
||||
UmtxChain m_umtx_chains[2][c_umtx_chains]{};
|
||||
|
||||
mutable shared_mutex m_proc_mtx;
|
||||
utils::LinkedNode<Process> *m_processes = nullptr;
|
||||
utils::kmap<utils::kstring, Ref<EventFlag>> m_event_flags;
|
||||
|
|
|
|||
|
|
@ -61,22 +61,21 @@ struct usem {
|
|||
|
||||
struct Thread;
|
||||
ErrorCode umtx_lock_umtx(Thread *thread, ptr<umtx> umtx, ulong id,
|
||||
timespec *ts);
|
||||
std::uint64_t ut);
|
||||
ErrorCode umtx_unlock_umtx(Thread *thread, ptr<umtx> umtx, ulong id);
|
||||
ErrorCode umtx_wait(Thread *thread, ptr<void> addr, ulong id,
|
||||
timespec *timeout);
|
||||
ErrorCode umtx_wait(Thread *thread, ptr<void> addr, ulong id, std::uint64_t ut);
|
||||
ErrorCode umtx_wake(Thread *thread, ptr<void> uaddr, sint n_wake);
|
||||
ErrorCode umtx_trylock_umutex(Thread *thread, ptr<umutex> m);
|
||||
ErrorCode umtx_lock_umutex(Thread *thread, ptr<umutex> m, timespec *timeout);
|
||||
ErrorCode umtx_lock_umutex(Thread *thread, ptr<umutex> m, std::uint64_t ut);
|
||||
ErrorCode umtx_unlock_umutex(Thread *thread, ptr<umutex> m);
|
||||
ErrorCode umtx_set_ceiling(Thread *thread, ptr<umutex> m, std::uint32_t ceiling,
|
||||
ptr<uint32_t> oldCeiling);
|
||||
ErrorCode umtx_cv_wait(Thread *thread, ptr<ucond> cv, ptr<umutex> m,
|
||||
timespec *ts, ulong wflags);
|
||||
std::uint64_t ut, ulong wflags);
|
||||
ErrorCode umtx_cv_signal(Thread *thread, ptr<ucond> cv);
|
||||
ErrorCode umtx_cv_broadcast(Thread *thread, ptr<ucond> cv);
|
||||
ErrorCode umtx_wait_uint(Thread *thread, ptr<void> addr, ulong id,
|
||||
timespec *timeout);
|
||||
std::uint64_t ut);
|
||||
ErrorCode umtx_rw_rdlock(Thread *thread, ptr<void> obj, std::int64_t val,
|
||||
ptr<void> uaddr1, ptr<void> uaddr2);
|
||||
ErrorCode umtx_rw_wrlock(Thread *thread, ptr<void> obj, std::int64_t val,
|
||||
|
|
@ -84,9 +83,9 @@ ErrorCode umtx_rw_wrlock(Thread *thread, ptr<void> obj, std::int64_t val,
|
|||
ErrorCode umtx_rw_unlock(Thread *thread, ptr<void> obj, std::int64_t val,
|
||||
ptr<void> uaddr1, ptr<void> uaddr2);
|
||||
ErrorCode umtx_wait_uint_private(Thread *thread, ptr<void> addr, ulong id,
|
||||
timespec *timeout);
|
||||
std::uint64_t ut);
|
||||
ErrorCode umtx_wake_private(Thread *thread, ptr<void> uaddr, sint n_wake);
|
||||
ErrorCode umtx_wait_umutex(Thread *thread, ptr<umutex> m, timespec *timeout);
|
||||
ErrorCode umtx_wait_umutex(Thread *thread, ptr<umutex> m, std::uint64_t ut);
|
||||
ErrorCode umtx_wake_umutex(Thread *thread, ptr<void> obj, std::int64_t val,
|
||||
ptr<void> uaddr1, ptr<void> uaddr2);
|
||||
ErrorCode umtx_sem_wait(Thread *thread, ptr<void> obj, std::int64_t val,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue