fix checking if there are pending jobs

This commit is contained in:
in0finite 2022-01-24 12:12:24 +01:00
parent 31a1a7a0a5
commit 37e73f5745
2 changed files with 31 additions and 13 deletions

View file

@ -332,8 +332,9 @@ namespace SanAndreasUnity.Editor
float diffPerc = endPerc - startPerc;
long initialNumPendingJobs = LoadingThread.Singleton.GetNumJobsPendingApproximately();
long initialNumPendingJobs = LoadingThread.Singleton.GetNumPendingJobs();
// TODO: this should be removed
yield return null; // this must be done, otherwise LoadingThread does not start processing any job
long numPendingJobs;
@ -341,7 +342,7 @@ namespace SanAndreasUnity.Editor
{
LoadingThread.Singleton.UpdateJobs();
numPendingJobs = LoadingThread.Singleton.GetNumJobsPendingApproximately();
numPendingJobs = LoadingThread.Singleton.GetNumPendingJobs();
long numJobsProcessed = initialNumPendingJobs - numPendingJobs;
float currentPerc = startPerc + diffPerc * (numJobsProcessed / (float)initialNumPendingJobs);

View file

@ -67,8 +67,10 @@ namespace SanAndreasUnity.Behaviours
private readonly ThreadParameters _threadParameters = new ThreadParameters();
private readonly Queue<Job<object>> _processedJobsBuffer = new Queue<Job<object>>(256);
private static long s_lastJobId = 0;
private static readonly object s_lastJobIdLockObject = new object();
private long _lastJobId = 0;
private readonly object _lastJobIdLockObject = new object();
private long _lastProcessedJobId = 0;
private readonly Stopwatch _stopwatch = new Stopwatch();
@ -170,6 +172,8 @@ namespace SanAndreasUnity.Behaviours
// invoke finish callback
if (job.callbackFinish != null)
F.RunExceptionSafe (() => job.callbackFinish (job.result));
_lastProcessedJobId = job.id;
}
}
@ -195,7 +199,6 @@ namespace SanAndreasUnity.Behaviours
job.exception = null;
var j = new Job<object> () {
id = GetNextJobId(),
priority = job.priority,
action = () => job.action(),
callbackError = job.callbackError,
@ -205,14 +208,12 @@ namespace SanAndreasUnity.Behaviours
if(job.callbackFinish != null)
j.callbackFinish = (arg) => job.callbackFinish( (T) arg );
_threadParameters.jobs.Add (j);
}
static long GetNextJobId()
{
lock (s_lastJobIdLockObject)
{
return ++s_lastJobId;
lock (_lastJobIdLockObject)
// make sure that changing id and adding new job is atomic operation, otherwise
// multiple threads accessing this part of code can cause the jobs to be inserted out of order
{
j.id = ++_lastJobId;
_threadParameters.jobs.Add(j);
}
}
@ -224,6 +225,22 @@ namespace SanAndreasUnity.Behaviours
return (long)_threadParameters.jobs.Count + (long)_threadParameters.processedJobs.Count + (long)_processedJobsBuffer.Count;
}
public long GetNumPendingJobs()
{
// this will not work if collections used are not FIFO collections (eg. other than queues)
// - this will be the case if job priority is used
ThreadHelper.ThrowIfNotOnMainThread();
lock (_lastJobIdLockObject)
{
if (_lastProcessedJobId > _lastJobId)
throw new Exception($"Last processed job id ({_lastProcessedJobId}) is higher than last registered job id ({_lastJobId}). This should not happen.");
return _lastJobId - _lastProcessedJobId;
}
}
static void ThreadFunction (object objectParameter)
{
ThreadParameters threadParameters = (ThreadParameters) objectParameter;