mirror of
https://github.com/wabbajack-tools/wabbajack.git
synced 2024-08-30 18:42:17 +00:00
Merge pull request #9 from halgari/issue-8
issue-8 - Fix PMap thread starvation
This commit is contained in:
commit
4a6b27eaea
@ -169,6 +169,8 @@ namespace Wabbajack.Common
|
|||||||
WorkQueue.MaxQueueSize = colllst.Count;
|
WorkQueue.MaxQueueSize = colllst.Count;
|
||||||
WorkQueue.CurrentQueueSize = 0;
|
WorkQueue.CurrentQueueSize = 0;
|
||||||
|
|
||||||
|
int remaining_tasks = colllst.Count;
|
||||||
|
|
||||||
var tasks = coll.Select(i =>
|
var tasks = coll.Select(i =>
|
||||||
{
|
{
|
||||||
TaskCompletionSource<TR> tc = new TaskCompletionSource<TR>();
|
TaskCompletionSource<TR> tc = new TaskCompletionSource<TR>();
|
||||||
@ -183,11 +185,22 @@ namespace Wabbajack.Common
|
|||||||
tc.SetException(ex);
|
tc.SetException(ex);
|
||||||
}
|
}
|
||||||
Interlocked.Increment(ref WorkQueue.CurrentQueueSize);
|
Interlocked.Increment(ref WorkQueue.CurrentQueueSize);
|
||||||
|
Interlocked.Decrement(ref remaining_tasks);
|
||||||
WorkQueue.ReportNow();
|
WorkQueue.ReportNow();
|
||||||
});
|
});
|
||||||
return tc.Task;
|
return tc.Task;
|
||||||
}).ToList();
|
}).ToList();
|
||||||
|
|
||||||
|
// To avoid thread starvation, we'll start to help out in the work queue
|
||||||
|
if (WorkQueue.WorkerThread)
|
||||||
|
while(remaining_tasks > 0)
|
||||||
|
{
|
||||||
|
if(WorkQueue.Queue.TryTake(out var a, 500))
|
||||||
|
{
|
||||||
|
a();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return tasks.Select(t =>
|
return tasks.Select(t =>
|
||||||
{
|
{
|
||||||
t.Wait();
|
t.Wait();
|
||||||
@ -199,29 +212,11 @@ namespace Wabbajack.Common
|
|||||||
|
|
||||||
public static void PMap<TI>(this IEnumerable<TI> coll, Action<TI> f)
|
public static void PMap<TI>(this IEnumerable<TI> coll, Action<TI> f)
|
||||||
{
|
{
|
||||||
var tasks = coll.Select(i =>
|
coll.PMap<TI, bool>(i =>
|
||||||
{
|
{
|
||||||
TaskCompletionSource<bool> tc = new TaskCompletionSource<bool>();
|
f(i);
|
||||||
WorkQueue.QueueTask(() =>
|
return false;
|
||||||
{
|
});
|
||||||
try
|
|
||||||
{
|
|
||||||
f(i);
|
|
||||||
tc.SetResult(true);
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
tc.SetException(ex);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return tc.Task;
|
|
||||||
}).ToList();
|
|
||||||
|
|
||||||
tasks.Select(t =>
|
|
||||||
{
|
|
||||||
t.Wait();
|
|
||||||
return t.Result;
|
|
||||||
}).ToList();
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -10,11 +10,14 @@ namespace Wabbajack.Common
|
|||||||
{
|
{
|
||||||
public class WorkQueue
|
public class WorkQueue
|
||||||
{
|
{
|
||||||
private static BlockingCollection<Action> Queue = new BlockingCollection<Action>();
|
internal static BlockingCollection<Action> Queue = new BlockingCollection<Action>();
|
||||||
|
|
||||||
[ThreadStatic]
|
[ThreadStatic]
|
||||||
private static int CpuId;
|
private static int CpuId;
|
||||||
|
|
||||||
|
[ThreadStatic]
|
||||||
|
internal static bool WorkerThread;
|
||||||
|
|
||||||
public static void Init(Action<int, string, int> report_function, Action<int, int> report_queue_size)
|
public static void Init(Action<int, string, int> report_function, Action<int, int> report_queue_size)
|
||||||
{
|
{
|
||||||
ReportFunction = report_function;
|
ReportFunction = report_function;
|
||||||
@ -40,6 +43,7 @@ namespace Wabbajack.Common
|
|||||||
private static void ThreadBody(int idx)
|
private static void ThreadBody(int idx)
|
||||||
{
|
{
|
||||||
CpuId = idx;
|
CpuId = idx;
|
||||||
|
WorkerThread = true;
|
||||||
|
|
||||||
while(true)
|
while(true)
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user