Merge pull request #4004 from zmeizy/claude/mutex-timedlock-try-first
fix(libkernel): try the lock before checking the pthread_mutex_timedl…
This commit is contained in:
commit
ddc713fbcf
|
|
@ -6,14 +6,13 @@
|
|||
#include "../include/Mutex.hpp"
|
||||
#include "Common.hpp"
|
||||
#include <atomic>
|
||||
#include <chrono>
|
||||
#include <limits>
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
|
||||
namespace {
|
||||
|
||||
constexpr int POSIX_EINVAL = 22;
|
||||
constexpr int GUEST_REALTIME_CLOCK = 0;
|
||||
constexpr int POSIX_PRIO_PROTECT = 2;
|
||||
constexpr int POSIX_SCHED_RR = 3;
|
||||
constexpr std::uintptr_t POSIX_ADAPTIVE_MUTEX_INITIALIZER = 1;
|
||||
|
|
@ -62,12 +61,10 @@ int APS5_VABI pthread_mutex_lock_nid_postfix(PthreadMutex* mutex) {
|
|||
|
||||
int APS5_VABI pthread_mutex_timedlock_nid_postfix(PthreadMutex* mutex, const KernelTimespec* abstime) {
|
||||
if (!abstime) throw std::runtime_error("pthread_mutex_timedlock: null abstime");
|
||||
if (abstime->tv_nsec < 0 || abstime->tv_nsec >= 1000000000) return POSIX_EINVAL;
|
||||
_initializeStatic(mutex, __func__);
|
||||
const auto deadline = std::chrono::seconds(abstime->tv_sec) + std::chrono::nanoseconds(abstime->tv_nsec);
|
||||
const auto now = std::chrono::system_clock::now().time_since_epoch();
|
||||
const auto remaining = std::chrono::duration_cast<std::chrono::microseconds>(deadline - now).count();
|
||||
const auto usec = remaining <= 0 ? 0 : remaining >= std::numeric_limits<KernelUseconds>::max() ? std::numeric_limits<KernelUseconds>::max() : static_cast<KernelUseconds>(remaining);
|
||||
if (scePthreadMutexTrylock(mutex) == 0) return 0;
|
||||
KernelUseconds usec = 0;
|
||||
if (!PosixThread::RelativeMicroseconds(GUEST_REALTIME_CLOCK, abstime, &usec)) return POSIX_EINVAL;
|
||||
return PosixThread::ToErrno(scePthreadMutexTimedlock(mutex, usec));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
#include "SceTypes.hpp"
|
||||
#include <cstdint>
|
||||
#include <cstdlib>
|
||||
#include <stdexcept>
|
||||
|
||||
|
|
@ -14,6 +15,9 @@ int APS5_VABI pthread_mutex_init_nid_postfix(PthreadMutex* mutex, const PthreadM
|
|||
int APS5_VABI pthread_mutex_lock_nid_postfix(PthreadMutex* mutex);
|
||||
int APS5_VABI pthread_mutex_unlock_nid_postfix(PthreadMutex* mutex);
|
||||
int APS5_VABI pthread_mutex_destroy_nid_postfix(PthreadMutex* mutex);
|
||||
int APS5_VABI pthread_mutex_timedlock_nid_postfix(PthreadMutex* mutex, const KernelTimespec* abstime);
|
||||
int APS5_VABI scePthreadCreate(Pthread* thread, const PthreadAttr* attr, PthreadEntry entry, void* arg, const char* name);
|
||||
int APS5_VABI scePthreadJoin(Pthread thread, void** retval);
|
||||
int APS5_VABI sched_get_priority_max_nid_postfix(int policy);
|
||||
}
|
||||
|
||||
|
|
@ -35,6 +39,25 @@ static bool Throws(Call call) {
|
|||
return false;
|
||||
}
|
||||
|
||||
static constexpr KernelTimespec INVALID_DEADLINE{0, 1000000000};
|
||||
|
||||
static void* APS5_VABI TimedlockInvalidDeadline(void* arg) {
|
||||
auto* mutex = static_cast<PthreadMutex*>(arg);
|
||||
return reinterpret_cast<void*>(static_cast<std::intptr_t>(pthread_mutex_timedlock_nid_postfix(mutex, &INVALID_DEADLINE)));
|
||||
}
|
||||
|
||||
static void CheckTimedlockInvalidDeadline() {
|
||||
PthreadMutex mutex = nullptr;
|
||||
Require(pthread_mutex_init_nid_postfix(&mutex, nullptr) == 0);
|
||||
Require(pthread_mutex_timedlock_nid_postfix(&mutex, &INVALID_DEADLINE) == 0);
|
||||
Pthread thread{};
|
||||
void* result = nullptr;
|
||||
Require(scePthreadCreate(&thread, nullptr, TimedlockInvalidDeadline, &mutex, nullptr) == 0);
|
||||
Require(scePthreadJoin(thread, &result) == 0 && reinterpret_cast<std::intptr_t>(result) == GUEST_EINVAL);
|
||||
Require(pthread_mutex_unlock_nid_postfix(&mutex) == 0);
|
||||
Require(pthread_mutex_destroy_nid_postfix(&mutex) == 0);
|
||||
}
|
||||
|
||||
static void CheckType() {
|
||||
PthreadMutexattr attr = nullptr;
|
||||
Require(pthread_mutexattr_init_nid_postfix(&attr) == 0);
|
||||
|
|
@ -55,6 +78,7 @@ static void CheckType() {
|
|||
|
||||
int main() {
|
||||
CheckType();
|
||||
CheckTimedlockInvalidDeadline();
|
||||
PthreadMutexattr attr = nullptr;
|
||||
Require(pthread_mutexattr_init_nid_postfix(&attr) == 0);
|
||||
int ceiling = -1;
|
||||
|
|
|
|||
Loading…
Reference in New Issue