diff --git a/orbis-kernel/include/orbis/umtx.hpp b/orbis-kernel/include/orbis/umtx.hpp index c8f9d73d6..b8b358908 100644 --- a/orbis-kernel/include/orbis/umtx.hpp +++ b/orbis-kernel/include/orbis/umtx.hpp @@ -2,54 +2,99 @@ #include "error/ErrorCode.hpp" #include "orbis-config.hpp" +#include "thread/types.hpp" +#include "time.hpp" +#include +#include namespace orbis { +inline constexpr ulong kUmtxUnowned = 0; +inline constexpr ulong kUmtxContested = std::numeric_limits::min(); + +inline constexpr auto kUsyncProcessShared = 1; + +inline constexpr auto kUmutexUnowned = 0; +inline constexpr auto kUmutexContested = 0x80000000; +inline constexpr auto kUmutexErrorCheck = 2; +inline constexpr auto kUmutexPrioInherit = 4; +inline constexpr auto kUmutexPrioProtect = 8; + +inline constexpr auto kUrwLockPreferReader = 2; +inline constexpr auto kUrwLockWriteOwner = 0x80000000; +inline constexpr auto kUrwLockWriteWaiters = 0x40000000; +inline constexpr auto kUrwLockReadWaiters = 0x20000000; +inline constexpr auto kUrwLockMaxReaders = 0x1fffffff; + +inline constexpr auto kSemNamed = 2; + +struct umtx { + std::atomic owner; // Owner of the mutex +}; + +struct umutex { + std::atomic owner; // Owner of the mutex + uint32_t flags; // Flags of the mutex + uint32_t ceilings[2]; // Priority protect ceiling + uint32_t spare[4]; +}; + +struct ucond { + std::atomic has_waiters; // Has waiters in kernel + uint32_t flags; // Flags of the condition variable + uint32_t clockid; // Clock id + uint32_t spare[1]; // Spare space +}; + +struct urwlock { + std::atomic state; + uint32_t flags; + uint32_t blocked_readers; + uint32_t blocked_writers; + uint32_t spare[4]; +}; + +struct usem { + std::atomic has_waiters; + std::atomic count; + uint32_t flags; +}; + struct Thread; -ErrorCode umtx_lock_umtx(Thread *thread, ptr obj, std::int64_t val, - ptr uaddr1, ptr uaddr2); -ErrorCode umtx_unlock_umtx(Thread *thread, ptr obj, std::int64_t val, - ptr uaddr1, ptr uaddr2); -ErrorCode umtx_wait(Thread *thread, ptr obj, std::int64_t val, - ptr uaddr1, ptr uaddr2); -ErrorCode umtx_wake(Thread *thread, ptr obj, std::int64_t val, - ptr uaddr1, ptr uaddr2); -ErrorCode umtx_trylock_umutex(Thread *thread, ptr obj, std::int64_t val, - ptr uaddr1, ptr uaddr2); -ErrorCode umtx_lock_umutex(Thread *thread, ptr obj, std::int64_t val, - ptr uaddr1, ptr uaddr2); -ErrorCode umtx_unlock_umutex(Thread *thread, ptr obj, std::int64_t val, - ptr uaddr1, ptr uaddr2); -ErrorCode umtx_set_ceiling(Thread *thread, ptr obj, std::int64_t val, - ptr uaddr1, ptr uaddr2); -ErrorCode umtx_cv_wait(Thread *thread, ptr obj, std::int64_t val, - ptr uaddr1, ptr uaddr2); -ErrorCode umtx_cv_signal(Thread *thread, ptr obj, std::int64_t val, - ptr uaddr1, ptr uaddr2); -ErrorCode umtx_cv_broadcast(Thread *thread, ptr obj, std::int64_t val, - ptr uaddr1, ptr uaddr2); -ErrorCode umtx_wait_uint(Thread *thread, ptr obj, std::int64_t val, - ptr uaddr1, ptr uaddr2); +ErrorCode umtx_lock_umtx(Thread *thread, ptr umtx, ulong id, + timespec *ts); +ErrorCode umtx_unlock_umtx(Thread *thread, ptr umtx, ulong id); +ErrorCode umtx_wait(Thread *thread, ptr addr, ulong id, + timespec *timeout); +ErrorCode umtx_wake(Thread *thread, ptr uaddr, sint n_wake); +ErrorCode umtx_trylock_umutex(Thread *thread, ptr m); +ErrorCode umtx_lock_umutex(Thread *thread, ptr m, timespec *timeout); +ErrorCode umtx_unlock_umutex(Thread *thread, ptr m); +ErrorCode umtx_set_ceiling(Thread *thread, ptr m, std::uint32_t ceiling, + ptr oldCeiling); +ErrorCode umtx_cv_wait(Thread *thread, ptr cv, ptr m, + timespec *ts, ulong wflags); +ErrorCode umtx_cv_signal(Thread *thread, ptr cv); +ErrorCode umtx_cv_broadcast(Thread *thread, ptr cv); +ErrorCode umtx_wait_uint(Thread *thread, ptr addr, ulong id, + timespec *timeout); ErrorCode umtx_rw_rdlock(Thread *thread, ptr obj, std::int64_t val, ptr uaddr1, ptr uaddr2); ErrorCode umtx_rw_wrlock(Thread *thread, ptr obj, std::int64_t val, ptr uaddr1, ptr uaddr2); ErrorCode umtx_rw_unlock(Thread *thread, ptr obj, std::int64_t val, ptr uaddr1, ptr uaddr2); -ErrorCode umtx_wait_uint_private(Thread *thread, ptr obj, - std::int64_t val, ptr uaddr1, - ptr uaddr2); -ErrorCode umtx_wake_private(Thread *thread, ptr obj, std::int64_t val, - ptr uaddr1, ptr uaddr2); -ErrorCode umtx_wait_umutex(Thread *thread, ptr obj, std::int64_t val, - ptr uaddr1, ptr uaddr2); +ErrorCode umtx_wait_uint_private(Thread *thread, ptr addr, ulong id, + timespec *timeout); +ErrorCode umtx_wake_private(Thread *thread, ptr uaddr, sint n_wake); +ErrorCode umtx_wait_umutex(Thread *thread, ptr m, timespec *timeout); ErrorCode umtx_wake_umutex(Thread *thread, ptr obj, std::int64_t val, ptr uaddr1, ptr uaddr2); ErrorCode umtx_sem_wait(Thread *thread, ptr obj, std::int64_t val, ptr uaddr1, ptr uaddr2); ErrorCode umtx_sem_wake(Thread *thread, ptr obj, std::int64_t val, ptr uaddr1, ptr uaddr2); -ErrorCode umtx_nwake_private(Thread *thread, ptr obj, std::int64_t val, - ptr uaddr1, ptr uaddr2); +ErrorCode umtx_nwake_private(Thread *thread, ptr uaddrs, + std::int64_t count); ErrorCode umtx_wake2_umutex(Thread *thread, ptr obj, std::int64_t val, ptr uaddr1, ptr uaddr2); } // namespace orbis \ No newline at end of file diff --git a/orbis-kernel/src/sys/sys_sce.cpp b/orbis-kernel/src/sys/sys_sce.cpp index 1a4f9b927..70d0c37c7 100644 --- a/orbis-kernel/src/sys/sys_sce.cpp +++ b/orbis-kernel/src/sys/sys_sce.cpp @@ -53,10 +53,6 @@ orbis::SysResult orbis::sys_regmgr_call(Thread *thread, uint32_t op, }; auto int_value = reinterpret_cast(value); - - const char *const string = "someString"; - - ORBIS_LOG_TODO(__FUNCTION__, string); ORBIS_LOG_TODO( __FUNCTION__, int_value->encoded_id, int_value->encoded_id_parts.data[0], diff --git a/orbis-kernel/src/sys/sys_umtx.cpp b/orbis-kernel/src/sys/sys_umtx.cpp index 7feaa5020..48ab55a0e 100644 --- a/orbis-kernel/src/sys/sys_umtx.cpp +++ b/orbis-kernel/src/sys/sys_umtx.cpp @@ -1,53 +1,149 @@ #include "sys/sysproto.hpp" +#include "time.hpp" #include "umtx.hpp" -orbis::SysResult orbis::sys__umtx_lock(Thread *thread, ptr umtx) { - return umtx_lock_umtx(thread, umtx, 0, 0, 0); +static orbis::ErrorCode ureadTimespec(orbis::timespec &ts, + orbis::ptr addr) { + ts = uread(addr); + if (ts.sec < 0 || ts.nsec < 0 || ts.nsec > 1000000000) { + return orbis::ErrorCode::INVAL; + } + + return {}; } -orbis::SysResult orbis::sys__umtx_unlock(Thread *thread, - ptr umtx) { - return umtx_lock_umtx(thread, umtx, thread->tid, 0, 0); + +orbis::SysResult orbis::sys__umtx_lock(Thread *thread, ptr umtx) { + return umtx_lock_umtx(thread, umtx, thread->tid, nullptr); +} +orbis::SysResult orbis::sys__umtx_unlock(Thread *thread, ptr umtx) { + return umtx_unlock_umtx(thread, umtx, thread->tid); } orbis::SysResult orbis::sys__umtx_op(Thread *thread, ptr obj, sint op, ulong val, ptr uaddr1, ptr uaddr2) { switch (op) { - case 0: - return umtx_lock_umtx(thread, obj, val, uaddr1, uaddr2); + case 0: { + timespec *ts = nullptr; + timespec timeout; + if (uaddr2 != nullptr) { + auto result = ureadTimespec(timeout, (ptr)uaddr2); + if (result != ErrorCode{}) { + return result; + } + + ts = &timeout; + } + + return umtx_lock_umtx(thread, (ptr)obj, val, ts); + } case 1: - return umtx_unlock_umtx(thread, obj, val, uaddr1, uaddr2); - case 2: - return umtx_wait(thread, obj, val, uaddr1, uaddr2); + return umtx_unlock_umtx(thread, (ptr)obj, val); + case 2: { + timespec *ts = nullptr; + timespec timeout; + if (uaddr2 != nullptr) { + auto result = ureadTimespec(timeout, (ptr)uaddr2); + if (result != ErrorCode{}) { + return result; + } + + ts = &timeout; + } + + return umtx_wait(thread, obj, val, ts); + } case 3: - return umtx_wake(thread, obj, val, uaddr1, uaddr2); + return umtx_wake(thread, obj, val); case 4: - return umtx_trylock_umutex(thread, obj, val, uaddr1, uaddr2); - case 5: - return umtx_lock_umutex(thread, obj, val, uaddr1, uaddr2); + return umtx_trylock_umutex(thread, (ptr)obj); + case 5: { + timespec *ts = nullptr; + timespec timeout; + if (uaddr2 != nullptr) { + auto result = ureadTimespec(timeout, (ptr)uaddr2); + if (result != ErrorCode{}) { + return result; + } + + ts = &timeout; + } + return umtx_lock_umutex(thread, (ptr)obj, ts); + } case 6: - return umtx_unlock_umutex(thread, obj, val, uaddr1, uaddr2); + return umtx_unlock_umutex(thread, (ptr)obj); case 7: - return umtx_set_ceiling(thread, obj, val, uaddr1, uaddr2); - case 8: - return umtx_cv_wait(thread, obj, val, uaddr1, uaddr2); + return umtx_set_ceiling(thread, (ptr)obj, val, + (ptr)uaddr1); + + case 8: { + timespec *ts = nullptr; + timespec timeout; + if (uaddr2 != nullptr) { + auto result = ureadTimespec(timeout, (ptr)uaddr2); + if (result != ErrorCode{}) { + return result; + } + + ts = &timeout; + } + + return umtx_cv_wait(thread, (ptr)obj, (ptr)uaddr1, ts, val); + } + case 9: - return umtx_cv_signal(thread, obj, val, uaddr1, uaddr2); + return umtx_cv_signal(thread, (ptr)obj); case 10: - return umtx_cv_broadcast(thread, obj, val, uaddr1, uaddr2); - case 11: - return umtx_wait_uint(thread, obj, val, uaddr1, uaddr2); + return umtx_cv_broadcast(thread, (ptr)obj); + case 11: { + timespec *ts = nullptr; + timespec timeout; + if (uaddr2 != nullptr) { + auto result = ureadTimespec(timeout, (ptr)uaddr2); + if (result != ErrorCode{}) { + return result; + } + + ts = &timeout; + } + + return umtx_wait_uint(thread, obj, val, ts); + } case 12: return umtx_rw_rdlock(thread, obj, val, uaddr1, uaddr2); case 13: return umtx_rw_wrlock(thread, obj, val, uaddr1, uaddr2); case 14: return umtx_rw_unlock(thread, obj, val, uaddr1, uaddr2); - case 15: - return umtx_wait_uint_private(thread, obj, val, uaddr1, uaddr2); + case 15: { + timespec *ts = nullptr; + timespec timeout; + if (uaddr2 != nullptr) { + auto result = ureadTimespec(timeout, (ptr)uaddr2); + if (result != ErrorCode{}) { + return result; + } + + ts = &timeout; + } + + return umtx_wait_uint_private(thread, obj, val, ts); + } case 16: - return umtx_wake_private(thread, obj, val, uaddr1, uaddr2); - case 17: - return umtx_wait_umutex(thread, obj, val, uaddr1, uaddr2); + return umtx_wake_private(thread, obj, val); + case 17: { + timespec *ts = nullptr; + timespec timeout; + if (uaddr2 != nullptr) { + auto result = ureadTimespec(timeout, (ptr)uaddr2); + if (result != ErrorCode{}) { + return result; + } + + ts = &timeout; + } + + return umtx_wait_umutex(thread, (ptr)obj, ts); + } case 18: return umtx_wake_umutex(thread, obj, val, uaddr1, uaddr2); case 19: @@ -55,7 +151,7 @@ orbis::SysResult orbis::sys__umtx_op(Thread *thread, ptr obj, sint op, case 20: return umtx_sem_wake(thread, obj, val, uaddr1, uaddr2); case 21: - return umtx_nwake_private(thread, obj, val, uaddr1, uaddr2); + return umtx_nwake_private(thread, obj, val); case 22: return umtx_wake2_umutex(thread, obj, val, uaddr1, uaddr2); } diff --git a/orbis-kernel/src/umtx.cpp b/orbis-kernel/src/umtx.cpp index 32d608d34..00728d532 100644 --- a/orbis-kernel/src/umtx.cpp +++ b/orbis-kernel/src/umtx.cpp @@ -1,74 +1,61 @@ #include "umtx.hpp" +#include "time.hpp" -orbis::ErrorCode orbis::umtx_lock_umtx(Thread *thread, ptr obj, - std::int64_t val, ptr uaddr1, - ptr uaddr2) { +orbis::ErrorCode orbis::umtx_lock_umtx(Thread *thread, ptr umtx, ulong id, + timespec *ts) { return ErrorCode::NOSYS; } -orbis::ErrorCode orbis::umtx_unlock_umtx(Thread *thread, ptr obj, - std::int64_t val, ptr uaddr1, - ptr uaddr2) { +orbis::ErrorCode orbis::umtx_unlock_umtx(Thread *thread, ptr umtx, + ulong id) { return ErrorCode::NOSYS; } -orbis::ErrorCode orbis::umtx_wait(Thread *thread, ptr obj, - std::int64_t val, ptr uaddr1, - ptr uaddr2) { +orbis::ErrorCode orbis::umtx_wait(Thread *thread, ptr addr, ulong id, + timespec *timeout) { return ErrorCode::NOSYS; } -orbis::ErrorCode orbis::umtx_wake(Thread *thread, ptr obj, - std::int64_t val, ptr uaddr1, - ptr uaddr2) { +orbis::ErrorCode orbis::umtx_wake(Thread *thread, ptr uaddr, + sint n_wake) { return ErrorCode::NOSYS; } -orbis::ErrorCode orbis::umtx_trylock_umutex(Thread *thread, ptr obj, - std::int64_t val, ptr uaddr1, - ptr uaddr2) { +orbis::ErrorCode orbis::umtx_trylock_umutex(Thread *thread, ptr m) { return ErrorCode::NOSYS; } -orbis::ErrorCode orbis::umtx_lock_umutex(Thread *thread, ptr obj, - std::int64_t val, ptr uaddr1, - ptr uaddr2) { +orbis::ErrorCode orbis::umtx_lock_umutex(Thread *thread, ptr m, + timespec *timeout) { return ErrorCode::NOSYS; } -orbis::ErrorCode orbis::umtx_unlock_umutex(Thread *thread, ptr obj, - std::int64_t val, ptr uaddr1, - ptr uaddr2) { +orbis::ErrorCode orbis::umtx_unlock_umutex(Thread *thread, ptr m) { return ErrorCode::NOSYS; } -orbis::ErrorCode orbis::umtx_set_ceiling(Thread *thread, ptr obj, - std::int64_t val, ptr uaddr1, - ptr uaddr2) { +orbis::ErrorCode orbis::umtx_set_ceiling(Thread *thread, ptr m, + std::uint32_t ceiling, + ptr oldCeiling) { return ErrorCode::NOSYS; } -orbis::ErrorCode orbis::umtx_cv_wait(Thread *thread, ptr obj, - std::int64_t val, ptr uaddr1, - ptr uaddr2) { +orbis::ErrorCode orbis::umtx_cv_wait(Thread *thread, ptr cv, + ptr m, timespec *ts, + ulong wflags) { return ErrorCode::NOSYS; } -orbis::ErrorCode orbis::umtx_cv_signal(Thread *thread, ptr obj, - std::int64_t val, ptr uaddr1, - ptr uaddr2) { +orbis::ErrorCode orbis::umtx_cv_signal(Thread *thread, ptr cv) { return ErrorCode::NOSYS; } -orbis::ErrorCode orbis::umtx_cv_broadcast(Thread *thread, ptr obj, - std::int64_t val, ptr uaddr1, - ptr uaddr2) { +orbis::ErrorCode orbis::umtx_cv_broadcast(Thread *thread, ptr cv) { return ErrorCode::NOSYS; } -orbis::ErrorCode orbis::umtx_wait_uint(Thread *thread, ptr obj, - std::int64_t val, ptr uaddr1, - ptr uaddr2) { +orbis::ErrorCode orbis::umtx_wait_uint(Thread *thread, ptr addr, ulong id, + timespec *timeout) { return ErrorCode::NOSYS; } @@ -90,22 +77,18 @@ orbis::ErrorCode orbis::umtx_rw_unlock(Thread *thread, ptr obj, return ErrorCode::NOSYS; } -orbis::ErrorCode orbis::umtx_wait_uint_private(Thread *thread, ptr obj, - std::int64_t val, - ptr uaddr1, - ptr uaddr2) { +orbis::ErrorCode orbis::umtx_wait_uint_private(Thread *thread, ptr addr, + ulong id, timespec *timeout) { return ErrorCode::NOSYS; } -orbis::ErrorCode orbis::umtx_wake_private(Thread *thread, ptr obj, - std::int64_t val, ptr uaddr1, - ptr uaddr2) { +orbis::ErrorCode orbis::umtx_wake_private(Thread *thread, ptr uaddr, + sint n_wake) { return ErrorCode::NOSYS; } -orbis::ErrorCode orbis::umtx_wait_umutex(Thread *thread, ptr obj, - std::int64_t val, ptr uaddr1, - ptr uaddr2) { +orbis::ErrorCode orbis::umtx_wait_umutex(Thread *thread, ptr m, + timespec *timeout) { return ErrorCode::NOSYS; } @@ -127,9 +110,8 @@ orbis::ErrorCode orbis::umtx_sem_wake(Thread *thread, ptr obj, return ErrorCode::NOSYS; } -orbis::ErrorCode orbis::umtx_nwake_private(Thread *thread, ptr obj, - std::int64_t val, ptr uaddr1, - ptr uaddr2) { +orbis::ErrorCode orbis::umtx_nwake_private(Thread *thread, ptr uaddrs, + std::int64_t count) { return ErrorCode::NOSYS; }