-
Notifications
You must be signed in to change notification settings - Fork 716
Let caches clear and code commit in background #9012
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from 4 commits
9a92ec5
3441de1
ac6057e
f135bdc
d6e35c9
1478a28
eb6470e
668fc49
c9e7c0b
646d1e6
fd5b1b5
5f4f847
181a0a4
c9d4db3
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -2,6 +2,7 @@ | |
| // SPDX-License-Identifier: LGPL-3.0-only | ||
|
|
||
| using System; | ||
| using System.Runtime.ExceptionServices; | ||
| using System.Runtime.InteropServices; | ||
| using System.Threading; | ||
| using System.Threading.Tasks; | ||
|
|
@@ -20,6 +21,7 @@ public class ParallelUnbalancedWork : IThreadPoolWorkItem | |
| }; | ||
|
|
||
| private readonly Data _data; | ||
| private ExceptionDispatchInfo? _exception; | ||
|
|
||
| /// <summary> | ||
| /// Executes a parallel for loop over a range of integers. | ||
|
|
@@ -43,19 +45,28 @@ public static void For(int fromInclusive, int toExclusive, ParallelOptions paral | |
|
|
||
| Data data = new(threads, fromInclusive, toExclusive, action, parallelOptions.CancellationToken); | ||
|
|
||
| for (int i = 0; i < threads - 1; i++) | ||
| // Queue work items to the thread pool for all threads except the current one | ||
| var tasks = new ParallelUnbalancedWork[threads - 1]; | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ArrayPool? |
||
| for (int i = 0; i < tasks.Length; i++) | ||
| { | ||
| ThreadPool.UnsafeQueueUserWorkItem(new ParallelUnbalancedWork(data), preferLocal: false); | ||
| ThreadPool.UnsafeQueueUserWorkItem((tasks[i] = new ParallelUnbalancedWork(data)), preferLocal: false); | ||
| } | ||
|
|
||
| new ParallelUnbalancedWork(data).Execute(); | ||
| var task = new ParallelUnbalancedWork(data); | ||
| task.Execute(); | ||
|
|
||
| // If there are still active threads, wait for them to complete | ||
| if (data.ActiveThreads > 0) | ||
| { | ||
| data.Event.Wait(); | ||
| } | ||
|
|
||
| task._exception?.Throw(); | ||
| for (int i = 0; i < tasks.Length; i++) | ||
| { | ||
| tasks[i]._exception?.Throw(); | ||
| } | ||
|
|
||
| parallelOptions.CancellationToken.ThrowIfCancellationRequested(); | ||
| } | ||
|
|
||
|
|
@@ -150,6 +161,13 @@ public void Execute() | |
| i = _data.Index.GetNext(); | ||
| } | ||
| } | ||
| catch (Exception ex) | ||
| { | ||
| if (ex is not OperationCanceledException) | ||
| { | ||
| _exception = ExceptionDispatchInfo.Capture(ex); | ||
| } | ||
| } | ||
| finally | ||
| { | ||
| // Signal that this thread has completed its work | ||
|
|
@@ -237,6 +255,7 @@ private class Data(int threads, int fromInclusive, int toExclusive, Action<int> | |
| private class InitProcessor<TLocal> : IThreadPoolWorkItem | ||
| { | ||
| private readonly Data<TLocal> _data; | ||
| private ExceptionDispatchInfo? _exception; | ||
|
|
||
| /// <summary> | ||
| /// Executes a parallel for loop over a range of integers, with thread-local data initialization and finalization. | ||
|
|
@@ -266,20 +285,28 @@ public static void For( | |
| var data = new Data<TLocal>(threads, fromInclusive, toExclusive, action, init, initValue, @finally, parallelOptions.CancellationToken); | ||
|
|
||
| // Queue work items to the thread pool for all threads except the current one | ||
| for (int i = 0; i < threads - 1; i++) | ||
| var tasks = new InitProcessor<TLocal>[threads - 1]; | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ArrayPool? |
||
| for (int i = 0; i < tasks.Length; i++) | ||
| { | ||
| ThreadPool.UnsafeQueueUserWorkItem(new InitProcessor<TLocal>(data), preferLocal: false); | ||
| ThreadPool.UnsafeQueueUserWorkItem((tasks[i] = new InitProcessor<TLocal>(data)), preferLocal: false); | ||
| } | ||
|
|
||
| // Execute work on the current thread | ||
| new InitProcessor<TLocal>(data).Execute(); | ||
| var task = new InitProcessor<TLocal>(data); | ||
| task.Execute(); | ||
|
|
||
| // If there are still active threads, wait for them to complete | ||
| if (data.ActiveThreads > 0) | ||
| { | ||
| data.Event.Wait(); | ||
| } | ||
|
|
||
| task._exception?.Throw(); | ||
| for (int i = 0; i < tasks.Length; i++) | ||
| { | ||
| tasks[i]._exception?.Throw(); | ||
| } | ||
|
|
||
| parallelOptions.CancellationToken.ThrowIfCancellationRequested(); | ||
| } | ||
|
|
||
|
|
@@ -294,21 +321,31 @@ public static void For( | |
| /// </summary> | ||
| public void Execute() | ||
|
benaadams marked this conversation as resolved.
|
||
| { | ||
| TLocal? value = _data.Init(); | ||
| try | ||
| { | ||
|
benaadams marked this conversation as resolved.
|
||
| int i = _data.Index.GetNext(); | ||
| while (i < _data.ToExclusive) | ||
| TLocal? value = _data.Init(); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [MEDIUM] Always signal worker completion when initialization fails If |
||
| try | ||
| { | ||
| if (_data.CancellationToken.IsCancellationRequested) return; | ||
| value = _data.Action(i, value); | ||
| i = _data.Index.GetNext(); | ||
| int i = _data.Index.GetNext(); | ||
| while (i < _data.ToExclusive) | ||
| { | ||
| if (_data.CancellationToken.IsCancellationRequested) return; | ||
| value = _data.Action(i, value); | ||
| i = _data.Index.GetNext(); | ||
| } | ||
| } | ||
| finally | ||
| { | ||
| _data.Finally(value); | ||
| _data.MarkThreadCompleted(); | ||
| } | ||
| } | ||
| finally | ||
| catch (Exception ex) | ||
| { | ||
| _data.Finally(value); | ||
| _data.MarkThreadCompleted(); | ||
| if (ex is not OperationCanceledException) | ||
| { | ||
| _exception = ExceptionDispatchInfo.Capture(ex); | ||
| } | ||
| } | ||
| } | ||
|
|
||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
worth logging?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be only in test context? Or maybe better we can expose something that will be awaited in tests, so this doesn't happen