Merge pull request #2118 from rozbh/feat/libkernel-aio-poll-requests
feat(libkernel): implement sceKernelAioPollRequests
This commit is contained in:
commit
416e40ef29
|
|
@ -305,8 +305,11 @@ int APS5_VABI sceKernelAioWaitRequest(int32_t id, int32_t* state, uint32_t* usec
|
|||
}
|
||||
}
|
||||
|
||||
int APS5_VABI sceKernelAioPollRequests() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
int APS5_VABI sceKernelAioPollRequests(int32_t* id, int32_t num, int32_t* state) {
|
||||
const int error = ValidateIds(id, num, state, "sceKernelAioPollRequests");
|
||||
if (error != 0) return error;
|
||||
std::lock_guard<std::mutex> lock(g_mutex);
|
||||
for (int32_t i = 0; i < num; ++i) state[i] = g_states[id[i]];
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@ int APS5_VABI sceKernelAioWaitRequest(std::int32_t id, std::int32_t* state, std:
|
|||
int APS5_VABI sceKernelAioSubmitReadCommandsMultiple(KernelAioRwRequest* req, std::int32_t size, std::int32_t prio, std::int32_t* id);
|
||||
int APS5_VABI sceKernelAioSubmitWriteCommandsMultiple(KernelAioRwRequest* req, std::int32_t size, std::int32_t prio, std::int32_t* id);
|
||||
int APS5_VABI sceKernelAioWaitRequests(std::int32_t* id, std::int32_t num, std::int32_t* state, std::uint32_t mode, std::uint32_t* usec);
|
||||
int APS5_VABI sceKernelAioPollRequests(std::int32_t* id, std::int32_t num, std::int32_t* state);
|
||||
int APS5_VABI sceKernelAioCancelRequest(std::int32_t id, std::int32_t* state);
|
||||
int APS5_VABI sceKernelAioCancelRequests(std::int32_t* id, std::int32_t num, std::int32_t* state);
|
||||
int APS5_VABI sceKernelAioDeleteRequests(std::int32_t* id, std::int32_t num, std::int32_t* ret);
|
||||
|
|
@ -113,6 +114,9 @@ int main() {
|
|||
std::int32_t writeStates[2] = {0, 0};
|
||||
Check(sceKernelAioWaitRequests(writeIds, 2, writeStates, 1, nullptr) == 0);
|
||||
Check(writeStates[0] == 3 && writeStates[1] == 4);
|
||||
std::int32_t polledStates[2] = {0, 0};
|
||||
Check(sceKernelAioPollRequests(writeIds, 2, polledStates) == 0);
|
||||
Check(polledStates[0] == 3 && polledStates[1] == 4);
|
||||
std::array<char, 4> readBack{};
|
||||
std::array<char, 4> tail{};
|
||||
KernelAioResult readBackResult{-1, 0};
|
||||
|
|
@ -145,6 +149,8 @@ int main() {
|
|||
Check(cancelStates[0] == 2 && cancelStates[1] == 4);
|
||||
Check(sceKernelAioPollRequest(readIds[1], &polled) == 0);
|
||||
Check(polled == 4);
|
||||
Check(sceKernelAioPollRequests(readIds, 2, polledStates) == 0);
|
||||
Check(polledStates[0] == 4 && polledStates[1] == 4);
|
||||
std::int32_t deletedRets[2] = {-1, -1};
|
||||
Check(sceKernelAioDeleteRequests(writeIds, 2, deletedRets) == 0);
|
||||
Check(deletedRets[0] == 0 && deletedRets[1] == 0);
|
||||
|
|
@ -164,6 +170,13 @@ int main() {
|
|||
Check(sceKernelAioWaitRequests(readIds, -1, readStates, 1, nullptr) == SCE_KERNEL_ERROR_EINVAL);
|
||||
Check(sceKernelAioWaitRequests(badIds, 2, untouched, 1, nullptr) == SCE_KERNEL_ERROR_EINVAL);
|
||||
Check(untouched[0] == 7 && untouched[1] == 7);
|
||||
Check(sceKernelAioPollRequests(readIds, 2, nullptr) == SCE_KERNEL_ERROR_EFAULT);
|
||||
Check(sceKernelAioPollRequests(nullptr, 2, readStates) == SCE_KERNEL_ERROR_EFAULT);
|
||||
Check(sceKernelAioPollRequests(readIds, -1, readStates) == SCE_KERNEL_ERROR_EINVAL);
|
||||
Check(sceKernelAioPollRequests(badIds, 2, untouched) == SCE_KERNEL_ERROR_EINVAL);
|
||||
Check(untouched[0] == 7 && untouched[1] == 7);
|
||||
Check(sceKernelAioPollRequests(readIds, 0, untouched) == 0);
|
||||
Check(untouched[0] == 7 && untouched[1] == 7);
|
||||
bool threw = false;
|
||||
try { sceKernelAioWaitRequests(readIds, 2, readStates, 3, nullptr); } catch (const std::runtime_error&) { threw = true; }
|
||||
Check(threw);
|
||||
|
|
@ -173,6 +186,9 @@ int main() {
|
|||
manyIds.fill(readIds[0]);
|
||||
try { sceKernelAioDeleteRequests(manyIds.data(), 129, manyStates.data()); } catch (const std::runtime_error&) { threw = true; }
|
||||
Check(threw);
|
||||
threw = false;
|
||||
try { sceKernelAioPollRequests(manyIds.data(), 129, manyStates.data()); } catch (const std::runtime_error&) { threw = true; }
|
||||
Check(threw);
|
||||
Check(sceKernelAioCancelRequest(9999, &cancelled) == SCE_KERNEL_ERROR_EINVAL);
|
||||
Check(sceKernelAioCancelRequest(readIds[0], nullptr) == SCE_KERNEL_ERROR_EFAULT);
|
||||
Check(sceKernelAioCancelRequests(badIds, 2, untouched) == SCE_KERNEL_ERROR_EINVAL);
|
||||
|
|
|
|||
|
|
@ -128,7 +128,7 @@ Throughout the project, every function at every stage either **does exactly what
|
|||
- [sceKernelSyncOnAddressWait](../../core/libs/prx/libkernel/SyncOnAddress/src/SyncOnAddress.cpp) (libkernel) - the only known caller passes a null timeout and a name string as the fourth argument; the timeout is assumed to point to microseconds like the other kernel waits, and the name is ignored
|
||||
- [sceKernelSyncOnAddressWait8 / sceKernelSyncOnAddressWait16 / sceKernelSyncOnAddressWait32 / sceKernelSyncOnAddressWait64](../../core/libs/prx/libkernel/SyncOnAddress/src/SyncOnAddress.cpp) (libkernel) - libc's `__std_atomic_wait_direct_8/16/32/64` pass a microsecond timeout or null and ignore the result; the by-value comparand, return values and the 2- and 8-byte alignment of Wait16 and Wait64 are assumed
|
||||
- [scePthreadCondWait / scePthreadCondTimedwait](../../core/libs/prx/libkernel/Pthread/src/Cond.cpp) (libkernel) - a recursive mutex locked several times is released completely for the wait and relocked to the same depth afterwards, as FreeBSD libthr does (`_mutex_cv_unlock`, `_mutex_cv_lock`); unverified on hardware
|
||||
- [sceKernelAioSubmitReadCommandsMultiple / sceKernelAioSubmitWriteCommandsMultiple / sceKernelAioWaitRequests / sceKernelAioCancelRequest / sceKernelAioCancelRequests / sceKernelAioDeleteRequests](../../core/libs/prx/libkernel/Aio/src/Aio.cpp) (libkernel) - behaviour from shadPS4 (one id per request for the Multiple submits, cancel turns any request aborted and id 0 reports processing, wait mode 2 returns once one request completed); the 128 requests or ids per batch limit is from SharpProspero, with an unknown error, so larger batches throw; wait modes other than 1 (and) and 2 (or) throw; null pointers, negative counts and invalid ids return the codes the single-request siblings use, checked before any state is written
|
||||
- [sceKernelAioSubmitReadCommandsMultiple / sceKernelAioSubmitWriteCommandsMultiple / sceKernelAioWaitRequests / sceKernelAioPollRequests / sceKernelAioCancelRequest / sceKernelAioCancelRequests / sceKernelAioDeleteRequests](../../core/libs/prx/libkernel/Aio/src/Aio.cpp) (libkernel) - behaviour from shadPS4 (one id per request for the Multiple submits, cancel turns any request aborted and id 0 reports processing, wait mode 2 returns once one request completed, poll copies every state without waiting); the 128 requests or ids per batch limit is from SharpProspero, with an unknown error, so larger batches throw; wait modes other than 1 (and) and 2 (or) throw; null pointers, negative counts and invalid ids return the codes the single-request siblings use, checked before any state is written
|
||||
- [sceKernelGetAvailableCpumask](../../core/libs/prx/libkernel/Pthread/src/Thread.cpp) (libkernel) - returns the default thread affinity, 0x1FFF (CPUs 0 to 12), as KytyPS5 does. Titles pin threads within it (PPSA02664 passes 0x1FFB, Hades II PPSA36082 0x3 and 0x3F); whether CPU 13 is available to a title is not confirmed
|
||||
- [sceKernelGetCurrentCpu](../../core/libs/prx/libkernel/System/src/Process.cpp) (libkernel) - guest affinities are not applied to host threads, so the host CPU index is mapped into the calling thread's affinity clipped to `sceKernelGetAvailableCpumask` (the available mask when they do not overlap): host CPU n reports the (n modulo the CPU count)-th CPU of that mask, so a thread pinned to one CPU reports that CPU, as a FreeBSD `cpuset` guarantees on the console. Which CPU the console reports for a thread allowed on several is not known; shadPS4 returns 0
|
||||
- [sceKernelMapNamedFlexibleMemoryInternal](../../core/libs/prx/libkernel/DirectMemory/Export.cpp) (libkernel) - flag 0x8000 is accepted and ignored; its meaning is not established. KytyPS5 (`GUEST_MAP_UNKNOWN_8000`) and sharpemu accept it without reading it. Every known caller is the SDK 9 `libc.prx` heap (Astro Bot PPSA21564, PPSA22520), which passes it with read/write protection and uses the mapping as an older `libc.prx` uses `sceKernelMapNamedFlexibleMemory` with flags 0
|
||||
|
|
|
|||
Loading…
Reference in New Issue