Skip to content

Commit 71689f6

Browse files
committed
Change: Attempt to tune threading a bit
#1050
1 parent 2539167 commit 71689f6

File tree

2 files changed

+34
-50
lines changed

2 files changed

+34
-50
lines changed

source/OpenBVE/System/GameWindow.cs

+17-26
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using System;
2+
using System.Collections.Concurrent;
23
using System.Collections.Generic;
34
using System.ComponentModel;
45
using System.Diagnostics;
@@ -394,8 +395,7 @@ protected override void OnLoad(EventArgs e)
394395
}
395396
Program.FileSystem.AppendToLogFile("Game window initialised successfully.");
396397
//Initialise the loader thread queues
397-
jobs = new Queue<ThreadStart>(10);
398-
locks = new Queue<object>(10);
398+
jobs = new ConcurrentQueue<ThreadStart>();
399399
Program.Renderer.Initialize();
400400
Program.Renderer.DetermineMaxAFLevel();
401401
Interface.CurrentOptions.Save(OpenBveApi.Path.CombineFile(Program.FileSystem.SettingsFolder, "1.5.0/options.cfg"));
@@ -1126,18 +1126,15 @@ public void LoadingScreenLoop()
11261126

11271127
if (Loading.JobAvailable)
11281128
{
1129-
while (jobs.Count > 0)
1129+
while (!jobs.IsEmpty)
11301130
{
1131-
lock (jobLock)
1131+
jobs.TryDequeue(out ThreadStart currentJob);
1132+
currentJob();
1133+
lock (currentJob)
11321134
{
1133-
var currentJob = jobs.Dequeue();
1134-
var locker = locks.Dequeue();
1135-
currentJob();
1136-
lock (locker)
1137-
{
1138-
Monitor.Pulse(locker);
1139-
}
1135+
Monitor.Pulse(currentJob);
11401136
}
1137+
11411138
}
11421139
Loading.JobAvailable = false;
11431140
}
@@ -1156,28 +1153,22 @@ public void LoadingScreenLoop()
11561153
}
11571154
}
11581155

1159-
private static readonly object jobLock = new object();
1160-
private static Queue<ThreadStart> jobs;
1161-
private static Queue<object> locks;
1156+
private static ConcurrentQueue<ThreadStart> jobs;
11621157

11631158
/// <summary>This method is used during loading to run commands requiring an OpenGL context in the main render loop</summary>
11641159
/// <param name="job">The OpenGL command</param>
11651160
/// <param name="timeout">The timeout</param>
11661161
internal static void RunInRenderThread(ThreadStart job, int timeout)
11671162
{
11681163
object locker = new object();
1169-
lock (jobLock)
1170-
{
1171-
jobs.Enqueue(job);
1172-
locks.Enqueue(locker);
1173-
//Don't set the job to available until after it's been loaded into the queue
1174-
Loading.JobAvailable = true;
1175-
}
1176-
lock (locker)
1177-
{
1178-
//Failsafe: If our job has taken more than the timeout, stop waiting for it
1179-
//A missing texture is probably better than an infinite loadscreen
1180-
Monitor.Wait(locker, timeout);
1164+
jobs.Enqueue(job);
1165+
//Don't set the job to available until after it's been loaded into the queue
1166+
Loading.JobAvailable = true;
1167+
//Failsafe: If our job has taken more than the timeout, stop waiting for it
1168+
//A missing texture is probably better than an infinite loadscreen
1169+
lock (job)
1170+
{
1171+
Monitor.Wait(job, timeout);
11811172
}
11821173
}
11831174
}

source/RouteViewer/System/Gamewindow.cs

+17-24
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using System;
2+
using System.Collections.Concurrent;
23
using System.Collections.Generic;
34
using System.ComponentModel;
45
using System.Threading;
@@ -152,15 +153,11 @@ public static void LoadingScreenLoop()
152153
{
153154
while (jobs.Count > 0)
154155
{
155-
lock (jobLock)
156+
jobs.TryDequeue(out ThreadStart currentJob);
157+
currentJob();
158+
lock (currentJob)
156159
{
157-
var currentJob = jobs.Dequeue();
158-
var locker = locks.Dequeue();
159-
currentJob();
160-
lock (locker)
161-
{
162-
Monitor.Pulse(locker);
163-
}
160+
Monitor.Pulse(currentJob);
164161
}
165162
}
166163
Loading.JobAvailable = false;
@@ -184,29 +181,25 @@ public static void LoadingScreenLoop()
184181
}
185182
}
186183

187-
internal static readonly object LoadingLock = new object();
188-
189-
private static readonly object jobLock = new object();
190184
#pragma warning disable 0649
191-
private static Queue<ThreadStart> jobs;
192-
private static Queue<object> locks;
193-
#pragma warning restore 0649
185+
private static ConcurrentQueue<ThreadStart> jobs;
186+
#pragma warning enable 0649
194187

195188
/// <summary>This method is used during loading to run commands requiring an OpenGL context in the main render loop</summary>
196189
/// <param name="job">The OpenGL command</param>
197-
internal static void RunInRenderThread(ThreadStart job)
190+
/// <param name="timeout">The timeout</param>
191+
internal static void RunInRenderThread(ThreadStart job, int timeout)
198192
{
199193
object locker = new object();
200-
lock (jobLock)
201-
{
202-
Loading.JobAvailable = true;
203-
jobs.Enqueue(job);
204-
locks.Enqueue(locker);
205-
}
206-
lock (locker)
194+
jobs.Enqueue(job);
195+
//Don't set the job to available until after it's been loaded into the queue
196+
Loading.JobAvailable = true;
197+
//Failsafe: If our job has taken more than the timeout, stop waiting for it
198+
//A missing texture is probably better than an infinite loadscreen
199+
lock (job)
207200
{
208-
Monitor.Wait(locker);
201+
Monitor.Wait(job, timeout);
209202
}
210203
}
211-
}
204+
}
212205
}

0 commit comments

Comments
 (0)