[Pthread] implement scePthreadCondSignalto

This commit is contained in:
ParantezTech 2026-09-22 03:07:29 +03:00
parent acbf28c784
commit 2a27cfe8be
1 changed files with 59 additions and 0 deletions

View File

@ -515,6 +515,14 @@ public static class KernelPthreadCompatExports
LibraryName = "libKernel")]
public static int PthreadCondSignal(CpuContext ctx) => PthreadCondSignalCore(ctx, ctx[CpuRegister.Rdi], broadcast: false);
[SysAbiExport(
Nid = "o69RpYO-Mu0",
ExportName = "scePthreadCondSignalto",
Target = Generation.Gen4 | Generation.Gen5,
LibraryName = "libKernel")]
public static int PthreadCondSignalto(CpuContext ctx) =>
PthreadCondSignalToCore(ctx, ctx[CpuRegister.Rdi], ctx[CpuRegister.Rsi]);
[SysAbiExport(
Nid = "JGgj7Uvrl+A",
ExportName = "scePthreadCondBroadcast",
@ -2060,6 +2068,57 @@ public static class KernelPthreadCompatExports
return (int)OrbisGen2Result.ORBIS_GEN2_OK;
}
private static int PthreadCondSignalToCore(CpuContext ctx, ulong condAddress, ulong threadId)
{
if (threadId == 0)
{
return PthreadCondSignalCore(ctx, condAddress, broadcast: false);
}
if (condAddress == 0)
{
return (int)OrbisGen2Result.ORBIS_GEN2_ERROR_INVALID_ARGUMENT;
}
if (!TryResolveCondState(ctx, condAddress, createIfZero: true, out _, out var state))
{
return (int)OrbisGen2Result.ORBIS_GEN2_ERROR_NOT_FOUND;
}
PthreadCondWaiter? completedWaiter = null;
lock (state.SyncRoot)
{
state.SignalEpoch++;
for (var node = state.WaiterQueue.First; node is not null; node = node.Next)
{
var waiter = node.Value;
if (waiter.ThreadId != threadId ||
waiter.CompletionState != 0 ||
!CompleteCondWaiterLocked(state, waiter, timedOut: false))
{
continue;
}
completedWaiter = waiter;
break;
}
TracePthreadCond("signalto", condAddress, mutexAddress: 0, state, timed: false,
completedWaiter is null ? 1 : (int)OrbisGen2Result.ORBIS_GEN2_OK);
}
if (completedWaiter is null)
{
// Matches pthread_cond_signalto_np: a valid target that is not
// currently waiting on this condition returns EPERM (1), which
// the Orbis wrapper maps to its kernel error form.
return (int)OrbisGen2Result.ORBIS_GEN2_ERROR_PERMISSION_DENIED;
}
WakeCooperativeWaiter(completedWaiter);
return (int)OrbisGen2Result.ORBIS_GEN2_OK;
}
private static PthreadMutexWaiter EnqueueMutexWaiterLocked(
PthreadMutexState state,
ulong threadId,