You've already forked linux-packaging-mono
Imported Upstream version 5.0.0.42
Former-commit-id: fd56571888259555122d8a0f58c68838229cea2b
This commit is contained in:
parent
1190d13a04
commit
6bdd276d05
36
external/corefx/src/System.Threading.Tasks.Parallel/System.Threading.Tasks.Parallel.sln
vendored
Normal file
36
external/corefx/src/System.Threading.Tasks.Parallel/System.Threading.Tasks.Parallel.sln
vendored
Normal file
@ -0,0 +1,36 @@
|
||||

|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio 2013
|
||||
VisualStudioVersion = 12.0.31101.0
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "System.Threading.Tasks.Parallel.Tests", "tests\System.Threading.Tasks.Parallel.Tests.csproj", "{DE29C320-2ECA-43FD-9F41-6F4F6C6BACD5}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{A6BA5DF2-772E-4DA1-BC2D-89FF4A21EE4F} = {A6BA5DF2-772E-4DA1-BC2D-89FF4A21EE4F}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "System.Threading.Tasks.Parallel", "src\System.Threading.Tasks.Parallel.csproj", "{A6BA5DF2-772E-4DA1-BC2D-89FF4A21EE4F}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".nuget", ".nuget", "{47919FF5-DA40-4D99-AF2D-F560282AA913}"
|
||||
ProjectSection(SolutionItems) = preProject
|
||||
..\.nuget\packages.Windows_NT.config = ..\.nuget\packages.Windows_NT.config
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
DebugNETCoreAppnetcoreappnetcoreapp|AnyCPU = DebugNETCoreAppnetcoreappnetcoreapp|AnyCPU
|
||||
ReleaseNETCoreAppnetcoreappnetcoreapp|AnyCPU = ReleaseNETCoreAppnetcoreappnetcoreapp|AnyCPU
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{DE29C320-2ECA-43FD-9F41-6F4F6C6BACD5}.DebugNETCoreAppnetcoreappnetcoreapp|AnyCPU.ActiveCfg = netcoreapp-Debug|Any CPU
|
||||
{DE29C320-2ECA-43FD-9F41-6F4F6C6BACD5}.DebugNETCoreAppnetcoreappnetcoreapp|AnyCPU.Build.0 = netcoreapp-Debug|Any CPU
|
||||
{DE29C320-2ECA-43FD-9F41-6F4F6C6BACD5}.ReleaseNETCoreAppnetcoreappnetcoreapp|AnyCPU.ActiveCfg = netcoreapp-Release|Any CPU
|
||||
{DE29C320-2ECA-43FD-9F41-6F4F6C6BACD5}.ReleaseNETCoreAppnetcoreappnetcoreapp|AnyCPU.Build.0 = netcoreapp-Release|Any CPU
|
||||
{A6BA5DF2-772E-4DA1-BC2D-89FF4A21EE4F}.DebugNETCoreAppnetcoreappnetcoreapp|AnyCPU.ActiveCfg = netcoreapp-Debug|Any CPU
|
||||
{A6BA5DF2-772E-4DA1-BC2D-89FF4A21EE4F}.DebugNETCoreAppnetcoreappnetcoreapp|AnyCPU.Build.0 = netcoreapp-Debug|Any CPU
|
||||
{A6BA5DF2-772E-4DA1-BC2D-89FF4A21EE4F}.ReleaseNETCoreAppnetcoreappnetcoreapp|AnyCPU.ActiveCfg = netcoreapp-Release|Any CPU
|
||||
{A6BA5DF2-772E-4DA1-BC2D-89FF4A21EE4F}.ReleaseNETCoreAppnetcoreappnetcoreapp|AnyCPU.Build.0 = netcoreapp-Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
EndGlobal
|
8
external/corefx/src/System.Threading.Tasks.Parallel/dir.props
vendored
Normal file
8
external/corefx/src/System.Threading.Tasks.Parallel/dir.props
vendored
Normal file
@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="..\dir.props" />
|
||||
<PropertyGroup>
|
||||
<AssemblyVersion>4.0.3.0</AssemblyVersion>
|
||||
<IsNETCoreApp>true</IsNETCoreApp>
|
||||
</PropertyGroup>
|
||||
</Project>
|
9
external/corefx/src/System.Threading.Tasks.Parallel/ref/Configurations.props
vendored
Normal file
9
external/corefx/src/System.Threading.Tasks.Parallel/ref/Configurations.props
vendored
Normal file
@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<BuildConfigurations>
|
||||
netcoreapp;
|
||||
uap;
|
||||
</BuildConfigurations>
|
||||
</PropertyGroup>
|
||||
</Project>
|
71
external/corefx/src/System.Threading.Tasks.Parallel/ref/System.Threading.Tasks.Parallel.cs
vendored
Normal file
71
external/corefx/src/System.Threading.Tasks.Parallel/ref/System.Threading.Tasks.Parallel.cs
vendored
Normal file
@ -0,0 +1,71 @@
|
||||
// Licensed to the .NET Foundation under one or more agreements.
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
// ------------------------------------------------------------------------------
|
||||
// Changes to this file must follow the http://aka.ms/api-review process.
|
||||
// ------------------------------------------------------------------------------
|
||||
|
||||
|
||||
namespace System.Threading.Tasks
|
||||
{
|
||||
public static partial class Parallel
|
||||
{
|
||||
public static System.Threading.Tasks.ParallelLoopResult For(int fromInclusive, int toExclusive, System.Action<int, System.Threading.Tasks.ParallelLoopState> body) { throw null; }
|
||||
public static System.Threading.Tasks.ParallelLoopResult For(int fromInclusive, int toExclusive, System.Action<int> body) { throw null; }
|
||||
public static System.Threading.Tasks.ParallelLoopResult For(int fromInclusive, int toExclusive, System.Threading.Tasks.ParallelOptions parallelOptions, System.Action<int, System.Threading.Tasks.ParallelLoopState> body) { throw null; }
|
||||
public static System.Threading.Tasks.ParallelLoopResult For(int fromInclusive, int toExclusive, System.Threading.Tasks.ParallelOptions parallelOptions, System.Action<int> body) { throw null; }
|
||||
public static System.Threading.Tasks.ParallelLoopResult For(long fromInclusive, long toExclusive, System.Action<long, System.Threading.Tasks.ParallelLoopState> body) { throw null; }
|
||||
public static System.Threading.Tasks.ParallelLoopResult For(long fromInclusive, long toExclusive, System.Action<long> body) { throw null; }
|
||||
public static System.Threading.Tasks.ParallelLoopResult For(long fromInclusive, long toExclusive, System.Threading.Tasks.ParallelOptions parallelOptions, System.Action<long, System.Threading.Tasks.ParallelLoopState> body) { throw null; }
|
||||
public static System.Threading.Tasks.ParallelLoopResult For(long fromInclusive, long toExclusive, System.Threading.Tasks.ParallelOptions parallelOptions, System.Action<long> body) { throw null; }
|
||||
public static System.Threading.Tasks.ParallelLoopResult For<TLocal>(int fromInclusive, int toExclusive, System.Func<TLocal> localInit, System.Func<int, System.Threading.Tasks.ParallelLoopState, TLocal, TLocal> body, System.Action<TLocal> localFinally) { throw null; }
|
||||
public static System.Threading.Tasks.ParallelLoopResult For<TLocal>(int fromInclusive, int toExclusive, System.Threading.Tasks.ParallelOptions parallelOptions, System.Func<TLocal> localInit, System.Func<int, System.Threading.Tasks.ParallelLoopState, TLocal, TLocal> body, System.Action<TLocal> localFinally) { throw null; }
|
||||
public static System.Threading.Tasks.ParallelLoopResult For<TLocal>(long fromInclusive, long toExclusive, System.Func<TLocal> localInit, System.Func<long, System.Threading.Tasks.ParallelLoopState, TLocal, TLocal> body, System.Action<TLocal> localFinally) { throw null; }
|
||||
public static System.Threading.Tasks.ParallelLoopResult For<TLocal>(long fromInclusive, long toExclusive, System.Threading.Tasks.ParallelOptions parallelOptions, System.Func<TLocal> localInit, System.Func<long, System.Threading.Tasks.ParallelLoopState, TLocal, TLocal> body, System.Action<TLocal> localFinally) { throw null; }
|
||||
public static System.Threading.Tasks.ParallelLoopResult ForEach<TSource>(System.Collections.Concurrent.OrderablePartitioner<TSource> source, System.Action<TSource, System.Threading.Tasks.ParallelLoopState, long> body) { throw null; }
|
||||
public static System.Threading.Tasks.ParallelLoopResult ForEach<TSource>(System.Collections.Concurrent.OrderablePartitioner<TSource> source, System.Threading.Tasks.ParallelOptions parallelOptions, System.Action<TSource, System.Threading.Tasks.ParallelLoopState, long> body) { throw null; }
|
||||
public static System.Threading.Tasks.ParallelLoopResult ForEach<TSource>(System.Collections.Concurrent.Partitioner<TSource> source, System.Action<TSource, System.Threading.Tasks.ParallelLoopState> body) { throw null; }
|
||||
public static System.Threading.Tasks.ParallelLoopResult ForEach<TSource>(System.Collections.Concurrent.Partitioner<TSource> source, System.Action<TSource> body) { throw null; }
|
||||
public static System.Threading.Tasks.ParallelLoopResult ForEach<TSource>(System.Collections.Concurrent.Partitioner<TSource> source, System.Threading.Tasks.ParallelOptions parallelOptions, System.Action<TSource, System.Threading.Tasks.ParallelLoopState> body) { throw null; }
|
||||
public static System.Threading.Tasks.ParallelLoopResult ForEach<TSource>(System.Collections.Concurrent.Partitioner<TSource> source, System.Threading.Tasks.ParallelOptions parallelOptions, System.Action<TSource> body) { throw null; }
|
||||
public static System.Threading.Tasks.ParallelLoopResult ForEach<TSource>(System.Collections.Generic.IEnumerable<TSource> source, System.Action<TSource, System.Threading.Tasks.ParallelLoopState, long> body) { throw null; }
|
||||
public static System.Threading.Tasks.ParallelLoopResult ForEach<TSource>(System.Collections.Generic.IEnumerable<TSource> source, System.Action<TSource, System.Threading.Tasks.ParallelLoopState> body) { throw null; }
|
||||
public static System.Threading.Tasks.ParallelLoopResult ForEach<TSource>(System.Collections.Generic.IEnumerable<TSource> source, System.Action<TSource> body) { throw null; }
|
||||
public static System.Threading.Tasks.ParallelLoopResult ForEach<TSource>(System.Collections.Generic.IEnumerable<TSource> source, System.Threading.Tasks.ParallelOptions parallelOptions, System.Action<TSource, System.Threading.Tasks.ParallelLoopState, long> body) { throw null; }
|
||||
public static System.Threading.Tasks.ParallelLoopResult ForEach<TSource>(System.Collections.Generic.IEnumerable<TSource> source, System.Threading.Tasks.ParallelOptions parallelOptions, System.Action<TSource, System.Threading.Tasks.ParallelLoopState> body) { throw null; }
|
||||
public static System.Threading.Tasks.ParallelLoopResult ForEach<TSource>(System.Collections.Generic.IEnumerable<TSource> source, System.Threading.Tasks.ParallelOptions parallelOptions, System.Action<TSource> body) { throw null; }
|
||||
public static System.Threading.Tasks.ParallelLoopResult ForEach<TSource, TLocal>(System.Collections.Concurrent.OrderablePartitioner<TSource> source, System.Func<TLocal> localInit, System.Func<TSource, System.Threading.Tasks.ParallelLoopState, long, TLocal, TLocal> body, System.Action<TLocal> localFinally) { throw null; }
|
||||
public static System.Threading.Tasks.ParallelLoopResult ForEach<TSource, TLocal>(System.Collections.Concurrent.OrderablePartitioner<TSource> source, System.Threading.Tasks.ParallelOptions parallelOptions, System.Func<TLocal> localInit, System.Func<TSource, System.Threading.Tasks.ParallelLoopState, long, TLocal, TLocal> body, System.Action<TLocal> localFinally) { throw null; }
|
||||
public static System.Threading.Tasks.ParallelLoopResult ForEach<TSource, TLocal>(System.Collections.Concurrent.Partitioner<TSource> source, System.Func<TLocal> localInit, System.Func<TSource, System.Threading.Tasks.ParallelLoopState, TLocal, TLocal> body, System.Action<TLocal> localFinally) { throw null; }
|
||||
public static System.Threading.Tasks.ParallelLoopResult ForEach<TSource, TLocal>(System.Collections.Concurrent.Partitioner<TSource> source, System.Threading.Tasks.ParallelOptions parallelOptions, System.Func<TLocal> localInit, System.Func<TSource, System.Threading.Tasks.ParallelLoopState, TLocal, TLocal> body, System.Action<TLocal> localFinally) { throw null; }
|
||||
public static System.Threading.Tasks.ParallelLoopResult ForEach<TSource, TLocal>(System.Collections.Generic.IEnumerable<TSource> source, System.Func<TLocal> localInit, System.Func<TSource, System.Threading.Tasks.ParallelLoopState, TLocal, TLocal> body, System.Action<TLocal> localFinally) { throw null; }
|
||||
public static System.Threading.Tasks.ParallelLoopResult ForEach<TSource, TLocal>(System.Collections.Generic.IEnumerable<TSource> source, System.Func<TLocal> localInit, System.Func<TSource, System.Threading.Tasks.ParallelLoopState, long, TLocal, TLocal> body, System.Action<TLocal> localFinally) { throw null; }
|
||||
public static System.Threading.Tasks.ParallelLoopResult ForEach<TSource, TLocal>(System.Collections.Generic.IEnumerable<TSource> source, System.Threading.Tasks.ParallelOptions parallelOptions, System.Func<TLocal> localInit, System.Func<TSource, System.Threading.Tasks.ParallelLoopState, TLocal, TLocal> body, System.Action<TLocal> localFinally) { throw null; }
|
||||
public static System.Threading.Tasks.ParallelLoopResult ForEach<TSource, TLocal>(System.Collections.Generic.IEnumerable<TSource> source, System.Threading.Tasks.ParallelOptions parallelOptions, System.Func<TLocal> localInit, System.Func<TSource, System.Threading.Tasks.ParallelLoopState, long, TLocal, TLocal> body, System.Action<TLocal> localFinally) { throw null; }
|
||||
public static void Invoke(params System.Action[] actions) { }
|
||||
public static void Invoke(System.Threading.Tasks.ParallelOptions parallelOptions, params System.Action[] actions) { }
|
||||
}
|
||||
[System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
|
||||
public partial struct ParallelLoopResult
|
||||
{
|
||||
public bool IsCompleted { get { throw null; } }
|
||||
public System.Nullable<long> LowestBreakIteration { get { throw null; } }
|
||||
}
|
||||
public partial class ParallelLoopState
|
||||
{
|
||||
internal ParallelLoopState() { }
|
||||
public bool IsExceptional { get { throw null; } }
|
||||
public bool IsStopped { get { throw null; } }
|
||||
public System.Nullable<long> LowestBreakIteration { get { throw null; } }
|
||||
public bool ShouldExitCurrentIteration { get { throw null; } }
|
||||
public void Break() { }
|
||||
public void Stop() { }
|
||||
}
|
||||
public partial class ParallelOptions
|
||||
{
|
||||
public ParallelOptions() { }
|
||||
public System.Threading.CancellationToken CancellationToken { get { throw null; } set { } }
|
||||
public int MaxDegreeOfParallelism { get { throw null; } set { } }
|
||||
public System.Threading.Tasks.TaskScheduler TaskScheduler { get { throw null; } set { } }
|
||||
}
|
||||
}
|
17
external/corefx/src/System.Threading.Tasks.Parallel/ref/System.Threading.Tasks.Parallel.csproj
vendored
Normal file
17
external/corefx/src/System.Threading.Tasks.Parallel/ref/System.Threading.Tasks.Parallel.csproj
vendored
Normal file
@ -0,0 +1,17 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'netcoreapp-Debug|AnyCPU'" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'netcoreapp-Release|AnyCPU'" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'uap-Debug|AnyCPU'" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'uap-Release|AnyCPU'" />
|
||||
<ItemGroup>
|
||||
<Compile Include="System.Threading.Tasks.Parallel.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\System.Runtime\ref\System.Runtime.csproj" />
|
||||
<ProjectReference Include="..\..\System.Collections.Concurrent\ref\System.Collections.Concurrent.csproj" />
|
||||
<ProjectReference Include="..\..\System.Threading.Tasks\ref\System.Threading.Tasks.csproj" />
|
||||
</ItemGroup>
|
||||
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
|
||||
</Project>
|
8
external/corefx/src/System.Threading.Tasks.Parallel/src/Configurations.props
vendored
Normal file
8
external/corefx/src/System.Threading.Tasks.Parallel/src/Configurations.props
vendored
Normal file
@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<BuildConfigurations>
|
||||
netcoreapp;
|
||||
</BuildConfigurations>
|
||||
</PropertyGroup>
|
||||
</Project>
|
144
external/corefx/src/System.Threading.Tasks.Parallel/src/Resources/Strings.resx
vendored
Normal file
144
external/corefx/src/System.Threading.Tasks.Parallel/src/Resources/Strings.resx
vendored
Normal file
@ -0,0 +1,144 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<data name="Parallel_Invoke_ActionNull" xml:space="preserve">
|
||||
<value>One of the actions was null.</value>
|
||||
</data>
|
||||
<data name="Parallel_ForEach_OrderedPartitionerKeysNotNormalized" xml:space="preserve">
|
||||
<value>This method requires the use of an OrderedPartitioner with the KeysNormalized property set to true.</value>
|
||||
</data>
|
||||
<data name="Parallel_ForEach_PartitionerNotDynamic" xml:space="preserve">
|
||||
<value>The Partitioner used here must support dynamic partitioning.</value>
|
||||
</data>
|
||||
<data name="Parallel_ForEach_PartitionerReturnedNull" xml:space="preserve">
|
||||
<value>The Partitioner used here returned a null partitioner source.</value>
|
||||
</data>
|
||||
<data name="Parallel_ForEach_NullEnumerator" xml:space="preserve">
|
||||
<value>The Partitioner source returned a null enumerator.</value>
|
||||
</data>
|
||||
<data name="ParallelState_Break_InvalidOperationException_BreakAfterStop" xml:space="preserve">
|
||||
<value>Break was called after Stop was called.</value>
|
||||
</data>
|
||||
<data name="ParallelState_Stop_InvalidOperationException_StopAfterBreak" xml:space="preserve">
|
||||
<value>Stop was called after Break was called.</value>
|
||||
</data>
|
||||
<data name="ParallelState_NotSupportedException_UnsupportedMethod" xml:space="preserve">
|
||||
<value>This method is not supported.</value>
|
||||
</data>
|
||||
</root>
|
39
external/corefx/src/System.Threading.Tasks.Parallel/src/System.Threading.Tasks.Parallel.csproj
vendored
Normal file
39
external/corefx/src/System.Threading.Tasks.Parallel/src/System.Threading.Tasks.Parallel.csproj
vendored
Normal file
@ -0,0 +1,39 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
|
||||
<PropertyGroup>
|
||||
<ProjectGuid>{A6BA5DF2-772E-4DA1-BC2D-89FF4A21EE4F}</ProjectGuid>
|
||||
<RootNamespace>System.Threading.Tasks.Parallel</RootNamespace>
|
||||
<AssemblyName>System.Threading.Tasks.Parallel</AssemblyName>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<DefineConstants>$(DefineConstants);CONCURRENT_COLLECTIONS;FEATURE_TRACING</DefineConstants>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='netcoreapp-Debug|AnyCPU'" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='netcoreapp-Release|AnyCPU'" />
|
||||
<ItemGroup>
|
||||
<Compile Include="System\Threading\PlatformHelper.cs" />
|
||||
<Compile Include="System\Threading\Tasks\Box.cs" />
|
||||
<Compile Include="System\Threading\Tasks\Parallel.cs" />
|
||||
<Compile Include="System\Threading\Tasks\ParallelETWProvider.cs" />
|
||||
<Compile Include="System\Threading\Tasks\ParallelLoopState.cs" />
|
||||
<Compile Include="System\Threading\Tasks\ParallelRangeManager.cs" />
|
||||
<Compile Include="System\Threading\Tasks\TaskReplicator.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<TargetingPackReference Include="mscorlib" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="System.Collections.Concurrent" />
|
||||
<Reference Include="System.Diagnostics.Contracts" />
|
||||
<Reference Include="System.Diagnostics.Debug" />
|
||||
<Reference Include="System.Diagnostics.Tools" />
|
||||
<Reference Include="System.Diagnostics.Tracing" />
|
||||
<Reference Include="System.Resources.ResourceManager" />
|
||||
<Reference Include="System.Runtime" />
|
||||
<Reference Include="System.Runtime.Extensions" />
|
||||
<Reference Include="System.Threading" />
|
||||
<Reference Include="System.Threading.Tasks" />
|
||||
</ItemGroup>
|
||||
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
|
||||
</Project>
|
34
external/corefx/src/System.Threading.Tasks.Parallel/src/System/Threading/PlatformHelper.cs
vendored
Normal file
34
external/corefx/src/System.Threading.Tasks.Parallel/src/System/Threading/PlatformHelper.cs
vendored
Normal file
@ -0,0 +1,34 @@
|
||||
// Licensed to the .NET Foundation under one or more agreements.
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
namespace System.Threading
|
||||
{
|
||||
/// <summary>
|
||||
/// A helper class to get the number of preocessors, it updates the numbers of processors every sampling interval
|
||||
/// </summary>
|
||||
internal static class PlatformHelper
|
||||
{
|
||||
private const Int32 PROCESSOR_COUNT_REFRESH_INTERVAL_MS = 30000; // How often to refresh the count, in milliseconds.
|
||||
private static volatile Int32 s_processorCount; // The last count seen.
|
||||
private static volatile Int32 s_lastProcessorCountRefreshTicks; // The last time we refreshed.
|
||||
|
||||
/// <summary>
|
||||
/// Gets the number of available processors
|
||||
/// </summary>
|
||||
internal static Int32 ProcessorCount
|
||||
{
|
||||
get
|
||||
{
|
||||
Int32 now = Environment.TickCount;
|
||||
if (s_processorCount == 0 || (now - s_lastProcessorCountRefreshTicks) >= PROCESSOR_COUNT_REFRESH_INTERVAL_MS)
|
||||
{
|
||||
s_processorCount = Environment.ProcessorCount;
|
||||
s_lastProcessorCountRefreshTicks = now;
|
||||
}
|
||||
|
||||
return s_processorCount;
|
||||
}
|
||||
}
|
||||
} // class PlatformHelper
|
||||
} // namespace
|
19
external/corefx/src/System.Threading.Tasks.Parallel/src/System/Threading/Tasks/Box.cs
vendored
Normal file
19
external/corefx/src/System.Threading.Tasks.Parallel/src/System/Threading/Tasks/Box.cs
vendored
Normal file
@ -0,0 +1,19 @@
|
||||
// Licensed to the .NET Foundation under one or more agreements.
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System;
|
||||
|
||||
namespace System.Threading.Tasks
|
||||
{
|
||||
/// <summary>Utility class for allocating value types as heap variables.</summary>
|
||||
internal class Box<T>
|
||||
{
|
||||
internal T Value;
|
||||
|
||||
internal Box(T value)
|
||||
{
|
||||
this.Value = value;
|
||||
}
|
||||
} // class Box<T>
|
||||
} // namespace
|
@ -0,0 +1 @@
|
||||
303dd2a6dafd2740261ab8816f1920ec6acc56ca
|
@ -0,0 +1,264 @@
|
||||
// Licensed to the .NET Foundation under one or more agreements.
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
// =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
|
||||
//
|
||||
// EventSource for Task.Parallel.
|
||||
//
|
||||
// =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Security;
|
||||
using System.Diagnostics.Tracing;
|
||||
|
||||
namespace System.Threading.Tasks
|
||||
{
|
||||
/// <summary>Provides an event source for tracing TPL information.</summary>
|
||||
[EventSource(Name = "System.Threading.Tasks.Parallel.EventSource")]
|
||||
internal sealed class ParallelEtwProvider : EventSource
|
||||
{
|
||||
/// <summary>
|
||||
/// Defines the singleton instance for the Task.Parallel ETW provider.
|
||||
/// </summary>
|
||||
public static readonly ParallelEtwProvider Log = new ParallelEtwProvider();
|
||||
|
||||
/// <summary>Prevent external instantiation. All logging should go through the Log instance.</summary>
|
||||
private ParallelEtwProvider() { }
|
||||
|
||||
/// <summary>Type of a fork/join operation.</summary>
|
||||
public enum ForkJoinOperationType
|
||||
{
|
||||
/// <summary>Parallel.Invoke.</summary>
|
||||
ParallelInvoke = 1,
|
||||
/// <summary>Parallel.For.</summary>
|
||||
ParallelFor = 2,
|
||||
/// <summary>Parallel.ForEach.</summary>
|
||||
ParallelForEach = 3
|
||||
}
|
||||
|
||||
/// <summary>ETW tasks that have start/stop events.</summary>
|
||||
public class Tasks
|
||||
{ // this name is important for EventSource
|
||||
/// <summary>A parallel loop.</summary>
|
||||
public const EventTask Loop = (EventTask)1;
|
||||
/// <summary>A parallel invoke.</summary>
|
||||
public const EventTask Invoke = (EventTask)2;
|
||||
|
||||
// Do not use 3, it is used for "TaskExecute" in the TPL provider.
|
||||
// Do not use 4, it is used for "TaskWait" in the TPL provider.
|
||||
|
||||
/// <summary>A fork/join task within a loop or invoke.</summary>
|
||||
public const EventTask ForkJoin = (EventTask)5;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>Enabled for all keywords.</summary>
|
||||
private const EventKeywords ALL_KEYWORDS = (EventKeywords)(-1);
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------------
|
||||
//
|
||||
// TPL Event IDs (must be unique)
|
||||
//
|
||||
|
||||
/// <summary>The beginning of a parallel loop.</summary>
|
||||
private const Int32 PARALLELLOOPBEGIN_ID = 1;
|
||||
|
||||
/// <summary>The ending of a parallel loop.</summary>
|
||||
private const Int32 PARALLELLOOPEND_ID = 2;
|
||||
|
||||
/// <summary>The beginning of a parallel invoke.</summary>
|
||||
private const Int32 PARALLELINVOKEBEGIN_ID = 3;
|
||||
|
||||
/// <summary>The ending of a parallel invoke.</summary>
|
||||
private const Int32 PARALLELINVOKEEND_ID = 4;
|
||||
|
||||
/// <summary>A task entering a fork/join construct.</summary>
|
||||
private const Int32 PARALLELFORK_ID = 5;
|
||||
|
||||
/// <summary>A task leaving a fork/join construct.</summary>
|
||||
private const Int32 PARALLELJOIN_ID = 6;
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------------
|
||||
//
|
||||
// Parallel Events
|
||||
//
|
||||
|
||||
#region ParallelLoopBegin
|
||||
/// <summary>
|
||||
/// Denotes the entry point for a Parallel.For or Parallel.ForEach loop
|
||||
/// </summary>
|
||||
/// <param name="OriginatingTaskSchedulerID">The scheduler ID.</param>
|
||||
/// <param name="OriginatingTaskID">The task ID.</param>
|
||||
/// <param name="ForkJoinContextID">The loop ID.</param>
|
||||
/// <param name="OperationType">The kind of fork/join operation.</param>
|
||||
/// <param name="InclusiveFrom">The lower bound of the loop.</param>
|
||||
/// <param name="ExclusiveTo">The upper bound of the loop.</param>
|
||||
[SecuritySafeCritical]
|
||||
[Event(PARALLELLOOPBEGIN_ID, Level = EventLevel.Informational, Task = ParallelEtwProvider.Tasks.Loop, Opcode = EventOpcode.Start)]
|
||||
public void ParallelLoopBegin(Int32 OriginatingTaskSchedulerID, Int32 OriginatingTaskID, // PFX_COMMON_EVENT_HEADER
|
||||
Int32 ForkJoinContextID, ForkJoinOperationType OperationType, // PFX_FORKJOIN_COMMON_EVENT_HEADER
|
||||
Int64 InclusiveFrom, Int64 ExclusiveTo)
|
||||
{
|
||||
if (IsEnabled(EventLevel.Informational, ALL_KEYWORDS))
|
||||
{
|
||||
// There is no explicit WriteEvent() overload matching this event's fields. Therefore calling
|
||||
// WriteEvent() would hit the "params" overload, which leads to an object allocation every time
|
||||
// this event is fired. To prevent that problem we will call WriteEventCore(), which works with
|
||||
// a stack based EventData array populated with the event fields.
|
||||
unsafe
|
||||
{
|
||||
EventData* eventPayload = stackalloc EventData[6];
|
||||
|
||||
eventPayload[0].Size = sizeof(Int32);
|
||||
eventPayload[0].DataPointer = ((IntPtr)(&OriginatingTaskSchedulerID));
|
||||
eventPayload[1].Size = sizeof(Int32);
|
||||
eventPayload[1].DataPointer = ((IntPtr)(&OriginatingTaskID));
|
||||
eventPayload[2].Size = sizeof(Int32);
|
||||
eventPayload[2].DataPointer = ((IntPtr)(&ForkJoinContextID));
|
||||
eventPayload[3].Size = sizeof(Int32);
|
||||
eventPayload[3].DataPointer = ((IntPtr)(&OperationType));
|
||||
eventPayload[4].Size = sizeof(Int64);
|
||||
eventPayload[4].DataPointer = ((IntPtr)(&InclusiveFrom));
|
||||
eventPayload[5].Size = sizeof(Int64);
|
||||
eventPayload[5].DataPointer = ((IntPtr)(&ExclusiveTo));
|
||||
|
||||
WriteEventCore(PARALLELLOOPBEGIN_ID, 6, eventPayload);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endregion ParallelLoopBegin
|
||||
|
||||
#region ParallelLoopEnd
|
||||
/// <summary>
|
||||
/// Denotes the end of a Parallel.For or Parallel.ForEach loop.
|
||||
/// </summary>
|
||||
/// <param name="OriginatingTaskSchedulerID">The scheduler ID.</param>
|
||||
/// <param name="OriginatingTaskID">The task ID.</param>
|
||||
/// <param name="ForkJoinContextID">The loop ID.</param>
|
||||
/// <param name="TotalIterations">the total number of iterations processed.</param>
|
||||
[SecuritySafeCritical]
|
||||
[Event(PARALLELLOOPEND_ID, Level = EventLevel.Informational, Task = ParallelEtwProvider.Tasks.Loop, Opcode = EventOpcode.Stop)]
|
||||
public void ParallelLoopEnd(Int32 OriginatingTaskSchedulerID, Int32 OriginatingTaskID, // PFX_COMMON_EVENT_HEADER
|
||||
Int32 ForkJoinContextID, Int64 TotalIterations)
|
||||
{
|
||||
if (IsEnabled(EventLevel.Informational, ALL_KEYWORDS))
|
||||
{
|
||||
// There is no explicit WriteEvent() overload matching this event's fields.
|
||||
// Therefore calling WriteEvent() would hit the "params" overload, which leads to an object allocation every time this event is fired.
|
||||
// To prevent that problem we will call WriteEventCore(), which works with a stack based EventData array populated with the event fields
|
||||
unsafe
|
||||
{
|
||||
EventData* eventPayload = stackalloc EventData[4];
|
||||
|
||||
eventPayload[0].Size = sizeof(Int32);
|
||||
eventPayload[0].DataPointer = ((IntPtr)(&OriginatingTaskSchedulerID));
|
||||
eventPayload[1].Size = sizeof(Int32);
|
||||
eventPayload[1].DataPointer = ((IntPtr)(&OriginatingTaskID));
|
||||
eventPayload[2].Size = sizeof(Int32);
|
||||
eventPayload[2].DataPointer = ((IntPtr)(&ForkJoinContextID));
|
||||
eventPayload[3].Size = sizeof(Int64);
|
||||
eventPayload[3].DataPointer = ((IntPtr)(&TotalIterations));
|
||||
|
||||
WriteEventCore(PARALLELLOOPEND_ID, 4, eventPayload);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endregion ParallelLoopEnd
|
||||
|
||||
#region ParallelInvokeBegin
|
||||
/// <summary>Denotes the entry point for a Parallel.Invoke call.</summary>
|
||||
/// <param name="OriginatingTaskSchedulerID">The scheduler ID.</param>
|
||||
/// <param name="OriginatingTaskID">The task ID.</param>
|
||||
/// <param name="ForkJoinContextID">The invoke ID.</param>
|
||||
/// <param name="OperationType">The kind of fork/join operation.</param>
|
||||
/// <param name="ActionCount">The number of actions being invoked.</param>
|
||||
[SecuritySafeCritical]
|
||||
[Event(PARALLELINVOKEBEGIN_ID, Level = EventLevel.Informational, Task = ParallelEtwProvider.Tasks.Invoke, Opcode = EventOpcode.Start)]
|
||||
public void ParallelInvokeBegin(Int32 OriginatingTaskSchedulerID, Int32 OriginatingTaskID, // PFX_COMMON_EVENT_HEADER
|
||||
Int32 ForkJoinContextID, ForkJoinOperationType OperationType, // PFX_FORKJOIN_COMMON_EVENT_HEADER
|
||||
Int32 ActionCount)
|
||||
{
|
||||
if (IsEnabled(EventLevel.Informational, ALL_KEYWORDS))
|
||||
{
|
||||
// There is no explicit WriteEvent() overload matching this event's fields.
|
||||
// Therefore calling WriteEvent() would hit the "params" overload, which leads to an object allocation every time this event is fired.
|
||||
// To prevent that problem we will call WriteEventCore(), which works with a stack based EventData array populated with the event fields
|
||||
unsafe
|
||||
{
|
||||
EventData* eventPayload = stackalloc EventData[5];
|
||||
|
||||
eventPayload[0].Size = sizeof(Int32);
|
||||
eventPayload[0].DataPointer = ((IntPtr)(&OriginatingTaskSchedulerID));
|
||||
eventPayload[1].Size = sizeof(Int32);
|
||||
eventPayload[1].DataPointer = ((IntPtr)(&OriginatingTaskID));
|
||||
eventPayload[2].Size = sizeof(Int32);
|
||||
eventPayload[2].DataPointer = ((IntPtr)(&ForkJoinContextID));
|
||||
eventPayload[3].Size = sizeof(Int32);
|
||||
eventPayload[3].DataPointer = ((IntPtr)(&OperationType));
|
||||
eventPayload[4].Size = sizeof(Int32);
|
||||
eventPayload[4].DataPointer = ((IntPtr)(&ActionCount));
|
||||
|
||||
WriteEventCore(PARALLELINVOKEBEGIN_ID, 5, eventPayload);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endregion ParallelInvokeBegin
|
||||
|
||||
#region ParallelInvokeEnd
|
||||
/// <summary>
|
||||
/// Denotes the exit point for a Parallel.Invoke call.
|
||||
/// </summary>
|
||||
/// <param name="OriginatingTaskSchedulerID">The scheduler ID.</param>
|
||||
/// <param name="OriginatingTaskID">The task ID.</param>
|
||||
/// <param name="ForkJoinContextID">The invoke ID.</param>
|
||||
[Event(PARALLELINVOKEEND_ID, Level = EventLevel.Informational, Task = ParallelEtwProvider.Tasks.Invoke, Opcode = EventOpcode.Stop)]
|
||||
public void ParallelInvokeEnd(Int32 OriginatingTaskSchedulerID, Int32 OriginatingTaskID, // PFX_COMMON_EVENT_HEADER
|
||||
Int32 ForkJoinContextID)
|
||||
{
|
||||
if (IsEnabled(EventLevel.Informational, ALL_KEYWORDS))
|
||||
WriteEvent(PARALLELINVOKEEND_ID, OriginatingTaskSchedulerID, OriginatingTaskID, ForkJoinContextID);
|
||||
}
|
||||
#endregion ParallelInvokeEnd
|
||||
|
||||
#region ParallelFork
|
||||
/// <summary>
|
||||
/// Denotes the start of an individual task that's part of a fork/join context.
|
||||
/// Before this event is fired, the start of the new fork/join context will be marked
|
||||
/// with another event that declares a unique context ID.
|
||||
/// </summary>
|
||||
/// <param name="OriginatingTaskSchedulerID">The scheduler ID.</param>
|
||||
/// <param name="OriginatingTaskID">The task ID.</param>
|
||||
/// <param name="ForkJoinContextID">The invoke ID.</param>
|
||||
[Event(PARALLELFORK_ID, Level = EventLevel.Verbose, Task = ParallelEtwProvider.Tasks.ForkJoin, Opcode = EventOpcode.Start)]
|
||||
public void ParallelFork(Int32 OriginatingTaskSchedulerID, Int32 OriginatingTaskID, // PFX_COMMON_EVENT_HEADER
|
||||
Int32 ForkJoinContextID)
|
||||
{
|
||||
if (IsEnabled(EventLevel.Verbose, ALL_KEYWORDS))
|
||||
WriteEvent(PARALLELFORK_ID, OriginatingTaskSchedulerID, OriginatingTaskID, ForkJoinContextID);
|
||||
}
|
||||
#endregion ParallelFork
|
||||
|
||||
#region ParallelJoin
|
||||
/// <summary>
|
||||
/// Denotes the end of an individual task that's part of a fork/join context.
|
||||
/// This should match a previous ParallelFork event with a matching "OriginatingTaskID"
|
||||
/// </summary>
|
||||
/// <param name="OriginatingTaskSchedulerID">The scheduler ID.</param>
|
||||
/// <param name="OriginatingTaskID">The task ID.</param>
|
||||
/// <param name="ForkJoinContextID">The invoke ID.</param>
|
||||
[Event(PARALLELJOIN_ID, Level = EventLevel.Verbose, Task = ParallelEtwProvider.Tasks.ForkJoin, Opcode = EventOpcode.Stop)]
|
||||
public void ParallelJoin(Int32 OriginatingTaskSchedulerID, Int32 OriginatingTaskID, // PFX_COMMON_EVENT_HEADER
|
||||
Int32 ForkJoinContextID)
|
||||
{
|
||||
if (IsEnabled(EventLevel.Verbose, ALL_KEYWORDS))
|
||||
WriteEvent(PARALLELJOIN_ID, OriginatingTaskSchedulerID, OriginatingTaskID, ForkJoinContextID);
|
||||
}
|
||||
#endregion ParallelJoin
|
||||
|
||||
} // class ParallelEtwProvider
|
||||
} // namespace
|
628
external/corefx/src/System.Threading.Tasks.Parallel/src/System/Threading/Tasks/ParallelLoopState.cs
vendored
Normal file
628
external/corefx/src/System.Threading.Tasks.Parallel/src/System/Threading/Tasks/ParallelLoopState.cs
vendored
Normal file
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,276 @@
|
||||
// Licensed to the .NET Foundation under one or more agreements.
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
// =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
|
||||
//
|
||||
// Implements the algorithm for distributing loop indices to parallel loop workers
|
||||
//
|
||||
// =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
|
||||
|
||||
using System;
|
||||
using System.Threading;
|
||||
using System.Diagnostics;
|
||||
|
||||
#pragma warning disable 0420
|
||||
namespace System.Threading.Tasks
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents an index range
|
||||
/// </summary>
|
||||
internal struct IndexRange
|
||||
{
|
||||
// the From and To values for this range. These do not change.
|
||||
internal long _nFromInclusive;
|
||||
internal long _nToExclusive;
|
||||
|
||||
// The shared index, stored as the offset from nFromInclusive. Using an offset rather than the actual
|
||||
// value saves us from overflows that can happen due to multiple workers racing to increment this.
|
||||
// All updates to this field need to be interlocked.
|
||||
internal volatile Box<long> _nSharedCurrentIndexOffset;
|
||||
|
||||
// to be set to 1 by the worker that finishes this range. It's OK to do a non-interlocked write here.
|
||||
internal int _bRangeFinished;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// The RangeWorker struct wraps the state needed by a task that services the parallel loop
|
||||
/// </summary>
|
||||
internal struct RangeWorker
|
||||
{
|
||||
// reference to the IndexRange array allocated by the range manager
|
||||
internal readonly IndexRange[] _indexRanges;
|
||||
|
||||
// index of the current index range that this worker is grabbing chunks from
|
||||
internal int _nCurrentIndexRange;
|
||||
|
||||
// the step for this loop. Duplicated here for quick access (rather than jumping to rangemanager)
|
||||
internal long _nStep;
|
||||
|
||||
// increment value is the current amount that this worker will use
|
||||
// to increment the shared index of the range it's working on
|
||||
internal long _nIncrementValue;
|
||||
|
||||
// the increment value is doubled each time this worker finds work, and is capped at this value
|
||||
internal readonly long _nMaxIncrementValue;
|
||||
|
||||
internal bool IsInitialized { get { return _indexRanges != null; } }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a RangeWorker struct
|
||||
/// </summary>
|
||||
internal RangeWorker(IndexRange[] ranges, int nInitialRange, long nStep)
|
||||
{
|
||||
_indexRanges = ranges;
|
||||
_nCurrentIndexRange = nInitialRange;
|
||||
_nStep = nStep;
|
||||
|
||||
_nIncrementValue = nStep;
|
||||
|
||||
_nMaxIncrementValue = Parallel.DEFAULT_LOOP_STRIDE * nStep;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Implements the core work search algorithm that will be used for this range worker.
|
||||
/// </summary>
|
||||
///
|
||||
/// Usage pattern is:
|
||||
/// 1) the thread associated with this rangeworker calls FindNewWork
|
||||
/// 2) if we return true, the worker uses the nFromInclusiveLocal and nToExclusiveLocal values
|
||||
/// to execute the sequential loop
|
||||
/// 3) if we return false it means there is no more work left. It's time to quit.
|
||||
///
|
||||
internal bool FindNewWork(out long nFromInclusiveLocal, out long nToExclusiveLocal)
|
||||
{
|
||||
// since we iterate over index ranges circularly, we will use the
|
||||
// count of visited ranges as our exit condition
|
||||
int numIndexRangesToVisit = _indexRanges.Length;
|
||||
|
||||
do
|
||||
{
|
||||
// local snap to save array access bounds checks in places where we only read fields
|
||||
IndexRange currentRange = _indexRanges[_nCurrentIndexRange];
|
||||
|
||||
if (currentRange._bRangeFinished == 0)
|
||||
{
|
||||
if (_indexRanges[_nCurrentIndexRange]._nSharedCurrentIndexOffset == null)
|
||||
{
|
||||
Interlocked.CompareExchange(ref _indexRanges[_nCurrentIndexRange]._nSharedCurrentIndexOffset, new Box<long>(0), null);
|
||||
}
|
||||
|
||||
// this access needs to be on the array slot
|
||||
long nMyOffset = Interlocked.Add(ref _indexRanges[_nCurrentIndexRange]._nSharedCurrentIndexOffset.Value,
|
||||
_nIncrementValue) - _nIncrementValue;
|
||||
|
||||
if (currentRange._nToExclusive - currentRange._nFromInclusive > nMyOffset)
|
||||
{
|
||||
// we found work
|
||||
|
||||
nFromInclusiveLocal = currentRange._nFromInclusive + nMyOffset;
|
||||
nToExclusiveLocal = nFromInclusiveLocal + _nIncrementValue;
|
||||
|
||||
// Check for going past end of range, or wrapping
|
||||
if ((nToExclusiveLocal > currentRange._nToExclusive) || (nToExclusiveLocal < currentRange._nFromInclusive))
|
||||
{
|
||||
nToExclusiveLocal = currentRange._nToExclusive;
|
||||
}
|
||||
|
||||
// We will double our unit of increment until it reaches the maximum.
|
||||
if (_nIncrementValue < _nMaxIncrementValue)
|
||||
{
|
||||
_nIncrementValue *= 2;
|
||||
if (_nIncrementValue > _nMaxIncrementValue)
|
||||
{
|
||||
_nIncrementValue = _nMaxIncrementValue;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// this index range is completed, mark it so that others can skip it quickly
|
||||
Interlocked.Exchange(ref _indexRanges[_nCurrentIndexRange]._bRangeFinished, 1);
|
||||
}
|
||||
}
|
||||
|
||||
// move on to the next index range, in circular order.
|
||||
_nCurrentIndexRange = (_nCurrentIndexRange + 1) % _indexRanges.Length;
|
||||
numIndexRangesToVisit--;
|
||||
} while (numIndexRangesToVisit > 0);
|
||||
// we've visited all index ranges possible => there's no work remaining
|
||||
|
||||
nFromInclusiveLocal = 0;
|
||||
nToExclusiveLocal = 0;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 32 bit integer version of FindNewWork. Assumes the ranges were initialized with 32 bit values.
|
||||
/// </summary>
|
||||
internal bool FindNewWork32(out int nFromInclusiveLocal32, out int nToExclusiveLocal32)
|
||||
{
|
||||
long nFromInclusiveLocal;
|
||||
long nToExclusiveLocal;
|
||||
|
||||
bool bRetVal = FindNewWork(out nFromInclusiveLocal, out nToExclusiveLocal);
|
||||
|
||||
Debug.Assert((nFromInclusiveLocal <= Int32.MaxValue) && (nFromInclusiveLocal >= Int32.MinValue) &&
|
||||
(nToExclusiveLocal <= Int32.MaxValue) && (nToExclusiveLocal >= Int32.MinValue));
|
||||
|
||||
// convert to 32 bit before returning
|
||||
nFromInclusiveLocal32 = (int)nFromInclusiveLocal;
|
||||
nToExclusiveLocal32 = (int)nToExclusiveLocal;
|
||||
|
||||
return bRetVal;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Represents the entire loop operation, keeping track of workers and ranges.
|
||||
/// </summary>
|
||||
///
|
||||
/// The usage pattern is:
|
||||
/// 1) The Parallel loop entry function (ForWorker) creates an instance of this class
|
||||
/// 2) Every thread joining to service the parallel loop calls RegisterWorker to grab a
|
||||
/// RangeWorker struct to wrap the state it will need to find and execute work,
|
||||
/// and they keep interacting with that struct until the end of the loop
|
||||
internal class RangeManager
|
||||
{
|
||||
internal readonly IndexRange[] _indexRanges;
|
||||
|
||||
internal int _nCurrentIndexRangeToAssign;
|
||||
internal long _nStep;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a RangeManager with the given loop parameters, and the desired number of outer ranges
|
||||
/// </summary>
|
||||
internal RangeManager(long nFromInclusive, long nToExclusive, long nStep, int nNumExpectedWorkers)
|
||||
{
|
||||
_nCurrentIndexRangeToAssign = 0;
|
||||
_nStep = nStep;
|
||||
|
||||
// Our signed math breaks down w/ nNumExpectedWorkers == 1. So change it to 2.
|
||||
if (nNumExpectedWorkers == 1)
|
||||
nNumExpectedWorkers = 2;
|
||||
|
||||
//
|
||||
// calculate the size of each index range
|
||||
//
|
||||
|
||||
ulong uSpan = (ulong)(nToExclusive - nFromInclusive);
|
||||
ulong uRangeSize = uSpan / (ulong)nNumExpectedWorkers; // rough estimate first
|
||||
|
||||
uRangeSize -= uRangeSize % (ulong)nStep; // snap to multiples of nStep
|
||||
// otherwise index range transitions will derail us from nStep
|
||||
|
||||
if (uRangeSize == 0)
|
||||
{
|
||||
uRangeSize = (ulong)nStep;
|
||||
}
|
||||
|
||||
//
|
||||
// find the actual number of index ranges we will need
|
||||
//
|
||||
Debug.Assert((uSpan / uRangeSize) < Int32.MaxValue);
|
||||
|
||||
int nNumRanges = (int)(uSpan / uRangeSize);
|
||||
|
||||
if (uSpan % uRangeSize != 0)
|
||||
{
|
||||
nNumRanges++;
|
||||
}
|
||||
|
||||
|
||||
// Convert to signed so the rest of the logic works.
|
||||
// Should be fine so long as uRangeSize < Int64.MaxValue, which we guaranteed by setting #workers >= 2.
|
||||
long nRangeSize = (long)uRangeSize;
|
||||
|
||||
// allocate the array of index ranges
|
||||
_indexRanges = new IndexRange[nNumRanges];
|
||||
|
||||
long nCurrentIndex = nFromInclusive;
|
||||
for (int i = 0; i < nNumRanges; i++)
|
||||
{
|
||||
// the fromInclusive of the new index range is always on nCurrentIndex
|
||||
_indexRanges[i]._nFromInclusive = nCurrentIndex;
|
||||
_indexRanges[i]._nSharedCurrentIndexOffset = null;
|
||||
_indexRanges[i]._bRangeFinished = 0;
|
||||
|
||||
// now increment it to find the toExclusive value for our range
|
||||
nCurrentIndex += nRangeSize;
|
||||
|
||||
// detect integer overflow or range overage and snap to nToExclusive
|
||||
if (nCurrentIndex < nCurrentIndex - nRangeSize ||
|
||||
nCurrentIndex > nToExclusive)
|
||||
{
|
||||
// this should only happen at the last index
|
||||
Debug.Assert(i == nNumRanges - 1);
|
||||
|
||||
nCurrentIndex = nToExclusive;
|
||||
}
|
||||
|
||||
// now that the end point of the new range is calculated, assign it.
|
||||
_indexRanges[i]._nToExclusive = nCurrentIndex;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The function that needs to be called by each new worker thread servicing the parallel loop
|
||||
/// in order to get a RangeWorker struct that wraps the state for finding and executing indices
|
||||
/// </summary>
|
||||
internal RangeWorker RegisterNewWorker()
|
||||
{
|
||||
Debug.Assert(_indexRanges != null && _indexRanges.Length != 0);
|
||||
|
||||
int nInitialRange = (Interlocked.Increment(ref _nCurrentIndexRangeToAssign) - 1) % _indexRanges.Length;
|
||||
|
||||
return new RangeWorker(_indexRanges, nInitialRange, _nStep);
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore 0420
|
162
external/corefx/src/System.Threading.Tasks.Parallel/src/System/Threading/Tasks/TaskReplicator.cs
vendored
Normal file
162
external/corefx/src/System.Threading.Tasks.Parallel/src/System/Threading/Tasks/TaskReplicator.cs
vendored
Normal file
@ -0,0 +1,162 @@
|
||||
// Licensed to the .NET Foundation under one or more agreements.
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace System.Threading.Tasks
|
||||
{
|
||||
//
|
||||
// TaskReplicator runs a delegate inside of one or more Tasks, concurrently. The idea is to exploit "available"
|
||||
// parallelism, where "available" is determined by the TaskScheduler. We always keep one Task queued to
|
||||
// the scheduler, and if it starts running we queue another one, etc., up to some (potentially) user-defined
|
||||
// limit.
|
||||
//
|
||||
internal class TaskReplicator
|
||||
{
|
||||
public delegate void ReplicatableUserAction<TState>(ref TState replicaState, int timeout, out bool yieldedBeforeCompletion);
|
||||
|
||||
private readonly TaskScheduler _scheduler;
|
||||
private readonly bool _stopOnFirstFailure;
|
||||
|
||||
private readonly ConcurrentQueue<Replica> _pendingReplicas = new ConcurrentQueue<Replica>();
|
||||
private ConcurrentQueue<Exception> _exceptions;
|
||||
private bool _stopReplicating;
|
||||
|
||||
private abstract class Replica
|
||||
{
|
||||
protected readonly TaskReplicator _replicator;
|
||||
protected readonly int _timeout;
|
||||
protected int _remainingConcurrency;
|
||||
protected volatile Task _pendingTask; // the most recently queued Task for this replica, or null if we're done.
|
||||
|
||||
protected Replica(TaskReplicator replicator, int maxConcurrency, int timeout)
|
||||
{
|
||||
_replicator = replicator;
|
||||
_timeout = timeout;
|
||||
_remainingConcurrency = maxConcurrency - 1;
|
||||
_pendingTask = new Task(s => ((Replica)s).Execute(), this);
|
||||
_replicator._pendingReplicas.Enqueue(this);
|
||||
}
|
||||
|
||||
public void Start()
|
||||
{
|
||||
_pendingTask.RunSynchronously(_replicator._scheduler);
|
||||
}
|
||||
|
||||
public void Wait()
|
||||
{
|
||||
//
|
||||
// We wait in a loop because each Task might queue another Task, and so on.
|
||||
// It's entirely possible for multiple Tasks to be queued without this loop seeing them,
|
||||
// but that's fine, since we really only need to know when all of them have finished.
|
||||
//
|
||||
// Note that it's *very* important that we use Task.Wait here, rather than waiting on some
|
||||
// other synchronization primitive. Task.Wait can "inline" the Task's execution, on this thread,
|
||||
// if it hasn't started running on another thread. That's essential for preventing deadlocks,
|
||||
// in the case where all other threads are blocked for other reasons.
|
||||
//
|
||||
Task pendingTask;
|
||||
while ((pendingTask = _pendingTask) != null)
|
||||
pendingTask.Wait();
|
||||
}
|
||||
|
||||
public void Execute()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (!_replicator._stopReplicating && _remainingConcurrency > 0)
|
||||
{
|
||||
CreateNewReplica();
|
||||
_remainingConcurrency = 0; // new replica is responsible for adding concurrency from now on.
|
||||
}
|
||||
|
||||
bool userActionYieldedBeforeCompletion;
|
||||
|
||||
ExecuteAction(out userActionYieldedBeforeCompletion);
|
||||
|
||||
if (userActionYieldedBeforeCompletion)
|
||||
{
|
||||
_pendingTask = new Task(s => ((Replica)s).Execute(), this, CancellationToken.None, TaskCreationOptions.PreferFairness);
|
||||
_pendingTask.Start(_replicator._scheduler);
|
||||
}
|
||||
else
|
||||
{
|
||||
_replicator._stopReplicating = true;
|
||||
_pendingTask = null;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LazyInitializer.EnsureInitialized(ref _replicator._exceptions).Enqueue(ex);
|
||||
if (_replicator._stopOnFirstFailure)
|
||||
_replicator._stopReplicating = true;
|
||||
_pendingTask = null;
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract void CreateNewReplica();
|
||||
protected abstract void ExecuteAction(out bool yieldedBeforeCompletion);
|
||||
}
|
||||
|
||||
private sealed class Replica<TState> : Replica
|
||||
{
|
||||
private readonly ReplicatableUserAction<TState> _action;
|
||||
private TState _state;
|
||||
|
||||
public Replica(TaskReplicator replicator, int maxConcurrency, int timeout, ReplicatableUserAction<TState> action)
|
||||
: base(replicator, maxConcurrency, timeout)
|
||||
{
|
||||
_action = action;
|
||||
}
|
||||
|
||||
protected override void CreateNewReplica()
|
||||
{
|
||||
Replica<TState> newReplica = new Replica<TState>(_replicator, _remainingConcurrency, GenerateCooperativeMultitaskingTaskTimeout(), _action);
|
||||
newReplica._pendingTask.Start(_replicator._scheduler);
|
||||
}
|
||||
|
||||
protected override void ExecuteAction(out bool yieldedBeforeCompletion)
|
||||
{
|
||||
_action(ref _state, _timeout, out yieldedBeforeCompletion);
|
||||
}
|
||||
}
|
||||
|
||||
private TaskReplicator(ParallelOptions options, bool stopOnFirstFailure)
|
||||
{
|
||||
_scheduler = options.TaskScheduler ?? TaskScheduler.Current;
|
||||
_stopOnFirstFailure = stopOnFirstFailure;
|
||||
}
|
||||
|
||||
public static void Run<TState>(ReplicatableUserAction<TState> action, ParallelOptions options, bool stopOnFirstFailure)
|
||||
{
|
||||
int maxConcurrencyLevel = (options.EffectiveMaxConcurrencyLevel > 0) ? options.EffectiveMaxConcurrencyLevel : int.MaxValue;
|
||||
|
||||
TaskReplicator replicator = new TaskReplicator(options, stopOnFirstFailure);
|
||||
new Replica<TState>(replicator, maxConcurrencyLevel, CooperativeMultitaskingTaskTimeout_RootTask, action).Start();
|
||||
|
||||
Replica nextReplica;
|
||||
while (replicator._pendingReplicas.TryDequeue(out nextReplica))
|
||||
nextReplica.Wait();
|
||||
|
||||
if (replicator._exceptions != null)
|
||||
throw new AggregateException(replicator._exceptions);
|
||||
}
|
||||
|
||||
|
||||
private const Int32 CooperativeMultitaskingTaskTimeout_Min = 100; // millisec
|
||||
private const Int32 CooperativeMultitaskingTaskTimeout_Increment = 50; // millisec
|
||||
private const Int32 CooperativeMultitaskingTaskTimeout_RootTask = (Int32.MaxValue / 2);
|
||||
|
||||
private static Int32 GenerateCooperativeMultitaskingTaskTimeout()
|
||||
{
|
||||
// This logic ensures that we have a diversity of timeouts across worker tasks (100, 150, 200, 250, 100, etc)
|
||||
// Otherwise all worker will try to timeout at precisely the same point, which is bad if the work is just about to finish.
|
||||
Int32 period = PlatformHelper.ProcessorCount;
|
||||
Int32 pseudoRnd = Environment.TickCount;
|
||||
return CooperativeMultitaskingTaskTimeout_Min + (pseudoRnd % period) * CooperativeMultitaskingTaskTimeout_Increment;
|
||||
}
|
||||
}
|
||||
}
|
169
external/corefx/src/System.Threading.Tasks.Parallel/tests/BreakTests.cs
vendored
Normal file
169
external/corefx/src/System.Threading.Tasks.Parallel/tests/BreakTests.cs
vendored
Normal file
@ -0,0 +1,169 @@
|
||||
// Licensed to the .NET Foundation under one or more agreements.
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
|
||||
using Xunit;
|
||||
|
||||
namespace System.Threading.Tasks.Tests
|
||||
{
|
||||
public static class BreakTests
|
||||
{
|
||||
[Theory]
|
||||
[InlineData(100, 10)]
|
||||
[InlineData(100, 20)]
|
||||
[InlineData(1000, 100)]
|
||||
[InlineData(1000, 200)]
|
||||
public static void TestFor_Break_Basic(int loopsize, int breakpoint)
|
||||
{
|
||||
var complete = new bool[loopsize];
|
||||
|
||||
Parallel.For(0, loopsize, delegate(int i, ParallelLoopState ps)
|
||||
{
|
||||
complete[i] = true;
|
||||
if (i >= breakpoint) ps.Break();
|
||||
//Thread.Sleep(2);
|
||||
});
|
||||
|
||||
// Should not be any omissions prior
|
||||
// to break, and there should be some after.
|
||||
for (int i = 0; i <= breakpoint; i++)
|
||||
{
|
||||
Assert.True(complete[i], string.Format("TestForBreak: Failed: incomplete at {0}, loopsize {1}, breakpoint {2}", i, loopsize, breakpoint));
|
||||
}
|
||||
|
||||
bool result = true;
|
||||
for (int i = breakpoint + 1; i < loopsize; i++)
|
||||
{
|
||||
if (!complete[i])
|
||||
{
|
||||
result = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Assert.True(result, "TestForBreak: Failed: Could not detect any interruption of For-loop.");
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(100, 10)]
|
||||
[InlineData(100, 20)]
|
||||
[InlineData(1000, 100)]
|
||||
[InlineData(1000, 200)]
|
||||
public static void TestFor_Break_64Bits(int loopsize, int breakpoint)
|
||||
{
|
||||
var complete = new bool[loopsize];
|
||||
|
||||
// Throw a curveball here and loop from just-under-Int32.MaxValue to
|
||||
// just-over-Int32.MaxValue. Make sure that 64-bit indices are being
|
||||
// handled correctly.
|
||||
long loopbase = (long)Int32.MaxValue - 10;
|
||||
Parallel.For(loopbase, loopbase + loopsize, delegate(long i, ParallelLoopState ps)
|
||||
{
|
||||
complete[i - loopbase] = true;
|
||||
if ((i - loopbase) >= breakpoint) ps.Break();
|
||||
//Thread.Sleep(2);
|
||||
});
|
||||
|
||||
// Should not be any omissions prior
|
||||
// to break, and there should be some after.
|
||||
for (long i = 0; i <= breakpoint; i++)
|
||||
{
|
||||
Assert.True(complete[i], string.Format("TestFor64Break: Failed: incomplete at {0}, loopsize {1}, breakpoint {2}", i, loopsize, breakpoint));
|
||||
}
|
||||
|
||||
bool result = false;
|
||||
for (long i = breakpoint + 1; i < loopsize; i++)
|
||||
{
|
||||
if (!complete[i])
|
||||
{
|
||||
result = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Assert.True(result, "TestFor64Break: Failed: Could not detect any interruption of For-loop.");
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(500, 10)]
|
||||
[InlineData(500, 20)]
|
||||
[InlineData(1000, 100)]
|
||||
[InlineData(1000, 200)]
|
||||
public static void TestForEach_Break(int loopsize, int breakpoint)
|
||||
{
|
||||
var complete = new bool[loopsize];
|
||||
|
||||
// NOTE: Make sure and use some collection that is NOT a list or an
|
||||
// array. Lists/arrays will be essentially be passed through
|
||||
// Parallel.For() logic, which will make this test fail.
|
||||
var iqueue = new Queue<int>();
|
||||
for (int i = 0; i < loopsize; i++) iqueue.Enqueue(i);
|
||||
|
||||
Parallel.ForEach(iqueue, delegate(int i, ParallelLoopState ps)
|
||||
{
|
||||
complete[i] = true;
|
||||
if (i >= breakpoint) ps.Break();
|
||||
//Thread.Sleep(2);
|
||||
});
|
||||
|
||||
// Same rules as For-loop. Should not be any omissions prior
|
||||
// to break, and there should be some after.
|
||||
for (int i = 0; i <= breakpoint; i++)
|
||||
{
|
||||
Assert.True(complete[i], string.Format("TestForEachBreak(loopsize={0},breakpoint={1}): Failed: incomplete at {2}", loopsize, breakpoint, i));
|
||||
}
|
||||
|
||||
bool result = false;
|
||||
for (int i = breakpoint + 1; i < loopsize; i++)
|
||||
{
|
||||
if (!complete[i])
|
||||
{
|
||||
result = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Assert.True(result, string.Format("TestForEachBreak(loopsize={0},breakpoint={1}): Failed: Could not detect any interruption of For-loop.", loopsize, breakpoint));
|
||||
|
||||
//
|
||||
// Now try it for OrderablePartitioner
|
||||
//
|
||||
var ilist = new List<int>();
|
||||
for (int i = 0; i < loopsize; i++)
|
||||
{
|
||||
ilist.Add(i);
|
||||
complete[i] = false;
|
||||
}
|
||||
OrderablePartitioner<int> mop = Partitioner.Create(ilist, true);
|
||||
Parallel.ForEach(mop, delegate(int item, ParallelLoopState ps, long index)
|
||||
{
|
||||
//break does not imply that the other iterations will not be run
|
||||
//http://msdn.microsoft.com/en-us/library/system.threading.tasks.parallelloopstate.break.aspx
|
||||
//execute the test with high loop size and low break index
|
||||
complete[index] = true;
|
||||
if (index >= breakpoint) ps.Break();
|
||||
//Thread.Sleep(2);
|
||||
});
|
||||
|
||||
for (int i = 0; i <= breakpoint; i++)
|
||||
{
|
||||
Assert.True(complete[i], string.Format("TestForEachBreak(loopsize={0},breakpoint={1}): Failed: incomplete at {2}", loopsize, breakpoint, i));
|
||||
}
|
||||
|
||||
result = false;
|
||||
for (int i = breakpoint + 1; i < loopsize; i++)
|
||||
{
|
||||
if (!complete[i])
|
||||
{
|
||||
result = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Assert.True(result, string.Format("TestForEachBreak(loopsize={0},breakpoint={1}): Failed: Could not detect any interruption of For-loop.", loopsize, breakpoint));
|
||||
}
|
||||
}
|
||||
}
|
8
external/corefx/src/System.Threading.Tasks.Parallel/tests/Configurations.props
vendored
Normal file
8
external/corefx/src/System.Threading.Tasks.Parallel/tests/Configurations.props
vendored
Normal file
@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<BuildConfigurations>
|
||||
netstandard1.5;
|
||||
</BuildConfigurations>
|
||||
</PropertyGroup>
|
||||
</Project>
|
47
external/corefx/src/System.Threading.Tasks.Parallel/tests/EtwTests.cs
vendored
Normal file
47
external/corefx/src/System.Threading.Tasks.Parallel/tests/EtwTests.cs
vendored
Normal file
@ -0,0 +1,47 @@
|
||||
// Licensed to the .NET Foundation under one or more agreements.
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System.Collections.Concurrent;
|
||||
using System.Diagnostics.Tracing;
|
||||
using System.Linq;
|
||||
|
||||
using Xunit;
|
||||
|
||||
namespace System.Threading.Tasks.Tests
|
||||
{
|
||||
public static class EtwTests
|
||||
{
|
||||
[Fact]
|
||||
public static void TestEtw()
|
||||
{
|
||||
using (var listener = new TestEventListener("System.Threading.Tasks.Parallel.EventSource", EventLevel.Verbose))
|
||||
{
|
||||
var events = new ConcurrentQueue<int>();
|
||||
listener.RunWithCallback(ev => events.Enqueue(ev.EventId), () => {
|
||||
Parallel.For(0, 10000, i => { });
|
||||
|
||||
var barrier = new Barrier(2);
|
||||
Parallel.Invoke(
|
||||
() => barrier.SignalAndWait(),
|
||||
() => barrier.SignalAndWait());
|
||||
});
|
||||
|
||||
const int BeginLoopEventId = 1;
|
||||
const int BeginInvokeEventId = 3;
|
||||
Assert.Equal(expected: 1, actual: events.Count(i => i == BeginLoopEventId));
|
||||
Assert.Equal(expected: 1, actual: events.Count(i => i == BeginInvokeEventId));
|
||||
|
||||
const int EndLoopEventId = 2;
|
||||
const int EndInvokeEventId = 4;
|
||||
Assert.Equal(expected: 1, actual: events.Count(i => i == EndLoopEventId));
|
||||
Assert.Equal(expected: 1, actual: events.Count(i => i == EndInvokeEventId));
|
||||
|
||||
const int ForkEventId = 5;
|
||||
const int JoinEventId = 6;
|
||||
Assert.True(events.Count(i => i == ForkEventId) >= 1);
|
||||
Assert.Equal(events.Count(i => i == ForkEventId), events.Count(i => i == JoinEventId));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
77
external/corefx/src/System.Threading.Tasks.Parallel/tests/ParallelFor.cs
vendored
Normal file
77
external/corefx/src/System.Threading.Tasks.Parallel/tests/ParallelFor.cs
vendored
Normal file
@ -0,0 +1,77 @@
|
||||
// Licensed to the .NET Foundation under one or more agreements.
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using Xunit;
|
||||
|
||||
namespace System.Threading.Tasks.Tests
|
||||
{
|
||||
public static class ParallelForUnitTests
|
||||
{
|
||||
[Theory]
|
||||
[InlineData(API.For64, StartIndexBase.Int32, 0, WithParallelOption.None, ActionWithState.None, ActionWithLocal.None)]
|
||||
[InlineData(API.For64, StartIndexBase.Int32, 10, WithParallelOption.None, ActionWithState.Stop, ActionWithLocal.HasFinally)]
|
||||
[InlineData(API.For64, StartIndexBase.Int32, 10, WithParallelOption.WithDOP, ActionWithState.None, ActionWithLocal.None)]
|
||||
[InlineData(API.For64, StartIndexBase.Int32, 1, WithParallelOption.None, ActionWithState.Stop, ActionWithLocal.None)]
|
||||
[InlineData(API.For64, StartIndexBase.Int32, 1, WithParallelOption.WithDOP, ActionWithState.None, ActionWithLocal.HasFinally)]
|
||||
[InlineData(API.For64, StartIndexBase.Int32, 2, WithParallelOption.None, ActionWithState.None, ActionWithLocal.None)]
|
||||
[InlineData(API.For64, StartIndexBase.Int32, 2, WithParallelOption.WithDOP, ActionWithState.Stop, ActionWithLocal.HasFinally)]
|
||||
[InlineData(API.For64, StartIndexBase.Int32, 97, WithParallelOption.None, ActionWithState.None, ActionWithLocal.HasFinally)]
|
||||
[InlineData(API.For64, StartIndexBase.Int32, 97, WithParallelOption.WithDOP, ActionWithState.Stop, ActionWithLocal.None)]
|
||||
|
||||
[InlineData(API.For, StartIndexBase.Zero, 0, WithParallelOption.None, ActionWithState.None, ActionWithLocal.None)]
|
||||
[InlineData(API.For, StartIndexBase.Zero, 10, WithParallelOption.None, ActionWithState.None, ActionWithLocal.None)]
|
||||
[InlineData(API.For, StartIndexBase.Zero, 10, WithParallelOption.None, ActionWithState.Stop, ActionWithLocal.HasFinally)]
|
||||
[InlineData(API.For, StartIndexBase.Zero, 10, WithParallelOption.WithDOP, ActionWithState.None, ActionWithLocal.None)]
|
||||
[InlineData(API.For, StartIndexBase.Zero, 1, WithParallelOption.None, ActionWithState.Stop, ActionWithLocal.None)]
|
||||
[InlineData(API.For, StartIndexBase.Zero, 1, WithParallelOption.WithDOP, ActionWithState.None, ActionWithLocal.HasFinally)]
|
||||
[InlineData(API.For, StartIndexBase.Zero, 2, WithParallelOption.None, ActionWithState.None, ActionWithLocal.None)]
|
||||
[InlineData(API.For, StartIndexBase.Zero, 2, WithParallelOption.WithDOP, ActionWithState.Stop, ActionWithLocal.HasFinally)]
|
||||
[InlineData(API.For, StartIndexBase.Zero, 97, WithParallelOption.None, ActionWithState.Stop, ActionWithLocal.None)]
|
||||
[InlineData(API.For, StartIndexBase.Zero, 97, WithParallelOption.WithDOP, ActionWithState.None, ActionWithLocal.HasFinally)]
|
||||
|
||||
[InlineData(API.ForeachOnArray, StartIndexBase.Zero, 0, WithParallelOption.None, ActionWithState.None, ActionWithLocal.None)]
|
||||
[InlineData(API.ForeachOnArray, StartIndexBase.Zero, 10, WithParallelOption.None, ActionWithState.Stop, ActionWithLocal.None)]
|
||||
[InlineData(API.ForeachOnArray, StartIndexBase.Zero, 10, WithParallelOption.WithDOP, ActionWithState.None, ActionWithLocal.HasFinally)]
|
||||
[InlineData(API.ForeachOnArray, StartIndexBase.Zero, 1, WithParallelOption.None, ActionWithState.None, ActionWithLocal.HasFinally)]
|
||||
[InlineData(API.ForeachOnArray, StartIndexBase.Zero, 1, WithParallelOption.WithDOP, ActionWithState.Stop, ActionWithLocal.None)]
|
||||
[InlineData(API.ForeachOnArray, StartIndexBase.Zero, 2, WithParallelOption.None, ActionWithState.Stop, ActionWithLocal.None)]
|
||||
[InlineData(API.ForeachOnArray, StartIndexBase.Zero, 2, WithParallelOption.WithDOP, ActionWithState.None, ActionWithLocal.HasFinally)]
|
||||
[InlineData(API.ForeachOnArray, StartIndexBase.Zero, 97, WithParallelOption.None, ActionWithState.Stop, ActionWithLocal.HasFinally)]
|
||||
[InlineData(API.ForeachOnArray, StartIndexBase.Zero, 97, WithParallelOption.WithDOP, ActionWithState.None, ActionWithLocal.None)]
|
||||
|
||||
[InlineData(API.ForeachOnList, StartIndexBase.Zero, 0, WithParallelOption.None, ActionWithState.None, ActionWithLocal.None)]
|
||||
[InlineData(API.ForeachOnList, StartIndexBase.Zero, 10, WithParallelOption.None, ActionWithState.Stop, ActionWithLocal.HasFinally)]
|
||||
[InlineData(API.ForeachOnList, StartIndexBase.Zero, 10, WithParallelOption.WithDOP, ActionWithState.None, ActionWithLocal.None)]
|
||||
[InlineData(API.ForeachOnList, StartIndexBase.Zero, 1, WithParallelOption.None, ActionWithState.None, ActionWithLocal.HasFinally)]
|
||||
[InlineData(API.ForeachOnList, StartIndexBase.Zero, 1, WithParallelOption.WithDOP, ActionWithState.Stop, ActionWithLocal.None)]
|
||||
[InlineData(API.ForeachOnList, StartIndexBase.Zero, 2, WithParallelOption.None, ActionWithState.None, ActionWithLocal.HasFinally)]
|
||||
[InlineData(API.ForeachOnList, StartIndexBase.Zero, 2, WithParallelOption.WithDOP, ActionWithState.Stop, ActionWithLocal.None)]
|
||||
[InlineData(API.ForeachOnList, StartIndexBase.Zero, 97, WithParallelOption.None, ActionWithState.None, ActionWithLocal.None)]
|
||||
[InlineData(API.ForeachOnList, StartIndexBase.Zero, 97, WithParallelOption.WithDOP, ActionWithState.Stop, ActionWithLocal.HasFinally)]
|
||||
|
||||
[InlineData(API.Foreach, StartIndexBase.Zero, 0, WithParallelOption.None, ActionWithState.None, ActionWithLocal.None)]
|
||||
[InlineData(API.Foreach, StartIndexBase.Zero, 10, WithParallelOption.None, ActionWithState.None, ActionWithLocal.HasFinally)]
|
||||
[InlineData(API.Foreach, StartIndexBase.Zero, 10, WithParallelOption.None, ActionWithState.Stop, ActionWithLocal.None)]
|
||||
[InlineData(API.Foreach, StartIndexBase.Zero, 10, WithParallelOption.WithDOP, ActionWithState.Stop, ActionWithLocal.HasFinally)]
|
||||
[InlineData(API.Foreach, StartIndexBase.Zero, 1, WithParallelOption.None, ActionWithState.None, ActionWithLocal.None)]
|
||||
[InlineData(API.Foreach, StartIndexBase.Zero, 1, WithParallelOption.WithDOP, ActionWithState.Stop, ActionWithLocal.HasFinally)]
|
||||
[InlineData(API.Foreach, StartIndexBase.Zero, 2, WithParallelOption.None, ActionWithState.None, ActionWithLocal.HasFinally)]
|
||||
[InlineData(API.Foreach, StartIndexBase.Zero, 2, WithParallelOption.WithDOP, ActionWithState.None, ActionWithLocal.HasFinally)]
|
||||
[InlineData(API.Foreach, StartIndexBase.Zero, 2, WithParallelOption.WithDOP, ActionWithState.Stop, ActionWithLocal.None)]
|
||||
[InlineData(API.Foreach, StartIndexBase.Zero, 97, WithParallelOption.None, ActionWithState.None, ActionWithLocal.HasFinally)]
|
||||
[InlineData(API.Foreach, StartIndexBase.Zero, 97, WithParallelOption.WithDOP, ActionWithState.Stop, ActionWithLocal.None)]
|
||||
public static void ParrallelFor(API api, StartIndexBase startIndexBase, int count, WithParallelOption parallelOption, ActionWithState stateOption, ActionWithLocal localOption)
|
||||
{
|
||||
var parameters = new TestParameters(api, startIndexBase)
|
||||
{
|
||||
Count = count,
|
||||
ParallelOption = parallelOption,
|
||||
StateOption = stateOption,
|
||||
LocalOption = localOption
|
||||
};
|
||||
var test = new ParallelForTest(parameters);
|
||||
test.RealRun();
|
||||
}
|
||||
}
|
||||
}
|
76
external/corefx/src/System.Threading.Tasks.Parallel/tests/ParallelForBoundary.cs
vendored
Normal file
76
external/corefx/src/System.Threading.Tasks.Parallel/tests/ParallelForBoundary.cs
vendored
Normal file
@ -0,0 +1,76 @@
|
||||
// Licensed to the .NET Foundation under one or more agreements.
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using Xunit;
|
||||
|
||||
namespace System.Threading.Tasks.Tests
|
||||
{
|
||||
public static class ParallelForBoundaryUnitTests
|
||||
{
|
||||
[Theory]
|
||||
[OuterLoop]
|
||||
[InlineData(API.For64, StartIndexBase.Int16, -1000, 100, WorkloadPattern.Increasing)]
|
||||
[InlineData(API.For64, StartIndexBase.Int16, 0, 5, WorkloadPattern.Random)]
|
||||
[InlineData(API.For64, StartIndexBase.Int16, 100, 100, WorkloadPattern.Similar)]
|
||||
|
||||
[InlineData(API.For64, StartIndexBase.Int32, -1000, 5, WorkloadPattern.Increasing)]
|
||||
[InlineData(API.For64, StartIndexBase.Int32, 0, 5, WorkloadPattern.Decreasing)]
|
||||
[InlineData(API.For64, StartIndexBase.Int32, 0, 5, WorkloadPattern.Similar)]
|
||||
[InlineData(API.For64, StartIndexBase.Int32, 0, 100, WorkloadPattern.Increasing)]
|
||||
[InlineData(API.For64, StartIndexBase.Int32, 0, 100, WorkloadPattern.Random)]
|
||||
[InlineData(API.For64, StartIndexBase.Int32, 100, 5, WorkloadPattern.Decreasing)]
|
||||
[InlineData(API.For64, StartIndexBase.Int32, 100, 5, WorkloadPattern.Random)]
|
||||
[InlineData(API.For64, StartIndexBase.Int32, 100, 5, WorkloadPattern.Similar)]
|
||||
[InlineData(API.For64, StartIndexBase.Int32, 100, 100, WorkloadPattern.Increasing)]
|
||||
[InlineData(API.For64, StartIndexBase.Int32, 1000, 5, WorkloadPattern.Increasing)]
|
||||
[InlineData(API.For64, StartIndexBase.Int32, 1000, 5, WorkloadPattern.Similar)]
|
||||
[InlineData(API.For64, StartIndexBase.Int32, 1000, 100, WorkloadPattern.Decreasing)]
|
||||
[InlineData(API.For64, StartIndexBase.Int32, 1000, 100, WorkloadPattern.Random)]
|
||||
|
||||
[InlineData(API.For64, StartIndexBase.Int64, -1000, 100, WorkloadPattern.Decreasing)]
|
||||
[InlineData(API.For64, StartIndexBase.Int64, -1000, 100, WorkloadPattern.Increasing)]
|
||||
[InlineData(API.For64, StartIndexBase.Int64, -1000, 5, WorkloadPattern.Random)]
|
||||
[InlineData(API.For64, StartIndexBase.Int64, -100, 5, WorkloadPattern.Decreasing)]
|
||||
[InlineData(API.For64, StartIndexBase.Int64, -100, 5, WorkloadPattern.Increasing)]
|
||||
[InlineData(API.For64, StartIndexBase.Int64, -100, 5, WorkloadPattern.Similar)]
|
||||
[InlineData(API.For64, StartIndexBase.Int64, -100, 100, WorkloadPattern.Random)]
|
||||
[InlineData(API.For64, StartIndexBase.Int64, -100, 100, WorkloadPattern.Similar)]
|
||||
|
||||
[InlineData(API.For64, StartIndexBase.Zero, 0, 5, WorkloadPattern.Increasing)]
|
||||
[InlineData(API.For64, StartIndexBase.Zero, 0, 100, WorkloadPattern.Decreasing)]
|
||||
[InlineData(API.For64, StartIndexBase.Zero, 0, 100, WorkloadPattern.Similar)]
|
||||
[InlineData(API.For64, StartIndexBase.Zero, 100, 5, WorkloadPattern.Random)]
|
||||
|
||||
[InlineData(API.For, StartIndexBase.Int16, -100, 5, WorkloadPattern.Similar)]
|
||||
[InlineData(API.For, StartIndexBase.Int16, -1000, 5, WorkloadPattern.Similar)]
|
||||
[InlineData(API.For, StartIndexBase.Int16, -1000, 100, WorkloadPattern.Random)]
|
||||
[InlineData(API.For, StartIndexBase.Int16, 0, 5, WorkloadPattern.Increasing)]
|
||||
[InlineData(API.For, StartIndexBase.Int16, 0, 100, WorkloadPattern.Decreasing)]
|
||||
[InlineData(API.For, StartIndexBase.Int16, 100, 5, WorkloadPattern.Increasing)]
|
||||
[InlineData(API.For, StartIndexBase.Int16, 100, 100, WorkloadPattern.Random)]
|
||||
[InlineData(API.For, StartIndexBase.Int16, 1000, 5, WorkloadPattern.Decreasing)]
|
||||
[InlineData(API.For, StartIndexBase.Int16, 1000, 100, WorkloadPattern.Similar)]
|
||||
|
||||
[InlineData(API.For, StartIndexBase.Int32, -1000, 5, WorkloadPattern.Decreasing)]
|
||||
[InlineData(API.For, StartIndexBase.Int32, -100, 5, WorkloadPattern.Random)]
|
||||
[InlineData(API.For, StartIndexBase.Int32, -100, 100, WorkloadPattern.Decreasing)]
|
||||
[InlineData(API.For, StartIndexBase.Int32, -1000, 100, WorkloadPattern.Similar)]
|
||||
|
||||
[InlineData(API.For, StartIndexBase.Zero, 0, 5, WorkloadPattern.Similar)]
|
||||
[InlineData(API.For, StartIndexBase.Zero, 100, 100, WorkloadPattern.Decreasing)]
|
||||
[InlineData(API.For, StartIndexBase.Zero, 100, 100, WorkloadPattern.Random)]
|
||||
[InlineData(API.For, StartIndexBase.Zero, 1000, 5, WorkloadPattern.Decreasing)]
|
||||
[InlineData(API.For, StartIndexBase.Zero, 1000, 5, WorkloadPattern.Random)]
|
||||
public static void TestFor_Boundary(API api, StartIndexBase startIndexBase, int startIndexOffset, int count, WorkloadPattern workloadPattern)
|
||||
{
|
||||
var parameters = new TestParameters(api, startIndexBase, startIndexOffset)
|
||||
{
|
||||
Count = count,
|
||||
WorkloadPattern = workloadPattern,
|
||||
};
|
||||
var test = new ParallelForTest(parameters);
|
||||
test.RealRun();
|
||||
}
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user