feat(job): fixed the deadlock issue in job system.

This commit is contained in:
2026-05-02 18:37:30 +09:00
parent 1b22b2a308
commit 6f24a0aefa
2 changed files with 55 additions and 20 deletions

View File

@@ -239,11 +239,25 @@ public sealed unsafe partial class JobScheduler : IDisposable
// Ensure the count of this job handle won't exceed the number of worker threads.
// Worker threads will steal parallel iteration ranges from each other.
var handleCount = Math.Min(jobInfo.jobRanges.TotalBatches, _workerThreads.Length);
var initialState = JobUtility.JOBSTATE_SCHEDULED | (handleCount * JobUtility.RC_ONE);
if (Interlocked.CompareExchange(ref jobInfo.state, initialState, JobUtility.JOBSTATE_CREATED) != JobUtility.JOBSTATE_CREATED)
var spin = new SpinWait();
while (true)
{
return;
var currentState = Volatile.Read(ref jobInfo.state);
if (JobUtility.GetState(currentState) != JobState.Created)
{
return;
}
var newState = (currentState & ~JobUtility.STATE_MASK) | JobUtility.JOBSTATE_SCHEDULED;
newState += handleCount * JobUtility.RC_ONE;
if (Interlocked.CompareExchange(ref jobInfo.state, newState, currentState) == currentState)
{
break;
}
spin.SpinOnce(-1);
}
var tier = (int)jobInfo.priority;
@@ -361,6 +375,11 @@ public sealed unsafe partial class JobScheduler : IDisposable
break;
}
if (state != JobState.Created && JobUtility.GetRefCount(stateVal) == 0)
{
break;
}
// Attempt to increment RC (Reader Count)
if (Interlocked.CompareExchange(ref depJobInfo.state, stateVal + JobUtility.RC_ONE, stateVal) == stateVal)
{
@@ -381,7 +400,11 @@ public sealed unsafe partial class JobScheduler : IDisposable
while (Interlocked.CompareExchange(ref depJobInfo.firstDependentEdgeIndex, newEdgeIndex, currentFirst) != currentFirst);
// Release RC
Interlocked.Add(ref depJobInfo.state, -JobUtility.RC_ONE);
var newState = Interlocked.Add(ref depJobInfo.state, -JobUtility.RC_ONE);
if (JobUtility.GetRefCount(newState) == 0 && JobUtility.GetState(newState) != JobState.Created)
{
MarkJobComplete(dependency);
}
registered = true;