mirror of
https://github.com/par274/sharpemu.git
synced 2026-08-18 15:31:31 +08:00
[Kernel] Implement clock_getres and the POSIX pthread_once alias
clock_getres (smIj7eqzZE8) was missing entirely. It reports 100ns, which is the resolution clock_gettime here actually delivers via DateTimeOffset.UtcNow, rather than claiming the 1ns a caller might otherwise rely on. A null res pointer is accepted per POSIX. pthread_once (Z4QosVuAsA0) needed no new logic: libKernel exports the same routine under two NIDs and only scePthreadOnce (14bOACANTBo) was registered. Shipped middleware links the plain name. Both are imported by DOOM + DOOM II (PPSA21444): clock_getres blocked party.prx from initialising, and pthread_once is used by libcohtml, libPlayFabMultiplayer, party.prx and the eboot. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -2327,6 +2327,37 @@ public static partial class KernelMemoryCompatExports
|
|||||||
return (int)OrbisGen2Result.ORBIS_GEN2_OK;
|
return (int)OrbisGen2Result.ORBIS_GEN2_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[SysAbiExport(
|
||||||
|
Nid = "smIj7eqzZE8",
|
||||||
|
ExportName = "clock_getres",
|
||||||
|
Target = Generation.Gen4 | Generation.Gen5,
|
||||||
|
LibraryName = "libKernel")]
|
||||||
|
public static int ClockGetres(CpuContext ctx)
|
||||||
|
{
|
||||||
|
var timespecAddress = ctx[CpuRegister.Rsi];
|
||||||
|
|
||||||
|
// POSIX allows a null resolution pointer: the call then only validates
|
||||||
|
// the clock id, which every id a title passes here does.
|
||||||
|
if (timespecAddress == 0)
|
||||||
|
{
|
||||||
|
ctx[CpuRegister.Rax] = 0;
|
||||||
|
return (int)OrbisGen2Result.ORBIS_GEN2_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
// clock_gettime above is backed by DateTimeOffset.UtcNow, whose tick is
|
||||||
|
// 100 ns, so that is the honest resolution to report rather than the 1 ns
|
||||||
|
// a caller might otherwise assume it can rely on.
|
||||||
|
const ulong ResolutionNanoseconds = 100;
|
||||||
|
if (!ctx.TryWriteUInt64(timespecAddress, 0) ||
|
||||||
|
!ctx.TryWriteUInt64(timespecAddress + sizeof(long), ResolutionNanoseconds))
|
||||||
|
{
|
||||||
|
return (int)OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT;
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx[CpuRegister.Rax] = 0;
|
||||||
|
return (int)OrbisGen2Result.ORBIS_GEN2_OK;
|
||||||
|
}
|
||||||
|
|
||||||
[SysAbiExport(
|
[SysAbiExport(
|
||||||
Nid = "vNe1w4diLCs",
|
Nid = "vNe1w4diLCs",
|
||||||
ExportName = "__tls_get_addr",
|
ExportName = "__tls_get_addr",
|
||||||
|
|||||||
@@ -578,6 +578,19 @@ public static class KernelPthreadCompatExports
|
|||||||
return SetReturn(ctx, OrbisGen2Result.ORBIS_GEN2_OK);
|
return SetReturn(ctx, OrbisGen2Result.ORBIS_GEN2_OK);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The POSIX-named alias of <see cref="PthreadOnce"/>. libKernel exports the
|
||||||
|
/// same routine under two NIDs, and shipped middleware links the plain name:
|
||||||
|
/// DOOM's libcohtml, PlayFab and party modules all import this one rather
|
||||||
|
/// than scePthreadOnce.
|
||||||
|
/// </summary>
|
||||||
|
[SysAbiExport(
|
||||||
|
Nid = "Z4QosVuAsA0",
|
||||||
|
ExportName = "pthread_once",
|
||||||
|
Target = Generation.Gen4 | Generation.Gen5,
|
||||||
|
LibraryName = "libKernel")]
|
||||||
|
public static int PthreadOncePOSIX(CpuContext ctx) => PthreadOnce(ctx);
|
||||||
|
|
||||||
private static int PthreadMutexInitCore(CpuContext ctx, ulong mutexAddress, ulong attrAddress)
|
private static int PthreadMutexInitCore(CpuContext ctx, ulong mutexAddress, ulong attrAddress)
|
||||||
{
|
{
|
||||||
if (mutexAddress == 0)
|
if (mutexAddress == 0)
|
||||||
|
|||||||
Reference in New Issue
Block a user