##// END OF EJS Templates
Added implab nuget spec
cin -
r234:8dd666e6b6bf v2
parent child
Show More
@@ -0,0 +1,17
1 <?xml version="1.0"?>
2 <package >
3 <metadata>
4 <id>Implab</id>
5 <version>$version$</version>
6 <title>$title$</title>
7 <authors>Implab team</authors>
8 <owners>Implab team</owners>
9 <projectUrl>https://implab.org/</projectUrl>
10 <!-- <iconUrl>http://ICON_URL_HERE_OR_DELETE_THIS_LINE</iconUrl> -->
11 <requireLicenseAcceptance>false</requireLicenseAcceptance>
12 <description>Common components for asynchronous applications, tracing, logging, json and xml traits.</description>
13 <releaseNotes>Added strong name.</releaseNotes>
14 <copyright>Copyright 2017</copyright>
15 <tags>async xml json</tags>
16 </metadata>
17 </package> No newline at end of file
1 NO CONTENT: new file 100644, binary diff hidden
NO CONTENT: new file 100644, binary diff hidden
@@ -0,0 +1,22
1 ο»ΏCopyright 2012 Sergey Smirnov
2
3 Redistribution and use in source and binary forms, with or without
4 modification, are permitted provided that the following conditions are met:
5
6 1. Redistributions of source code must retain the above copyright notice, this
7 list of conditions and the following disclaimer.
8
9 2. Redistributions in binary form must reproduce the above copyright notice,
10 this list of conditions and the following disclaimer in the documentation
11 and/or other materials provided with the distribution.
12
13 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
14 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
15 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
16 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
17 FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
19 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
20 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
21 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
22 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. No newline at end of file
@@ -1,183 +1,182
1 using Implab.Formats.Json;
1 using Implab.Formats.Json;
2 using Implab.Parallels;
2 using Implab.Parallels;
3 using Implab.Xml;
3 using Implab.Xml;
4 using System;
4 using System;
5 using System.Collections.Concurrent;
5 using System.Collections.Concurrent;
6 using System.Collections.Generic;
6 using System.Collections.Generic;
7 using System.IO;
7 using System.IO;
8 using System.Linq;
8 using System.Linq;
9 using System.Text;
9 using System.Text;
10 using System.Threading;
10 using System.Threading;
11 using System.Threading.Tasks;
11 using System.Threading.Tasks;
12 using System.Xml;
12 using System.Xml;
13 using System.Xml.Serialization;
13 using System.Xml.Serialization;
14
14
15 namespace Implab.Playground {
15 namespace Implab.Playground {
16 public class Program {
16 public class Program {
17
17
18 static void EnqueueRange<T>(ConcurrentQueue<T> q, T[] data, int offset, int len) {
18 static void EnqueueRange<T>(ConcurrentQueue<T> q, T[] data, int offset, int len) {
19 for (var i = offset; i < offset + len; i++)
19 for (var i = offset; i < offset + len; i++)
20 q.Enqueue(data[i]);
20 q.Enqueue(data[i]);
21 }
21 }
22
22
23 static bool TryDequeueRange<T>(ConcurrentQueue<T> q,T[] buffer,int offset, int len, out int actual) {
23 static bool TryDequeueRange<T>(ConcurrentQueue<T> q,T[] buffer,int offset, int len, out int actual) {
24 actual = 0;
24 actual = 0;
25 T res;
25 T res;
26 while(q.TryDequeue(out res)) {
26 while(q.TryDequeue(out res)) {
27 buffer[offset + actual] = res;
27 buffer[offset + actual] = res;
28 actual++;
28 actual++;
29 if (actual == len)
29 if (actual == len)
30 break;
30 break;
31 }
31 }
32 return actual != 0;
32 return actual != 0;
33 }
33 }
34
34
35 static void EnqueueRange<T>(SimpleAsyncQueue<T> q, T[] data, int offset, int len) {
35 static void EnqueueRange<T>(SimpleAsyncQueue<T> q, T[] data, int offset, int len) {
36 for (var i = offset; i < offset + len; i++)
36 for (var i = offset; i < offset + len; i++)
37 q.Enqueue(data[i]);
37 q.Enqueue(data[i]);
38 }
38 }
39
39
40 static bool TryDequeueRange<T>(SimpleAsyncQueue<T> q, T[] buffer, int offset, int len, out int actual) {
40 static bool TryDequeueRange<T>(SimpleAsyncQueue<T> q, T[] buffer, int offset, int len, out int actual) {
41 actual = 0;
41 actual = 0;
42 T res;
42 T res;
43 while (q.TryDequeue(out res)) {
43 while (q.TryDequeue(out res)) {
44 buffer[offset + actual] = res;
44 buffer[offset + actual] = res;
45 actual++;
45 actual++;
46 if (actual == len)
46 if (actual == len)
47 break;
47 break;
48 }
48 }
49 return actual != 0;
49 return actual != 0;
50 }
50 }
51
51
52 /*
53 static void EnqueueRange<T>(AsyncQueue<T> q, T[] data, int offset, int len) {
52 static void EnqueueRange<T>(AsyncQueue<T> q, T[] data, int offset, int len) {
54 for (var i = offset; i < offset + len; i++)
53 for (var i = offset; i < offset + len; i++)
55 q.Enqueue(data[i]);
54 q.Enqueue(data[i]);
56 }
55 }
57
56
58 static bool TryDequeueRange<T>(AsyncQueue<T> q, T[] buffer, int offset, int len, out int actual) {
57 static bool TryDequeueRange<T>(AsyncQueue<T> q, T[] buffer, int offset, int len, out int actual) {
59 actual = 0;
58 actual = 0;
60 T res;
59 T res;
61 while (q.TryDequeue(out res)) {
60 while (q.TryDequeue(out res)) {
62 buffer[offset + actual] = res;
61 buffer[offset + actual] = res;
63 actual++;
62 actual++;
64 if (actual == len)
63 if (actual == len)
65 break;
64 break;
66 }
65 }
67 return actual != 0;
66 return actual != 0;
68 }
67 }
69 */
68
70
69
71 static void EnqueueRange<T>(AsyncQueue<T> q, T[] data, int offset, int len) {
70 /*static void EnqueueRange<T>(AsyncQueue<T> q, T[] data, int offset, int len) {
72 q.EnqueueRange(data, offset, len);
71 q.EnqueueRange(data, offset, len);
73 }
72 }
74
73
75 static bool TryDequeueRange<T>(AsyncQueue<T> q, T[] buffer, int offset, int len, out int actual) {
74 static bool TryDequeueRange<T>(AsyncQueue<T> q, T[] buffer, int offset, int len, out int actual) {
76 return q.TryDequeueRange(buffer, offset, len, out actual);
75 return q.TryDequeueRange(buffer, offset, len, out actual);
77 }
76 }*/
78
77
79
78
80 static void Main(string[] args) {
79 static void Main(string[] args) {
81
80
82 //var queue = new ConcurrentQueue<int>();
81 //var queue = new ConcurrentQueue<int>();
83 var queue = new AsyncQueue<int>();
82 var queue = new AsyncQueue<int>();
84 //var queue = new SimpleAsyncQueue<int>();
83 //var queue = new SimpleAsyncQueue<int>();
85
84
86 const int wBatch = 32;
85 const int wBatch = 32;
87 const long wCount = 1000000;
86 const long wCount = 1000000;
88 const long total = wBatch * wCount * 3;
87 const long total = wBatch * wCount * 3;
89
88
90 long r1 = 0, r2 = 0, r3 = 0;
89 long r1 = 0, r2 = 0, r3 = 0;
91 const int rBatch = 1000;
90 const int rBatch = 1000;
92 long read = 0;
91 long read = 0;
93
92
94 var t1 = Environment.TickCount;
93 var t1 = Environment.TickCount;
95
94
96 AsyncPool.RunThread(
95 AsyncPool.RunThread(
97 () => {
96 () => {
98 var buffer = new int[wBatch];
97 var buffer = new int[wBatch];
99 for (int i = 0; i < wBatch; i++)
98 for (int i = 0; i < wBatch; i++)
100 buffer[i] = 1;
99 buffer[i] = 1;
101
100
102 for (int i = 0; i < wCount; i++)
101 for (int i = 0; i < wCount; i++)
103 EnqueueRange(queue, buffer, 0, wBatch);
102 EnqueueRange(queue, buffer, 0, wBatch);
104 Console.WriteLine("done writer #1: {0} ms", Environment.TickCount - t1);
103 Console.WriteLine("done writer #1: {0} ms", Environment.TickCount - t1);
105 },
104 },
106 () => {
105 () => {
107 var buffer = new int[wBatch];
106 var buffer = new int[wBatch];
108 for (int i = 0; i < wBatch; i++)
107 for (int i = 0; i < wBatch; i++)
109 buffer[i] = 1;
108 buffer[i] = 1;
110
109
111 for (int i = 0; i < wCount; i++)
110 for (int i = 0; i < wCount; i++)
112 EnqueueRange(queue, buffer, 0, wBatch);
111 EnqueueRange(queue, buffer, 0, wBatch);
113 Console.WriteLine("done writer #2: {0} ms", Environment.TickCount - t1);
112 Console.WriteLine("done writer #2: {0} ms", Environment.TickCount - t1);
114 },
113 },
115 () => {
114 () => {
116 var buffer = new int[wBatch];
115 var buffer = new int[wBatch];
117 for (int i = 0; i < wBatch; i++)
116 for (int i = 0; i < wBatch; i++)
118 buffer[i] = 1;
117 buffer[i] = 1;
119
118
120 for (int i = 0; i < wCount; i++)
119 for (int i = 0; i < wCount; i++)
121 EnqueueRange(queue, buffer, 0, wBatch);
120 EnqueueRange(queue, buffer, 0, wBatch);
122 Console.WriteLine("done writer #3: {0} ms", Environment.TickCount - t1);
121 Console.WriteLine("done writer #3: {0} ms", Environment.TickCount - t1);
123 },
122 },
124 () => {
123 () => {
125 var buffer = new int[rBatch];
124 var buffer = new int[rBatch];
126
125
127 while (read < total) {
126 while (read < total) {
128 int actual;
127 int actual;
129 if (TryDequeueRange(queue, buffer, 0, rBatch, out actual)) {
128 if (TryDequeueRange(queue, buffer, 0, rBatch, out actual)) {
130 for (int i = 0; i < actual; i++)
129 for (int i = 0; i < actual; i++)
131 r1 += buffer[i];
130 r1 += buffer[i];
132 Interlocked.Add(ref read, actual);
131 Interlocked.Add(ref read, actual);
133 }
132 }
134 }
133 }
135
134
136 Console.WriteLine("done reader #1: {0} ms", Environment.TickCount - t1);
135 Console.WriteLine("done reader #1: {0} ms", Environment.TickCount - t1);
137 }/*,
136 }/*,
138 () => {
137 () => {
139 var buffer = new int[rBatch];
138 var buffer = new int[rBatch];
140
139
141 while (read < total) {
140 while (read < total) {
142 int actual;
141 int actual;
143 if (TryDequeueRange(queue, buffer, 0, rBatch, out actual)) {
142 if (TryDequeueRange(queue, buffer, 0, rBatch, out actual)) {
144 for (int i = 0; i < actual; i++)
143 for (int i = 0; i < actual; i++)
145 r2 += buffer[i];
144 r2 += buffer[i];
146 Interlocked.Add(ref read, actual);
145 Interlocked.Add(ref read, actual);
147 }
146 }
148 }
147 }
149
148
150 Console.WriteLine("done reader #2: {0} ms", Environment.TickCount - t1);
149 Console.WriteLine("done reader #2: {0} ms", Environment.TickCount - t1);
151 }*//*,
150 }*//*,
152 () => {
151 () => {
153 var buffer = new int[rBatch];
152 var buffer = new int[rBatch];
154
153
155 while (read < total) {
154 while (read < total) {
156 int actual;
155 int actual;
157 if (TryDequeueRange(queue, buffer, 0, rBatch, out actual)) {
156 if (TryDequeueRange(queue, buffer, 0, rBatch, out actual)) {
158 for (int i = 0; i < actual; i++)
157 for (int i = 0; i < actual; i++)
159 r3 += buffer[i];
158 r3 += buffer[i];
160 Interlocked.Add(ref read, actual);
159 Interlocked.Add(ref read, actual);
161 }
160 }
162 }
161 }
163
162
164 Console.WriteLine("done reader #3: {0} ms", Environment.TickCount - t1);
163 Console.WriteLine("done reader #3: {0} ms", Environment.TickCount - t1);
165 }*/
164 }*/
166 )
165 )
167 .PromiseAll()
166 .PromiseAll()
168 .Join();
167 .Join();
169
168
170
169
171 Console.WriteLine(
170 Console.WriteLine(
172 "done: {0} ms, summ#1: {1}, summ#2: {2}, total: {3}, count: {4}",
171 "done: {0} ms, summ#1: {1}, summ#2: {2}, total: {3}, count: {4}",
173 Environment.TickCount - t1,
172 Environment.TickCount - t1,
174 r1,
173 r1,
175 r2,
174 r2,
176 r1 + r2 + r3,
175 r1 + r2 + r3,
177 total
176 total
178 );
177 );
179
178
180 Console.WriteLine("done");
179 Console.WriteLine("done");
181 }
180 }
182 }
181 }
183 }
182 }
@@ -1,283 +1,296
1 ο»Ώ<?xml version="1.0" encoding="utf-8"?>
1 ο»Ώ<?xml version="1.0" encoding="utf-8"?>
2 <Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
2 <Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
3 <PropertyGroup>
3 <PropertyGroup>
4 <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
4 <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
5 <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
5 <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
6 <ProjectGuid>{F550F1F8-8746-4AD0-9614-855F4C4B7F05}</ProjectGuid>
6 <ProjectGuid>{F550F1F8-8746-4AD0-9614-855F4C4B7F05}</ProjectGuid>
7 <OutputType>Library</OutputType>
7 <OutputType>Library</OutputType>
8 <RootNamespace>Implab</RootNamespace>
8 <RootNamespace>Implab</RootNamespace>
9 <AssemblyName>Implab</AssemblyName>
9 <AssemblyName>Implab</AssemblyName>
10 <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
10 <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
11 <TargetFrameworkProfile />
11 <TargetFrameworkProfile />
12 </PropertyGroup>
12 </PropertyGroup>
13 <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
13 <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
14 <DebugSymbols>true</DebugSymbols>
14 <DebugSymbols>true</DebugSymbols>
15 <DebugType>full</DebugType>
15 <DebugType>full</DebugType>
16 <Optimize>false</Optimize>
16 <Optimize>false</Optimize>
17 <OutputPath>bin\Debug</OutputPath>
17 <OutputPath>bin\Debug</OutputPath>
18 <DefineConstants>TRACE;DEBUG;</DefineConstants>
18 <DefineConstants>TRACE;DEBUG;</DefineConstants>
19 <ErrorReport>prompt</ErrorReport>
19 <ErrorReport>prompt</ErrorReport>
20 <WarningLevel>4</WarningLevel>
20 <WarningLevel>4</WarningLevel>
21 <ConsolePause>false</ConsolePause>
21 <ConsolePause>false</ConsolePause>
22 <RunCodeAnalysis>true</RunCodeAnalysis>
22 <RunCodeAnalysis>true</RunCodeAnalysis>
23 </PropertyGroup>
23 </PropertyGroup>
24 <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
24 <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
25 <DebugType>full</DebugType>
25 <DebugType>full</DebugType>
26 <Optimize>true</Optimize>
26 <Optimize>true</Optimize>
27 <OutputPath>bin\Release</OutputPath>
27 <OutputPath>bin\Release</OutputPath>
28 <ErrorReport>prompt</ErrorReport>
28 <ErrorReport>prompt</ErrorReport>
29 <WarningLevel>4</WarningLevel>
29 <WarningLevel>4</WarningLevel>
30 <ConsolePause>false</ConsolePause>
30 <ConsolePause>false</ConsolePause>
31 </PropertyGroup>
31 </PropertyGroup>
32 <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug 4.5|AnyCPU' ">
32 <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug 4.5|AnyCPU' ">
33 <DebugSymbols>true</DebugSymbols>
33 <DebugSymbols>true</DebugSymbols>
34 <DebugType>full</DebugType>
34 <DebugType>full</DebugType>
35 <Optimize>false</Optimize>
35 <Optimize>false</Optimize>
36 <OutputPath>bin\Debug</OutputPath>
36 <OutputPath>bin\Debug</OutputPath>
37 <DefineConstants>TRACE;DEBUG;NET_4_5</DefineConstants>
37 <DefineConstants>TRACE;DEBUG;NET_4_5</DefineConstants>
38 <ErrorReport>prompt</ErrorReport>
38 <ErrorReport>prompt</ErrorReport>
39 <WarningLevel>4</WarningLevel>
39 <WarningLevel>4</WarningLevel>
40 <RunCodeAnalysis>true</RunCodeAnalysis>
40 <RunCodeAnalysis>true</RunCodeAnalysis>
41 <ConsolePause>false</ConsolePause>
41 <ConsolePause>false</ConsolePause>
42 </PropertyGroup>
42 </PropertyGroup>
43 <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release 4.5|AnyCPU' ">
43 <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release 4.5|AnyCPU' ">
44 <Optimize>true</Optimize>
44 <Optimize>true</Optimize>
45 <OutputPath>bin\Release</OutputPath>
45 <OutputPath>bin\Release</OutputPath>
46 <ErrorReport>prompt</ErrorReport>
46 <ErrorReport>prompt</ErrorReport>
47 <WarningLevel>4</WarningLevel>
47 <WarningLevel>4</WarningLevel>
48 <ConsolePause>false</ConsolePause>
48 <ConsolePause>false</ConsolePause>
49 <DefineConstants>NET_4_5</DefineConstants>
49 <DefineConstants>NET_4_5</DefineConstants>
50 </PropertyGroup>
50 </PropertyGroup>
51 <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'DebugMono|AnyCPU' ">
51 <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'DebugMono|AnyCPU' ">
52 <DebugSymbols>true</DebugSymbols>
52 <DebugSymbols>true</DebugSymbols>
53 <DebugType>full</DebugType>
53 <DebugType>full</DebugType>
54 <Optimize>false</Optimize>
54 <Optimize>false</Optimize>
55 <OutputPath>bin\Debug</OutputPath>
55 <OutputPath>bin\Debug</OutputPath>
56 <DefineConstants>TRACE;DEBUG;NET_4_5;MONO</DefineConstants>
56 <DefineConstants>TRACE;DEBUG;NET_4_5;MONO</DefineConstants>
57 <ErrorReport>prompt</ErrorReport>
57 <ErrorReport>prompt</ErrorReport>
58 <WarningLevel>4</WarningLevel>
58 <WarningLevel>4</WarningLevel>
59 <RunCodeAnalysis>true</RunCodeAnalysis>
59 <RunCodeAnalysis>true</RunCodeAnalysis>
60 <ConsolePause>false</ConsolePause>
60 <ConsolePause>false</ConsolePause>
61 </PropertyGroup>
61 </PropertyGroup>
62 <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'ReleaseMono|AnyCPU' ">
62 <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'ReleaseMono|AnyCPU' ">
63 <Optimize>true</Optimize>
63 <Optimize>true</Optimize>
64 <OutputPath>bin\Release</OutputPath>
64 <OutputPath>bin\Release</OutputPath>
65 <DefineConstants>NET_4_5;MONO;</DefineConstants>
65 <DefineConstants>NET_4_5;MONO;</DefineConstants>
66 <ErrorReport>prompt</ErrorReport>
66 <ErrorReport>prompt</ErrorReport>
67 <WarningLevel>4</WarningLevel>
67 <WarningLevel>4</WarningLevel>
68 <ConsolePause>false</ConsolePause>
68 <ConsolePause>false</ConsolePause>
69 </PropertyGroup>
69 </PropertyGroup>
70 <PropertyGroup>
71 <SignAssembly>true</SignAssembly>
72 </PropertyGroup>
73 <PropertyGroup>
74 <AssemblyOriginatorKeyFile>implab.snk</AssemblyOriginatorKeyFile>
75 </PropertyGroup>
70 <ItemGroup>
76 <ItemGroup>
71 <Reference Include="System" />
77 <Reference Include="System" />
72 <Reference Include="System.Xml" />
78 <Reference Include="System.Xml" />
73 <Reference Include="mscorlib" />
79 <Reference Include="mscorlib" />
74 <Reference Include="System.Xml.Linq" />
80 <Reference Include="System.Xml.Linq" />
75 </ItemGroup>
81 </ItemGroup>
76 <ItemGroup>
82 <ItemGroup>
77 <Compile Include="Components\StateChangeEventArgs.cs" />
83 <Compile Include="Components\StateChangeEventArgs.cs" />
78 <Compile Include="CustomEqualityComparer.cs" />
84 <Compile Include="CustomEqualityComparer.cs" />
79 <Compile Include="Diagnostics\ConsoleTraceListener.cs" />
85 <Compile Include="Diagnostics\ConsoleTraceListener.cs" />
80 <Compile Include="Diagnostics\LogChannel.cs" />
86 <Compile Include="Diagnostics\LogChannel.cs" />
81 <Compile Include="Diagnostics\LogicalOperation.cs" />
87 <Compile Include="Diagnostics\LogicalOperation.cs" />
82 <Compile Include="Diagnostics\TextFileListener.cs" />
88 <Compile Include="Diagnostics\TextFileListener.cs" />
83 <Compile Include="Diagnostics\Trace.cs" />
89 <Compile Include="Diagnostics\Trace.cs" />
84 <Compile Include="Diagnostics\TraceLog.cs" />
90 <Compile Include="Diagnostics\TraceLog.cs" />
85 <Compile Include="Diagnostics\TraceEvent.cs" />
91 <Compile Include="Diagnostics\TraceEvent.cs" />
86 <Compile Include="Diagnostics\TraceEventType.cs" />
92 <Compile Include="Diagnostics\TraceEventType.cs" />
87 <Compile Include="Diagnostics\TraceSourceAttribute.cs" />
93 <Compile Include="Diagnostics\TraceSourceAttribute.cs" />
88 <Compile Include="Formats\CharMap.cs" />
94 <Compile Include="Formats\CharMap.cs" />
89 <Compile Include="Formats\InputScanner.cs" />
95 <Compile Include="Formats\InputScanner.cs" />
90 <Compile Include="Formats\Json\JsonStringScanner.cs" />
96 <Compile Include="Formats\Json\JsonStringScanner.cs" />
91 <Compile Include="Formats\Json\JsonTextScanner.cs" />
97 <Compile Include="Formats\Json\JsonTextScanner.cs" />
92 <Compile Include="ICancellable.cs" />
98 <Compile Include="ICancellable.cs" />
93 <Compile Include="IProgressHandler.cs" />
99 <Compile Include="IProgressHandler.cs" />
94 <Compile Include="IProgressNotifier.cs" />
100 <Compile Include="IProgressNotifier.cs" />
95 <Compile Include="IPromiseT.cs" />
101 <Compile Include="IPromiseT.cs" />
96 <Compile Include="IPromise.cs" />
102 <Compile Include="IPromise.cs" />
97 <Compile Include="IServiceLocator.cs" />
103 <Compile Include="IServiceLocator.cs" />
98 <Compile Include="ITaskController.cs" />
104 <Compile Include="ITaskController.cs" />
99 <Compile Include="Parallels\DispatchPool.cs" />
105 <Compile Include="Parallels\DispatchPool.cs" />
100 <Compile Include="Parallels\ArrayTraits.cs" />
106 <Compile Include="Parallels\ArrayTraits.cs" />
101 <Compile Include="Parallels\SimpleAsyncQueue.cs" />
107 <Compile Include="Parallels\SimpleAsyncQueue.cs" />
102 <Compile Include="Parallels\WorkerPool.cs" />
108 <Compile Include="Parallels\WorkerPool.cs" />
103 <Compile Include="ProgressInitEventArgs.cs" />
109 <Compile Include="ProgressInitEventArgs.cs" />
104 <Compile Include="Properties\AssemblyInfo.cs" />
110 <Compile Include="Properties\AssemblyInfo.cs" />
105 <Compile Include="Parallels\AsyncPool.cs" />
111 <Compile Include="Parallels\AsyncPool.cs" />
106 <Compile Include="Safe.cs" />
112 <Compile Include="Safe.cs" />
107 <Compile Include="SyncContextPromise.cs" />
113 <Compile Include="SyncContextPromise.cs" />
108 <Compile Include="ValueEventArgs.cs" />
114 <Compile Include="ValueEventArgs.cs" />
109 <Compile Include="PromiseExtensions.cs" />
115 <Compile Include="PromiseExtensions.cs" />
110 <Compile Include="SyncContextPromiseT.cs" />
116 <Compile Include="SyncContextPromiseT.cs" />
111 <Compile Include="Diagnostics\OperationContext.cs" />
117 <Compile Include="Diagnostics\OperationContext.cs" />
112 <Compile Include="Diagnostics\TraceContext.cs" />
118 <Compile Include="Diagnostics\TraceContext.cs" />
113 <Compile Include="Diagnostics\LogEventArgs.cs" />
119 <Compile Include="Diagnostics\LogEventArgs.cs" />
114 <Compile Include="Diagnostics\LogEventArgsT.cs" />
120 <Compile Include="Diagnostics\LogEventArgsT.cs" />
115 <Compile Include="Diagnostics\Extensions.cs" />
121 <Compile Include="Diagnostics\Extensions.cs" />
116 <Compile Include="PromiseEventType.cs" />
122 <Compile Include="PromiseEventType.cs" />
117 <Compile Include="Parallels\AsyncQueue.cs" />
123 <Compile Include="Parallels\AsyncQueue.cs" />
118 <Compile Include="PromiseT.cs" />
124 <Compile Include="PromiseT.cs" />
119 <Compile Include="IDeferred.cs" />
125 <Compile Include="IDeferred.cs" />
120 <Compile Include="IDeferredT.cs" />
126 <Compile Include="IDeferredT.cs" />
121 <Compile Include="Promise.cs" />
127 <Compile Include="Promise.cs" />
122 <Compile Include="PromiseTransientException.cs" />
128 <Compile Include="PromiseTransientException.cs" />
123 <Compile Include="Parallels\Signal.cs" />
129 <Compile Include="Parallels\Signal.cs" />
124 <Compile Include="Parallels\SharedLock.cs" />
130 <Compile Include="Parallels\SharedLock.cs" />
125 <Compile Include="Diagnostics\ILogWriter.cs" />
131 <Compile Include="Diagnostics\ILogWriter.cs" />
126 <Compile Include="Diagnostics\ListenerBase.cs" />
132 <Compile Include="Diagnostics\ListenerBase.cs" />
127 <Compile Include="Parallels\BlockingQueue.cs" />
133 <Compile Include="Parallels\BlockingQueue.cs" />
128 <Compile Include="AbstractEvent.cs" />
134 <Compile Include="AbstractEvent.cs" />
129 <Compile Include="AbstractPromise.cs" />
135 <Compile Include="AbstractPromise.cs" />
130 <Compile Include="AbstractPromiseT.cs" />
136 <Compile Include="AbstractPromiseT.cs" />
131 <Compile Include="FuncTask.cs" />
137 <Compile Include="FuncTask.cs" />
132 <Compile Include="FuncTaskBase.cs" />
138 <Compile Include="FuncTaskBase.cs" />
133 <Compile Include="FuncTaskT.cs" />
139 <Compile Include="FuncTaskT.cs" />
134 <Compile Include="ActionChainTaskBase.cs" />
140 <Compile Include="ActionChainTaskBase.cs" />
135 <Compile Include="ActionChainTask.cs" />
141 <Compile Include="ActionChainTask.cs" />
136 <Compile Include="ActionChainTaskT.cs" />
142 <Compile Include="ActionChainTaskT.cs" />
137 <Compile Include="FuncChainTaskBase.cs" />
143 <Compile Include="FuncChainTaskBase.cs" />
138 <Compile Include="FuncChainTask.cs" />
144 <Compile Include="FuncChainTask.cs" />
139 <Compile Include="FuncChainTaskT.cs" />
145 <Compile Include="FuncChainTaskT.cs" />
140 <Compile Include="ActionTaskBase.cs" />
146 <Compile Include="ActionTaskBase.cs" />
141 <Compile Include="ActionTask.cs" />
147 <Compile Include="ActionTask.cs" />
142 <Compile Include="ActionTaskT.cs" />
148 <Compile Include="ActionTaskT.cs" />
143 <Compile Include="ICancellationToken.cs" />
149 <Compile Include="ICancellationToken.cs" />
144 <Compile Include="SuccessPromise.cs" />
150 <Compile Include="SuccessPromise.cs" />
145 <Compile Include="SuccessPromiseT.cs" />
151 <Compile Include="SuccessPromiseT.cs" />
146 <Compile Include="PromiseAwaiterT.cs" />
152 <Compile Include="PromiseAwaiterT.cs" />
147 <Compile Include="PromiseAwaiter.cs" />
153 <Compile Include="PromiseAwaiter.cs" />
148 <Compile Include="Components\ComponentContainer.cs" />
154 <Compile Include="Components\ComponentContainer.cs" />
149 <Compile Include="Components\Disposable.cs" />
155 <Compile Include="Components\Disposable.cs" />
150 <Compile Include="Components\DisposablePool.cs" />
156 <Compile Include="Components\DisposablePool.cs" />
151 <Compile Include="Components\ObjectPool.cs" />
157 <Compile Include="Components\ObjectPool.cs" />
152 <Compile Include="Components\ServiceLocator.cs" />
158 <Compile Include="Components\ServiceLocator.cs" />
153 <Compile Include="Components\IInitializable.cs" />
159 <Compile Include="Components\IInitializable.cs" />
154 <Compile Include="TaskController.cs" />
160 <Compile Include="TaskController.cs" />
155 <Compile Include="Components\App.cs" />
161 <Compile Include="Components\App.cs" />
156 <Compile Include="Components\IRunnable.cs" />
162 <Compile Include="Components\IRunnable.cs" />
157 <Compile Include="Components\ExecutionState.cs" />
163 <Compile Include="Components\ExecutionState.cs" />
158 <Compile Include="Components\RunnableComponent.cs" />
164 <Compile Include="Components\RunnableComponent.cs" />
159 <Compile Include="Components\IFactory.cs" />
165 <Compile Include="Components\IFactory.cs" />
160 <Compile Include="Automaton\IAlphabet.cs" />
166 <Compile Include="Automaton\IAlphabet.cs" />
161 <Compile Include="Automaton\ParserException.cs" />
167 <Compile Include="Automaton\ParserException.cs" />
162 <Compile Include="Automaton\IndexedAlphabetBase.cs" />
168 <Compile Include="Automaton\IndexedAlphabetBase.cs" />
163 <Compile Include="Automaton\IAlphabetBuilder.cs" />
169 <Compile Include="Automaton\IAlphabetBuilder.cs" />
164 <Compile Include="Automaton\RegularExpressions\AltToken.cs" />
170 <Compile Include="Automaton\RegularExpressions\AltToken.cs" />
165 <Compile Include="Automaton\RegularExpressions\BinaryToken.cs" />
171 <Compile Include="Automaton\RegularExpressions\BinaryToken.cs" />
166 <Compile Include="Automaton\RegularExpressions\CatToken.cs" />
172 <Compile Include="Automaton\RegularExpressions\CatToken.cs" />
167 <Compile Include="Automaton\RegularExpressions\StarToken.cs" />
173 <Compile Include="Automaton\RegularExpressions\StarToken.cs" />
168 <Compile Include="Automaton\RegularExpressions\SymbolToken.cs" />
174 <Compile Include="Automaton\RegularExpressions\SymbolToken.cs" />
169 <Compile Include="Automaton\RegularExpressions\EmptyToken.cs" />
175 <Compile Include="Automaton\RegularExpressions\EmptyToken.cs" />
170 <Compile Include="Automaton\RegularExpressions\Token.cs" />
176 <Compile Include="Automaton\RegularExpressions\Token.cs" />
171 <Compile Include="Automaton\RegularExpressions\IVisitor.cs" />
177 <Compile Include="Automaton\RegularExpressions\IVisitor.cs" />
172 <Compile Include="Automaton\AutomatonTransition.cs" />
178 <Compile Include="Automaton\AutomatonTransition.cs" />
173 <Compile Include="Formats\Json\JsonElementContext.cs" />
179 <Compile Include="Formats\Json\JsonElementContext.cs" />
174 <Compile Include="Formats\Json\JsonElementType.cs" />
180 <Compile Include="Formats\Json\JsonElementType.cs" />
175 <Compile Include="Formats\Json\JsonGrammar.cs" />
181 <Compile Include="Formats\Json\JsonGrammar.cs" />
176 <Compile Include="Formats\Json\JsonReader.cs" />
182 <Compile Include="Formats\Json\JsonReader.cs" />
177 <Compile Include="Formats\Json\JsonScanner.cs" />
183 <Compile Include="Formats\Json\JsonScanner.cs" />
178 <Compile Include="Formats\Json\JsonTokenType.cs" />
184 <Compile Include="Formats\Json\JsonTokenType.cs" />
179 <Compile Include="Formats\Json\JsonWriter.cs" />
185 <Compile Include="Formats\Json\JsonWriter.cs" />
180 <Compile Include="Formats\Json\StringTranslator.cs" />
186 <Compile Include="Formats\Json\StringTranslator.cs" />
181 <Compile Include="Automaton\MapAlphabet.cs" />
187 <Compile Include="Automaton\MapAlphabet.cs" />
182 <Compile Include="Formats\CharAlphabet.cs" />
188 <Compile Include="Formats\CharAlphabet.cs" />
183 <Compile Include="Formats\ByteAlphabet.cs" />
189 <Compile Include="Formats\ByteAlphabet.cs" />
184 <Compile Include="Automaton\IDFATable.cs" />
190 <Compile Include="Automaton\IDFATable.cs" />
185 <Compile Include="Automaton\IDFATableBuilder.cs" />
191 <Compile Include="Automaton\IDFATableBuilder.cs" />
186 <Compile Include="Automaton\DFATable.cs" />
192 <Compile Include="Automaton\DFATable.cs" />
187 <Compile Include="Automaton\RegularExpressions\RegularExpressionVisitor.cs" />
193 <Compile Include="Automaton\RegularExpressions\RegularExpressionVisitor.cs" />
188 <Compile Include="Automaton\RegularExpressions\ITaggedDFABuilder.cs" />
194 <Compile Include="Automaton\RegularExpressions\ITaggedDFABuilder.cs" />
189 <Compile Include="Formats\Grammar.cs" />
195 <Compile Include="Formats\Grammar.cs" />
190 <Compile Include="Automaton\RegularExpressions\EndTokenT.cs" />
196 <Compile Include="Automaton\RegularExpressions\EndTokenT.cs" />
191 <Compile Include="Automaton\RegularExpressions\EndToken.cs" />
197 <Compile Include="Automaton\RegularExpressions\EndToken.cs" />
192 <Compile Include="Automaton\RegularExpressions\RegularExpressionVisitorT.cs" />
198 <Compile Include="Automaton\RegularExpressions\RegularExpressionVisitorT.cs" />
193 <Compile Include="Automaton\AutomatonConst.cs" />
199 <Compile Include="Automaton\AutomatonConst.cs" />
194 <Compile Include="Automaton\RegularExpressions\RegularDFA.cs" />
200 <Compile Include="Automaton\RegularExpressions\RegularDFA.cs" />
195 <Compile Include="Components\LazyAndWeak.cs" />
201 <Compile Include="Components\LazyAndWeak.cs" />
196 <Compile Include="AbstractTask.cs" />
202 <Compile Include="AbstractTask.cs" />
197 <Compile Include="AbstractTaskT.cs" />
203 <Compile Include="AbstractTaskT.cs" />
198 <Compile Include="FailedPromise.cs" />
204 <Compile Include="FailedPromise.cs" />
199 <Compile Include="FailedPromiseT.cs" />
205 <Compile Include="FailedPromiseT.cs" />
200 <Compile Include="Components\PollingComponent.cs" />
206 <Compile Include="Components\PollingComponent.cs" />
201 <Compile Include="Xml\JsonXmlReader.cs" />
207 <Compile Include="Xml\JsonXmlReader.cs" />
202 <Compile Include="Xml\JsonXmlReaderOptions.cs" />
208 <Compile Include="Xml\JsonXmlReaderOptions.cs" />
203 <Compile Include="Xml\JsonXmlReaderPosition.cs" />
209 <Compile Include="Xml\JsonXmlReaderPosition.cs" />
204 <Compile Include="Xml\SerializationHelpers.cs" />
210 <Compile Include="Xml\SerializationHelpers.cs" />
205 <Compile Include="Xml\SerializersPool.cs" />
211 <Compile Include="Xml\SerializersPool.cs" />
206 <Compile Include="Xml\XmlSimpleAttribute.cs" />
212 <Compile Include="Xml\XmlSimpleAttribute.cs" />
207 <Compile Include="Xml\XmlNameContext.cs" />
213 <Compile Include="Xml\XmlNameContext.cs" />
208 </ItemGroup>
214 </ItemGroup>
209 <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
215 <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
210 <ItemGroup />
216 <ItemGroup>
217 <None Include="Implab.nuspec">
218 <SubType>Designer</SubType>
219 </None>
220 <None Include="implab.snk" />
221 </ItemGroup>
211 <ProjectExtensions>
222 <ProjectExtensions>
212 <MonoDevelop>
223 <MonoDevelop>
213 <Properties>
224 <Properties>
214 <Policies>
225 <Policies>
215 <CSharpFormattingPolicy IndentBlock="True" IndentBraces="False" IndentSwitchSection="False" IndentSwitchCaseSection="True" LabelPositioning="OneLess" NewLinesForBracesInProperties="False" NewLinesForBracesInAccessors="False" NewLinesForBracesInAnonymousMethods="False" NewLinesForBracesInControlBlocks="False" NewLinesForBracesInAnonymousTypes="False" NewLinesForBracesInObjectCollectionArrayInitializers="False" NewLinesForBracesInLambdaExpressionBody="False" NewLineForElse="False" NewLineForCatch="False" NewLineForFinally="False" NewLineForMembersInObjectInit="False" NewLineForMembersInAnonymousTypes="False" NewLineForClausesInQuery="False" SpaceWithinMethodDeclarationParenthesis="False" SpaceBetweenEmptyMethodDeclarationParentheses="False" SpaceWithinMethodCallParentheses="False" SpaceBetweenEmptyMethodCallParentheses="False" SpaceAfterControlFlowStatementKeyword="True" SpaceWithinExpressionParentheses="False" SpaceWithinCastParentheses="False" SpaceWithinOtherParentheses="False" SpaceAfterCast="False" SpacesIgnoreAroundVariableDeclaration="False" SpaceBetweenEmptySquareBrackets="False" SpaceWithinSquareBrackets="False" SpaceAfterColonInBaseTypeDeclaration="True" SpaceAfterComma="True" SpaceAfterDot="False" SpaceAfterSemicolonsInForStatement="True" SpaceBeforeComma="False" SpaceBeforeDot="False" SpaceBeforeSemicolonsInForStatement="False" SpacingAroundBinaryOperator="Single" WrappingPreserveSingleLine="True" WrappingKeepStatementsOnSingleLine="True" PlaceSystemDirectiveFirst="True" NewLinesForBracesInTypes="True" NewLinesForBracesInMethods="True" SpacingAfterMethodDeclarationName="True" SpaceAfterMethodCallName="True" SpaceBeforeOpenSquareBracket="True" SpaceBeforeColonInBaseTypeDeclaration="True" scope="text/x-csharp" />
226 <CSharpFormattingPolicy IndentBlock="True" IndentBraces="False" IndentSwitchSection="False" IndentSwitchCaseSection="True" LabelPositioning="OneLess" NewLinesForBracesInProperties="False" NewLinesForBracesInAccessors="False" NewLinesForBracesInAnonymousMethods="False" NewLinesForBracesInControlBlocks="False" NewLinesForBracesInAnonymousTypes="False" NewLinesForBracesInObjectCollectionArrayInitializers="False" NewLinesForBracesInLambdaExpressionBody="False" NewLineForElse="False" NewLineForCatch="False" NewLineForFinally="False" NewLineForMembersInObjectInit="False" NewLineForMembersInAnonymousTypes="False" NewLineForClausesInQuery="False" SpaceWithinMethodDeclarationParenthesis="False" SpaceBetweenEmptyMethodDeclarationParentheses="False" SpaceWithinMethodCallParentheses="False" SpaceBetweenEmptyMethodCallParentheses="False" SpaceAfterControlFlowStatementKeyword="True" SpaceWithinExpressionParentheses="False" SpaceWithinCastParentheses="False" SpaceWithinOtherParentheses="False" SpaceAfterCast="False" SpacesIgnoreAroundVariableDeclaration="False" SpaceBetweenEmptySquareBrackets="False" SpaceWithinSquareBrackets="False" SpaceAfterColonInBaseTypeDeclaration="True" SpaceAfterComma="True" SpaceAfterDot="False" SpaceAfterSemicolonsInForStatement="True" SpaceBeforeComma="False" SpaceBeforeDot="False" SpaceBeforeSemicolonsInForStatement="False" SpacingAroundBinaryOperator="Single" WrappingPreserveSingleLine="True" WrappingKeepStatementsOnSingleLine="True" PlaceSystemDirectiveFirst="True" NewLinesForBracesInTypes="True" NewLinesForBracesInMethods="True" SpacingAfterMethodDeclarationName="True" SpaceAfterMethodCallName="True" SpaceBeforeOpenSquareBracket="True" SpaceBeforeColonInBaseTypeDeclaration="True" scope="text/x-csharp" />
216 <TextStylePolicy FileWidth="120" TabWidth="4" IndentWidth="4" RemoveTrailingWhitespace="True" NoTabsAfterNonTabs="False" TabsToSpaces="True" EolMarker="Unix" scope="text/x-csharp" />
227 <TextStylePolicy FileWidth="120" TabWidth="4" IndentWidth="4" RemoveTrailingWhitespace="True" NoTabsAfterNonTabs="False" TabsToSpaces="True" EolMarker="Unix" scope="text/x-csharp" />
217 <DotNetNamingPolicy DirectoryNamespaceAssociation="PrefixedHierarchical" ResourceNamePolicy="MSBuild" />
228 <DotNetNamingPolicy DirectoryNamespaceAssociation="PrefixedHierarchical" ResourceNamePolicy="MSBuild" />
218 <TextStylePolicy FileWidth="120" TabWidth="4" TabsToSpaces="False" IndentWidth="4" RemoveTrailingWhitespace="True" NoTabsAfterNonTabs="False" EolMarker="Native" scope="application/xml" />
229 <TextStylePolicy FileWidth="120" TabWidth="4" TabsToSpaces="False" IndentWidth="4" RemoveTrailingWhitespace="True" NoTabsAfterNonTabs="False" EolMarker="Native" scope="application/xml" />
219 <XmlFormattingPolicy scope="application/xml">
230 <XmlFormattingPolicy scope="application/xml">
220 <DefaultFormat OmitXmlDeclaration="False" NewLineChars="&#xA;" IndentContent="True" ContentIndentString=" " AttributesInNewLine="False" MaxAttributesPerLine="10" AttributesIndentString=" " WrapAttributes="False" AlignAttributes="False" AlignAttributeValues="False" QuoteChar="&quot;" SpacesBeforeAssignment="0" SpacesAfterAssignment="0" EmptyLinesBeforeStart="0" EmptyLinesAfterStart="0" EmptyLinesBeforeEnd="0" EmptyLinesAfterEnd="0" />
231 <DefaultFormat OmitXmlDeclaration="False" NewLineChars="&#xA;" IndentContent="True" ContentIndentString=" " AttributesInNewLine="False" MaxAttributesPerLine="10" AttributesIndentString=" " WrapAttributes="False" AlignAttributes="False" AlignAttributeValues="False" QuoteChar="&quot;" SpacesBeforeAssignment="0" SpacesAfterAssignment="0" EmptyLinesBeforeStart="0" EmptyLinesAfterStart="0" EmptyLinesBeforeEnd="0" EmptyLinesAfterEnd="0" />
221 </XmlFormattingPolicy>
232 </XmlFormattingPolicy>
222 <TextStylePolicy FileWidth="120" TabWidth="4" TabsToSpaces="False" IndentWidth="4" RemoveTrailingWhitespace="True" NoTabsAfterNonTabs="False" EolMarker="Native" scope="text/plain" />
233 <TextStylePolicy FileWidth="120" TabWidth="4" TabsToSpaces="False" IndentWidth="4" RemoveTrailingWhitespace="True" NoTabsAfterNonTabs="False" EolMarker="Native" scope="text/plain" />
223 <NameConventionPolicy>
234 <NameConventionPolicy>
224 <Rules>
235 <Rules>
225 <NamingRule Name="Namespaces" AffectedEntity="Namespace" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True" />
236 <NamingRule Name="Namespaces" AffectedEntity="Namespace" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True" />
226 <NamingRule Name="Types" AffectedEntity="Class, Struct, Enum, Delegate" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True" />
237 <NamingRule Name="Types" AffectedEntity="Class, Struct, Enum, Delegate" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True" />
227 <NamingRule Name="Interfaces" AffectedEntity="Interface" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True">
238 <NamingRule Name="Interfaces" AffectedEntity="Interface" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True">
228 <RequiredPrefixes>
239 <RequiredPrefixes>
229 <String>I</String>
240 <String>I</String>
230 </RequiredPrefixes>
241 </RequiredPrefixes>
231 </NamingRule>
242 </NamingRule>
232 <NamingRule Name="Attributes" AffectedEntity="CustomAttributes" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True">
243 <NamingRule Name="Attributes" AffectedEntity="CustomAttributes" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True">
233 <RequiredSuffixes>
244 <RequiredSuffixes>
234 <String>Attribute</String>
245 <String>Attribute</String>
235 </RequiredSuffixes>
246 </RequiredSuffixes>
236 </NamingRule>
247 </NamingRule>
237 <NamingRule Name="Event Arguments" AffectedEntity="CustomEventArgs" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True">
248 <NamingRule Name="Event Arguments" AffectedEntity="CustomEventArgs" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True">
238 <RequiredSuffixes>
249 <RequiredSuffixes>
239 <String>EventArgs</String>
250 <String>EventArgs</String>
240 </RequiredSuffixes>
251 </RequiredSuffixes>
241 </NamingRule>
252 </NamingRule>
242 <NamingRule Name="Exceptions" AffectedEntity="CustomExceptions" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True">
253 <NamingRule Name="Exceptions" AffectedEntity="CustomExceptions" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True">
243 <RequiredSuffixes>
254 <RequiredSuffixes>
244 <String>Exception</String>
255 <String>Exception</String>
245 </RequiredSuffixes>
256 </RequiredSuffixes>
246 </NamingRule>
257 </NamingRule>
247 <NamingRule Name="Methods" AffectedEntity="Methods" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True" />
258 <NamingRule Name="Methods" AffectedEntity="Methods" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True" />
248 <NamingRule Name="Static Readonly Fields" AffectedEntity="ReadonlyField" VisibilityMask="Internal, Protected, Public" NamingStyle="CamelCase" IncludeInstanceMembers="False" IncludeStaticEntities="True" />
259 <NamingRule Name="Static Readonly Fields" AffectedEntity="ReadonlyField" VisibilityMask="Internal, Protected, Public" NamingStyle="CamelCase" IncludeInstanceMembers="False" IncludeStaticEntities="True" />
249 <NamingRule Name="Fields (Non Private)" AffectedEntity="Field" VisibilityMask="Internal, Public" NamingStyle="CamelCase" IncludeInstanceMembers="True" IncludeStaticEntities="True" />
260 <NamingRule Name="Fields (Non Private)" AffectedEntity="Field" VisibilityMask="Internal, Public" NamingStyle="CamelCase" IncludeInstanceMembers="True" IncludeStaticEntities="True" />
250 <NamingRule Name="ReadOnly Fields (Non Private)" AffectedEntity="ReadonlyField" VisibilityMask="Internal, Public" NamingStyle="CamelCase" IncludeInstanceMembers="True" IncludeStaticEntities="False" />
261 <NamingRule Name="ReadOnly Fields (Non Private)" AffectedEntity="ReadonlyField" VisibilityMask="Internal, Public" NamingStyle="CamelCase" IncludeInstanceMembers="True" IncludeStaticEntities="False" />
251 <NamingRule Name="Fields (Private)" AffectedEntity="Field, ReadonlyField" VisibilityMask="Private, Protected" NamingStyle="CamelCase" IncludeInstanceMembers="True" IncludeStaticEntities="False">
262 <NamingRule Name="Fields (Private)" AffectedEntity="Field, ReadonlyField" VisibilityMask="Private, Protected" NamingStyle="CamelCase" IncludeInstanceMembers="True" IncludeStaticEntities="False">
252 <RequiredPrefixes>
263 <RequiredPrefixes>
253 <String>m_</String>
264 <String>m_</String>
254 </RequiredPrefixes>
265 </RequiredPrefixes>
255 </NamingRule>
266 </NamingRule>
256 <NamingRule Name="Static Fields (Private)" AffectedEntity="Field" VisibilityMask="Private" NamingStyle="CamelCase" IncludeInstanceMembers="False" IncludeStaticEntities="True">
267 <NamingRule Name="Static Fields (Private)" AffectedEntity="Field" VisibilityMask="Private" NamingStyle="CamelCase" IncludeInstanceMembers="False" IncludeStaticEntities="True">
257 <RequiredPrefixes>
268 <RequiredPrefixes>
258 <String>_</String>
269 <String>_</String>
259 </RequiredPrefixes>
270 </RequiredPrefixes>
260 </NamingRule>
271 </NamingRule>
261 <NamingRule Name="ReadOnly Fields (Private)" AffectedEntity="ReadonlyField" VisibilityMask="Private, Protected" NamingStyle="CamelCase" IncludeInstanceMembers="True" IncludeStaticEntities="False">
272 <NamingRule Name="ReadOnly Fields (Private)" AffectedEntity="ReadonlyField" VisibilityMask="Private, Protected" NamingStyle="CamelCase" IncludeInstanceMembers="True" IncludeStaticEntities="False">
262 <RequiredPrefixes>
273 <RequiredPrefixes>
263 <String>m_</String>
274 <String>m_</String>
264 </RequiredPrefixes>
275 </RequiredPrefixes>
265 </NamingRule>
276 </NamingRule>
266 <NamingRule Name="Constant Fields" AffectedEntity="ConstantField" VisibilityMask="VisibilityMask" NamingStyle="AllUpper" IncludeInstanceMembers="True" IncludeStaticEntities="True" />
277 <NamingRule Name="Constant Fields" AffectedEntity="ConstantField" VisibilityMask="VisibilityMask" NamingStyle="AllUpper" IncludeInstanceMembers="True" IncludeStaticEntities="True" />
267 <NamingRule Name="Properties" AffectedEntity="Property" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True" />
278 <NamingRule Name="Properties" AffectedEntity="Property" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True" />
268 <NamingRule Name="Events" AffectedEntity="Event" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True" />
279 <NamingRule Name="Events" AffectedEntity="Event" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True" />
269 <NamingRule Name="Enum Members" AffectedEntity="EnumMember" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True" />
280 <NamingRule Name="Enum Members" AffectedEntity="EnumMember" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True" />
270 <NamingRule Name="Parameters" AffectedEntity="Parameter, LocalVariable" VisibilityMask="VisibilityMask" NamingStyle="CamelCase" IncludeInstanceMembers="True" IncludeStaticEntities="True" />
281 <NamingRule Name="Parameters" AffectedEntity="Parameter, LocalVariable" VisibilityMask="VisibilityMask" NamingStyle="CamelCase" IncludeInstanceMembers="True" IncludeStaticEntities="True" />
271 <NamingRule Name="Type Parameters" AffectedEntity="TypeParameter" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True">
282 <NamingRule Name="Type Parameters" AffectedEntity="TypeParameter" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True">
272 <RequiredPrefixes>
283 <RequiredPrefixes>
273 <String>T</String>
284 <String>T</String>
274 </RequiredPrefixes>
285 </RequiredPrefixes>
275 </NamingRule>
286 </NamingRule>
276 </Rules>
287 </Rules>
277 </NameConventionPolicy>
288 </NameConventionPolicy>
278 </Policies>
289 </Policies>
279 </Properties>
290 </Properties>
280 </MonoDevelop>
291 </MonoDevelop>
281 </ProjectExtensions>
292 </ProjectExtensions>
282 <ItemGroup />
293 <ItemGroup>
294 <Content Include="license.txt" />
295 </ItemGroup>
283 </Project> No newline at end of file
296 </Project>
@@ -1,562 +1,563
1 using System.Threading;
1 using System.Threading;
2 using System.Collections.Generic;
2 using System.Collections.Generic;
3 using System;
3 using System;
4 using System.Collections;
4 using System.Collections;
5 using System.Diagnostics;
5 using System.Diagnostics;
6 using System.Runtime.CompilerServices;
6
7
7 namespace Implab.Parallels {
8 namespace Implab.Parallels {
8 public class AsyncQueue<T> : IEnumerable<T> {
9 public class AsyncQueue<T> : IEnumerable<T> {
9 class Chunk {
10 class Chunk {
10 public volatile Chunk next;
11 public volatile Chunk next;
11
12
12 volatile int m_low;
13 volatile int m_low;
13 volatile int m_hi;
14 volatile int m_hi;
14 volatile int m_alloc;
15 volatile int m_alloc;
15 readonly int m_size;
16 readonly int m_size;
16 readonly T[] m_data;
17 readonly T[] m_data;
17
18
18 public Chunk(int size) {
19 public Chunk(int size) {
19 m_size = size;
20 m_size = size;
20 m_data = new T[size];
21 m_data = new T[size];
21 }
22 }
22
23
23 public Chunk(int size, T value) {
24 public Chunk(int size, T value) {
24 m_size = size;
25 m_size = size;
25 m_hi = 1;
26 m_hi = 1;
26 m_alloc = 1;
27 m_alloc = 1;
27 m_data = new T[size];
28 m_data = new T[size];
28 m_data[0] = value;
29 m_data[0] = value;
29 }
30 }
30
31
31 public Chunk(int size, int allocated) {
32 public Chunk(int size, int allocated) {
32 m_size = size;
33 m_size = size;
33 m_hi = allocated;
34 m_hi = allocated;
34 m_alloc = allocated;
35 m_alloc = allocated;
35 m_data = new T[size];
36 m_data = new T[size];
36 }
37 }
37
38
38 public void WriteData(T[] data, int offset, int dest, int length) {
39 public void WriteData(T[] data, int offset, int dest, int length) {
39 Array.Copy(data, offset, m_data, dest, length);
40 Array.Copy(data, offset, m_data, dest, length);
40 }
41 }
41
42
42 public int Low {
43 public int Low {
43 get { return m_low; }
44 get { return m_low; }
44 }
45 }
45
46
46 public int Hi {
47 public int Hi {
47 get { return m_hi; }
48 get { return m_hi; }
48 }
49 }
49
50
50 public int Size {
51 public int Size {
51 get { return m_size; }
52 get { return m_size; }
52 }
53 }
53
54
55 [MethodImpl(MethodImplOptions.AggressiveInlining)]
56 void AwaitWrites(int mark) {
57 if (m_hi != mark) {
58 SpinWait spin = new SpinWait();
59 do {
60 spin.SpinOnce();
61 } while (m_hi != mark);
62 }
63 }
64
54 public bool TryEnqueue(T value) {
65 public bool TryEnqueue(T value) {
55 int alloc;
66 int alloc;
56 do {
67 do {
57 alloc = m_alloc;
68 alloc = m_alloc;
58 if (alloc >= m_size)
69 if (alloc >= m_size)
59 return false;
70 return false;
60 } while(alloc != Interlocked.CompareExchange(ref m_alloc, alloc + 1, alloc));
71 } while(alloc != Interlocked.CompareExchange(ref m_alloc, alloc + 1, alloc));
61
72
62 m_data[alloc] = value;
73 m_data[alloc] = value;
63
74
64 SpinWait spin = new SpinWait();
75 AwaitWrites(alloc);
65 // m_hi is volatile
66 while (alloc != m_hi) {
67 // spin wait for commit
68 spin.SpinOnce();
69 }
70 m_hi = alloc + 1;
76 m_hi = alloc + 1;
71
77
72 return true;
78 return true;
73 }
79 }
74
80
75 /// <summary>
81 /// <summary>
76 /// Prevents from allocating new space in the chunk and waits for all write operations to complete
82 /// Prevents from allocating new space in the chunk and waits for all write operations to complete
77 /// </summary>
83 /// </summary>
78 public void Seal() {
84 public void Seal() {
79 var actual = Math.Min(Interlocked.Exchange(ref m_alloc, m_size), m_size);
85 var actual = Math.Min(Interlocked.Exchange(ref m_alloc, m_size), m_size);
80 SpinWait spin = new SpinWait();
86 AwaitWrites(actual);
81 while (m_hi != actual) {
82 spin.SpinOnce();
83 }
84 }
87 }
85
88
86 public bool TryDequeue(out T value, out bool recycle) {
89 public bool TryDequeue(out T value, out bool recycle) {
87 int low;
90 int low;
88 do {
91 do {
89 low = m_low;
92 low = m_low;
90 if (low >= m_hi) {
93 if (low >= m_hi) {
91 value = default(T);
94 value = default(T);
92 recycle = (low == m_size);
95 recycle = (low == m_size);
93 return false;
96 return false;
94 }
97 }
95 } while (low != Interlocked.CompareExchange(ref m_low, low + 1, low));
98 } while (low != Interlocked.CompareExchange(ref m_low, low + 1, low));
96
99
97 recycle = (low + 1 == m_size);
100 recycle = (low + 1 == m_size);
98 value = m_data[low];
101 value = m_data[low];
99
102
100 return true;
103 return true;
101 }
104 }
102
105
103 public bool TryEnqueueBatch(T[] batch, int offset, int length, out int enqueued) {
106 public bool TryEnqueueBatch(T[] batch, int offset, int length, out int enqueued) {
104 int alloc;
107 int alloc;
105 do {
108 do {
106 alloc = m_alloc;
109 alloc = m_alloc;
107 if (alloc >= m_size) {
110 if (alloc >= m_size) {
108 enqueued = 0;
111 enqueued = 0;
109 return false;
112 return false;
110 } else {
113 } else {
111 enqueued = Math.Min(length, m_size - alloc);
114 enqueued = Math.Min(length, m_size - alloc);
112 }
115 }
113 } while (alloc != Interlocked.CompareExchange(ref m_alloc, alloc + enqueued, alloc));
116 } while (alloc != Interlocked.CompareExchange(ref m_alloc, alloc + enqueued, alloc));
114
117
115 Array.Copy(batch, offset, m_data, alloc, enqueued);
118 Array.Copy(batch, offset, m_data, alloc, enqueued);
116
119
117 SpinWait spin = new SpinWait();
120 AwaitWrites(alloc);
118 while (alloc != m_hi) {
119 spin.SpinOnce();
120 }
121
122 m_hi = alloc + enqueued;
121 m_hi = alloc + enqueued;
123 return true;
122 return true;
124 }
123 }
125
124
126 public bool TryDequeueBatch(T[] buffer, int offset, int length, out int dequeued, out bool recycle) {
125 public bool TryDequeueBatch(T[] buffer, int offset, int length, out int dequeued, out bool recycle) {
127 int low, hi, batchSize;
126 int low, hi, batchSize;
128
127
129 do {
128 do {
130 low = m_low;
129 low = m_low;
131 hi = m_hi;
130 hi = m_hi;
132 if (low >= hi) {
131 if (low >= hi) {
133 dequeued = 0;
132 dequeued = 0;
134 recycle = (low == m_size);
133 recycle = (low == m_size);
135 return false;
134 return false;
136 }
135 }
137 batchSize = Math.Min(hi - low, length);
136 batchSize = Math.Min(hi - low, length);
138 } while (low != Interlocked.CompareExchange(ref m_low, low + batchSize, low));
137 } while (low != Interlocked.CompareExchange(ref m_low, low + batchSize, low));
139
138
140 dequeued = batchSize;
139 dequeued = batchSize;
141 recycle = (low + batchSize == m_size);
140 recycle = (low + batchSize == m_size);
142 Array.Copy(m_data, low, buffer, offset, batchSize);
141 Array.Copy(m_data, low, buffer, offset, batchSize);
143
142
144 return true;
143 return true;
145 }
144 }
146
145
147 public T GetAt(int pos) {
146 public T GetAt(int pos) {
148 return m_data[pos];
147 return m_data[pos];
149 }
148 }
150 }
149 }
151
150
152 public const int DEFAULT_CHUNK_SIZE = 32;
151 public const int DEFAULT_CHUNK_SIZE = 32;
153 public const int MAX_CHUNK_SIZE = 256;
152 public const int MAX_CHUNK_SIZE = 256;
154
153
155 Chunk m_first;
154 Chunk m_first;
156 Chunk m_last;
155 Chunk m_last;
157
156
158 public AsyncQueue() {
157 public AsyncQueue() {
159 m_first = m_last = new Chunk(DEFAULT_CHUNK_SIZE);
158 m_first = m_last = new Chunk(DEFAULT_CHUNK_SIZE);
160 }
159 }
161
160
162 /// <summary>
161 /// <summary>
163 /// Adds the specified value to the queue.
162 /// Adds the specified value to the queue.
164 /// </summary>
163 /// </summary>
165 /// <param name="value">Tha value which will be added to the queue.</param>
164 /// <param name="value">Tha value which will be added to the queue.</param>
166 public void Enqueue(T value) {
165 public void Enqueue(T value) {
167 var last = m_last;
166 var last = m_last;
168 SpinWait spin = new SpinWait();
167 SpinWait spin = new SpinWait();
169 while (!last.TryEnqueue(value)) {
168 while (!last.TryEnqueue(value)) {
170 // try to extend queue
169 // try to extend queue
171 var chunk = new Chunk(DEFAULT_CHUNK_SIZE, value);
170 var chunk = new Chunk(DEFAULT_CHUNK_SIZE, value);
172 var t = Interlocked.CompareExchange(ref m_last, chunk, last);
171 var t = Interlocked.CompareExchange(ref m_last, chunk, last);
173 if (t == last) {
172 if (t == last) {
174 last.next = chunk;
173 last.next = chunk;
175 break;
174 break;
176 } else {
175 } else {
177 last = t;
176 last = t;
178 }
177 }
179 spin.SpinOnce();
178 spin.SpinOnce();
180 }
179 }
181 }
180 }
182
181
183 /// <summary>
182 /// <summary>
184 /// Adds the specified data to the queue.
183 /// Adds the specified data to the queue.
185 /// </summary>
184 /// </summary>
186 /// <param name="data">The buffer which contains the data to be enqueued.</param>
185 /// <param name="data">The buffer which contains the data to be enqueued.</param>
187 /// <param name="offset">The offset of the data in the buffer.</param>
186 /// <param name="offset">The offset of the data in the buffer.</param>
188 /// <param name="length">The size of the data to read from the buffer.</param>
187 /// <param name="length">The size of the data to read from the buffer.</param>
189 public void EnqueueRange(T[] data, int offset, int length) {
188 public void EnqueueRange(T[] data, int offset, int length) {
190 if (data == null)
189 if (data == null)
191 throw new ArgumentNullException("data");
190 throw new ArgumentNullException("data");
192 if (offset < 0)
191 if (offset < 0)
193 throw new ArgumentOutOfRangeException("offset");
192 throw new ArgumentOutOfRangeException("offset");
194 if (length < 1 || offset + length > data.Length)
193 if (length < 1 || offset + length > data.Length)
195 throw new ArgumentOutOfRangeException("length");
194 throw new ArgumentOutOfRangeException("length");
196
195
197 while (length > 0) {
196 while (length > 0) {
198 var last = m_last;
197 var last = m_last;
199 int enqueued;
198 int enqueued;
200
199
201 if (last.TryEnqueueBatch(data, offset, length, out enqueued)) {
200 if (last.TryEnqueueBatch(data, offset, length, out enqueued)) {
202 length -= enqueued;
201 length -= enqueued;
203 offset += enqueued;
202 offset += enqueued;
204 }
203 }
205
204
206 if (length > 0) {
205 if (length > 0) {
207 // we have something to enqueue
206 // we have something to enqueue
208
207
209 var tail = length % MAX_CHUNK_SIZE;
208 var tail = length % MAX_CHUNK_SIZE;
210
209
211 var chunk = new Chunk(Math.Max(tail, DEFAULT_CHUNK_SIZE), tail);
210 var chunk = new Chunk(Math.Max(tail, DEFAULT_CHUNK_SIZE), tail);
212
211
213 if (last != Interlocked.CompareExchange(ref m_last, chunk, last))
212 if (last != Interlocked.CompareExchange(ref m_last, chunk, last))
214 continue; // we wasn't able to catch the writer, roundtrip
213 continue; // we wasn't able to catch the writer, roundtrip
215
214
216 // we are lucky
215 // we are lucky
217 // we can exclusively write our batch, the other writers will continue their work
216 // we can exclusively write our batch, the other writers will continue their work
218
217
219 length -= tail;
218 length -= tail;
220
219
221
220
222 for(var i = 0; i < length; i+= MAX_CHUNK_SIZE) {
221 for(var i = 0; i < length; i+= MAX_CHUNK_SIZE) {
223 var node = new Chunk(MAX_CHUNK_SIZE, MAX_CHUNK_SIZE);
222 var node = new Chunk(MAX_CHUNK_SIZE, MAX_CHUNK_SIZE);
224 node.WriteData(data, offset, 0, MAX_CHUNK_SIZE);
223 node.WriteData(data, offset, 0, MAX_CHUNK_SIZE);
225 offset += MAX_CHUNK_SIZE;
224 offset += MAX_CHUNK_SIZE;
226 // fence last.next is volatile
225 // fence last.next is volatile
227 last.next = node;
226 last.next = node;
228 last = node;
227 last = node;
229 }
228 }
230
229
231 if (tail > 0)
230 if (tail > 0)
232 chunk.WriteData(data, offset, 0, tail);
231 chunk.WriteData(data, offset, 0, tail);
233
232
234 // fence last.next is volatile
233 // fence last.next is volatile
235 last.next = chunk;
234 last.next = chunk;
236 return;
235 return;
237 }
236 }
238 }
237 }
239 }
238 }
240
239
241 /// <summary>
240 /// <summary>
242 /// Tries to retrieve the first element from the queue.
241 /// Tries to retrieve the first element from the queue.
243 /// </summary>
242 /// </summary>
244 /// <returns><c>true</c>, if element is dequeued, <c>false</c> otherwise.</returns>
243 /// <returns><c>true</c>, if element is dequeued, <c>false</c> otherwise.</returns>
245 /// <param name="value">The value of the dequeued element.</param>
244 /// <param name="value">The value of the dequeued element.</param>
246 public bool TryDequeue(out T value) {
245 public bool TryDequeue(out T value) {
247 var chunk = m_first;
246 var chunk = m_first;
248 do {
247 do {
249 bool recycle;
248 bool recycle;
250
249
251 var result = chunk.TryDequeue(out value, out recycle);
250 var result = chunk.TryDequeue(out value, out recycle);
252
251
253 if (recycle && chunk.next != null) {
252 if (recycle && chunk.next != null) {
254 // this chunk is waste
253 // this chunk is waste
255 chunk = Interlocked.CompareExchange(ref m_first, chunk.next, chunk);
254 chunk = Interlocked.CompareExchange(ref m_first, chunk.next, chunk);
256 } else {
255 } else {
257 return result; // this chunk is usable and returned actual result
256 return result; // this chunk is usable and returned actual result
258 }
257 }
259
258
260 if (result) // this chunk is waste but the true result is always actual
259 if (result) // this chunk is waste but the true result is always actual
261 return true;
260 return true;
262 } while (true);
261 } while (true);
263 }
262 }
264
263
265 /// <summary>
264 /// <summary>
266 /// Tries to dequeue the specified amount of data from the queue.
265 /// Tries to dequeue the specified amount of data from the queue.
267 /// </summary>
266 /// </summary>
268 /// <returns><c>true</c>, if data was deuqueued, <c>false</c> otherwise.</returns>
267 /// <returns><c>true</c>, if data was deuqueued, <c>false</c> otherwise.</returns>
269 /// <param name="buffer">The buffer to which the data will be written.</param>
268 /// <param name="buffer">The buffer to which the data will be written.</param>
270 /// <param name="offset">The offset in the buffer at which the data will be written.</param>
269 /// <param name="offset">The offset in the buffer at which the data will be written.</param>
271 /// <param name="length">The maximum amount of data to be retrieved.</param>
270 /// <param name="length">The maximum amount of data to be retrieved.</param>
272 /// <param name="dequeued">The actual amout of the retrieved data.</param>
271 /// <param name="dequeued">The actual amout of the retrieved data.</param>
273 public bool TryDequeueRange(T[] buffer, int offset, int length, out int dequeued) {
272 public bool TryDequeueRange(T[] buffer, int offset, int length, out int dequeued) {
274 if (buffer == null)
273 if (buffer == null)
275 throw new ArgumentNullException("buffer");
274 throw new ArgumentNullException("buffer");
276 if (offset < 0)
275 if (offset < 0)
277 throw new ArgumentOutOfRangeException("offset");
276 throw new ArgumentOutOfRangeException("offset");
278 if (length < 1 || offset + length > buffer.Length)
277 if (length < 1 || offset + length > buffer.Length)
279 throw new ArgumentOutOfRangeException("length");
278 throw new ArgumentOutOfRangeException("length");
280
279
281 var chunk = m_first;
280 var chunk = m_first;
282 dequeued = 0;
281 dequeued = 0;
283 do {
282 do {
284 bool recycle;
283 bool recycle;
285 int actual;
284 int actual;
286 if (chunk.TryDequeueBatch(buffer, offset, length, out actual, out recycle)) {
285 if (chunk.TryDequeueBatch(buffer, offset, length, out actual, out recycle)) {
287 offset += actual;
286 offset += actual;
288 length -= actual;
287 length -= actual;
289 dequeued += actual;
288 dequeued += actual;
290 }
289 }
291
290
292 if (recycle && chunk.next != null) {
291 if (recycle && chunk.next != null) {
293 // this chunk is waste
292 // this chunk is waste
294 chunk = Interlocked.CompareExchange(ref m_first, chunk.next, chunk);
293 chunk = Interlocked.CompareExchange(ref m_first, chunk.next, chunk);
295 } else {
294 } else {
296 chunk = null;
295 chunk = null;
297 }
296 }
298
297
299 if (length == 0)
298 if (length == 0)
300 return true;
299 return true;
301 } while (chunk != null);
300 } while (chunk != null);
302
301
303 return dequeued != 0;
302 return dequeued != 0;
304 }
303 }
305
304
306 /// <summary>
305 /// <summary>
307 /// Tries to dequeue all remaining data in the first chunk.
306 /// Tries to dequeue all remaining data in the first chunk.
308 /// </summary>
307 /// </summary>
309 /// <returns><c>true</c>, if data was dequeued, <c>false</c> otherwise.</returns>
308 /// <returns><c>true</c>, if data was dequeued, <c>false</c> otherwise.</returns>
310 /// <param name="buffer">The buffer to which the data will be written.</param>
309 /// <param name="buffer">The buffer to which the data will be written.</param>
311 /// <param name="offset">The offset in the buffer at which the data will be written.</param>
310 /// <param name="offset">The offset in the buffer at which the data will be written.</param>
312 /// <param name="length">Tha maximum amount of the data to be dequeued.</param>
311 /// <param name="length">Tha maximum amount of the data to be dequeued.</param>
313 /// <param name="dequeued">The actual amount of the dequeued data.</param>
312 /// <param name="dequeued">The actual amount of the dequeued data.</param>
314 public bool TryDequeueChunk(T[] buffer, int offset, int length, out int dequeued) {
313 public bool TryDequeueChunk(T[] buffer, int offset, int length, out int dequeued) {
315 if (buffer == null)
314 if (buffer == null)
316 throw new ArgumentNullException("buffer");
315 throw new ArgumentNullException("buffer");
317 if (offset < 0)
316 if (offset < 0)
318 throw new ArgumentOutOfRangeException("offset");
317 throw new ArgumentOutOfRangeException("offset");
319 if (length < 1 || offset + length > buffer.Length)
318 if (length < 1 || offset + length > buffer.Length)
320 throw new ArgumentOutOfRangeException("length");
319 throw new ArgumentOutOfRangeException("length");
321
320
322 var chunk = m_first;
321 var chunk = m_first;
323 do {
322 do {
324 bool recycle;
323 bool recycle;
325 chunk.TryDequeueBatch(buffer, offset, length, out dequeued, out recycle);
324 chunk.TryDequeueBatch(buffer, offset, length, out dequeued, out recycle);
326
325
327 if (recycle && chunk.next != null) {
326 if (recycle && chunk.next != null) {
328 // this chunk is waste
327 // this chunk is waste
329 chunk = Interlocked.CompareExchange(ref m_first, chunk.next, chunk);
328 chunk = Interlocked.CompareExchange(ref m_first, chunk.next, chunk);
330 } else {
329 } else {
331 chunk = null;
330 chunk = null;
332 }
331 }
333
332
334 // if we have dequeued any data, then return
333 // if we have dequeued any data, then return
335 if (dequeued != 0)
334 if (dequeued != 0)
336 return true;
335 return true;
337
336
338 } while (chunk != null);
337 } while (chunk != null);
339
338
340 return false;
339 return false;
341 }
340 }
342
341
343
342
344 public void Clear() {
343 public void Clear() {
345 // start the new queue
344 // start the new queue
346 var chunk = new Chunk(DEFAULT_CHUNK_SIZE);
345 var chunk = new Chunk(DEFAULT_CHUNK_SIZE);
347 do {
346 do {
348 var first = m_first;
347 var first = m_first;
349 if (first.next == null && first != m_last) {
348 if (first.next == null && first != m_last) {
350 continue;
349 continue;
351 }
350 }
352
351
353 // here we will create inconsistency which will force others to spin
352 // here we will create inconsistency which will force others to spin
354 // and prevent from fetching. chunk.next = null
353 // and prevent from fetching. chunk.next = null
355 if (first != Interlocked.CompareExchange(ref m_first, chunk, first))
354 if (first != Interlocked.CompareExchange(ref m_first, chunk, first))
356 continue;// inconsistent
355 continue;// inconsistent
357
356
358 m_last = chunk;
357 m_last = chunk;
359 return;
358 return;
360 } while (true);
359 } while (true);
361 }
360 }
362
361
363 public List<T> Drain() {
362 public List<T> Drain() {
364 // start the new queue
363 Chunk chunk = null;
365 var chunk = new Chunk(DEFAULT_CHUNK_SIZE);
366
367 do {
364 do {
368 var first = m_first;
365 var first = m_first;
369 // first.next is volatile
366 // first.next is volatile
370 if (first.next == null) {
367 if (first.next == null) {
371 if (first != m_last)
368 if (first != m_last)
372 continue;
369 continue;
373 else if (first.Hi == first.Low)
370 else if (first.Hi == first.Low)
374 return new List<T>();
371 return new List<T>();
375 }
372 }
376
373
374 // start the new queue
375 if (chunk == null)
376 chunk = new Chunk(DEFAULT_CHUNK_SIZE);
377
377 // here we will create inconsistency which will force others to spin
378 // here we will create inconsistency which will force others to spin
378 // and prevent from fetching. chunk.next = null
379 // and prevent from fetching. chunk.next = null
379 if (first != Interlocked.CompareExchange(ref m_first, chunk, first))
380 if (first != Interlocked.CompareExchange(ref m_first, chunk, first))
380 continue;// inconsistent
381 continue;// inconsistent
381
382
382 var last = Interlocked.Exchange(ref m_last, chunk);
383 var last = Interlocked.Exchange(ref m_last, chunk);
383
384
384 return ReadChunks(first, last);
385 return ReadChunks(first, last);
385
386
386 } while (true);
387 } while (true);
387 }
388 }
388
389
389 static List<T> ReadChunks(Chunk chunk, object last) {
390 static List<T> ReadChunks(Chunk chunk, object last) {
390 var result = new List<T>();
391 var result = new List<T>();
391 var buffer = new T[MAX_CHUNK_SIZE];
392 var buffer = new T[MAX_CHUNK_SIZE];
392 int actual;
393 int actual;
393 bool recycle;
394 bool recycle;
394 SpinWait spin = new SpinWait();
395 SpinWait spin = new SpinWait();
395 while (chunk != null) {
396 while (chunk != null) {
396 // ensure all write operations on the chunk are complete
397 // ensure all write operations on the chunk are complete
397 chunk.Seal();
398 chunk.Seal();
398
399
399 // we need to read the chunk using this way
400 // we need to read the chunk using this way
400 // since some client still may completing the dequeue
401 // since some client still may completing the dequeue
401 // operation, such clients most likely won't get results
402 // operation, such clients most likely won't get results
402 while (chunk.TryDequeueBatch(buffer, 0, buffer.Length, out actual, out recycle))
403 while (chunk.TryDequeueBatch(buffer, 0, buffer.Length, out actual, out recycle))
403 result.AddRange(new ArraySegmentCollection(buffer, 0, actual));
404 result.AddRange(new ArraySegmentCollection(buffer, 0, actual));
404
405
405 if (chunk == last) {
406 if (chunk == last) {
406 chunk = null;
407 chunk = null;
407 } else {
408 } else {
408 while (chunk.next == null)
409 while (chunk.next == null)
409 spin.SpinOnce();
410 spin.SpinOnce();
410 chunk = chunk.next;
411 chunk = chunk.next;
411 }
412 }
412 }
413 }
413
414
414 return result;
415 return result;
415 }
416 }
416
417
417 struct ArraySegmentCollection : ICollection<T> {
418 struct ArraySegmentCollection : ICollection<T> {
418 readonly T[] m_data;
419 readonly T[] m_data;
419 readonly int m_offset;
420 readonly int m_offset;
420 readonly int m_length;
421 readonly int m_length;
421
422
422 public ArraySegmentCollection(T[] data, int offset, int length) {
423 public ArraySegmentCollection(T[] data, int offset, int length) {
423 m_data = data;
424 m_data = data;
424 m_offset = offset;
425 m_offset = offset;
425 m_length = length;
426 m_length = length;
426 }
427 }
427
428
428 #region ICollection implementation
429 #region ICollection implementation
429
430
430 public void Add(T item) {
431 public void Add(T item) {
431 throw new NotSupportedException();
432 throw new NotSupportedException();
432 }
433 }
433
434
434 public void Clear() {
435 public void Clear() {
435 throw new NotSupportedException();
436 throw new NotSupportedException();
436 }
437 }
437
438
438 public bool Contains(T item) {
439 public bool Contains(T item) {
439 return false;
440 return false;
440 }
441 }
441
442
442 public void CopyTo(T[] array, int arrayIndex) {
443 public void CopyTo(T[] array, int arrayIndex) {
443 Array.Copy(m_data, m_offset, array, arrayIndex, m_length);
444 Array.Copy(m_data, m_offset, array, arrayIndex, m_length);
444 }
445 }
445
446
446 public bool Remove(T item) {
447 public bool Remove(T item) {
447 throw new NotSupportedException();
448 throw new NotSupportedException();
448 }
449 }
449
450
450 public int Count {
451 public int Count {
451 get {
452 get {
452 return m_length;
453 return m_length;
453 }
454 }
454 }
455 }
455
456
456 public bool IsReadOnly {
457 public bool IsReadOnly {
457 get {
458 get {
458 return true;
459 return true;
459 }
460 }
460 }
461 }
461
462
462 #endregion
463 #endregion
463
464
464 #region IEnumerable implementation
465 #region IEnumerable implementation
465
466
466 public IEnumerator<T> GetEnumerator() {
467 public IEnumerator<T> GetEnumerator() {
467 for (int i = m_offset; i < m_length + m_offset; i++)
468 for (int i = m_offset; i < m_length + m_offset; i++)
468 yield return m_data[i];
469 yield return m_data[i];
469 }
470 }
470
471
471 #endregion
472 #endregion
472
473
473 #region IEnumerable implementation
474 #region IEnumerable implementation
474
475
475 IEnumerator IEnumerable.GetEnumerator() {
476 IEnumerator IEnumerable.GetEnumerator() {
476 return GetEnumerator();
477 return GetEnumerator();
477 }
478 }
478
479
479 #endregion
480 #endregion
480 }
481 }
481
482
482 #region IEnumerable implementation
483 #region IEnumerable implementation
483
484
484 class Enumerator : IEnumerator<T> {
485 class Enumerator : IEnumerator<T> {
485 Chunk m_current;
486 Chunk m_current;
486 int m_pos = -1;
487 int m_pos = -1;
487
488
488 public Enumerator(Chunk fisrt) {
489 public Enumerator(Chunk fisrt) {
489 m_current = fisrt;
490 m_current = fisrt;
490 }
491 }
491
492
492 #region IEnumerator implementation
493 #region IEnumerator implementation
493
494
494 public bool MoveNext() {
495 public bool MoveNext() {
495 if (m_current == null)
496 if (m_current == null)
496 return false;
497 return false;
497
498
498 if (m_pos == -1)
499 if (m_pos == -1)
499 m_pos = m_current.Low;
500 m_pos = m_current.Low;
500 else
501 else
501 m_pos++;
502 m_pos++;
502
503
503 if (m_pos == m_current.Hi) {
504 if (m_pos == m_current.Hi) {
504
505
505 m_current = m_pos == m_current.Size ? m_current.next : null;
506 m_current = m_pos == m_current.Size ? m_current.next : null;
506
507
507 m_pos = 0;
508 m_pos = 0;
508
509
509 if (m_current == null)
510 if (m_current == null)
510 return false;
511 return false;
511 }
512 }
512
513
513 return true;
514 return true;
514 }
515 }
515
516
516 public void Reset() {
517 public void Reset() {
517 throw new NotSupportedException();
518 throw new NotSupportedException();
518 }
519 }
519
520
520 object IEnumerator.Current {
521 object IEnumerator.Current {
521 get {
522 get {
522 return Current;
523 return Current;
523 }
524 }
524 }
525 }
525
526
526 #endregion
527 #endregion
527
528
528 #region IDisposable implementation
529 #region IDisposable implementation
529
530
530 public void Dispose() {
531 public void Dispose() {
531 }
532 }
532
533
533 #endregion
534 #endregion
534
535
535 #region IEnumerator implementation
536 #region IEnumerator implementation
536
537
537 public T Current {
538 public T Current {
538 get {
539 get {
539 if (m_pos == -1 || m_current == null)
540 if (m_pos == -1 || m_current == null)
540 throw new InvalidOperationException();
541 throw new InvalidOperationException();
541 return m_current.GetAt(m_pos);
542 return m_current.GetAt(m_pos);
542 }
543 }
543 }
544 }
544
545
545 #endregion
546 #endregion
546 }
547 }
547
548
548 public IEnumerator<T> GetEnumerator() {
549 public IEnumerator<T> GetEnumerator() {
549 return new Enumerator(m_first);
550 return new Enumerator(m_first);
550 }
551 }
551
552
552 #endregion
553 #endregion
553
554
554 #region IEnumerable implementation
555 #region IEnumerable implementation
555
556
556 IEnumerator IEnumerable.GetEnumerator() {
557 IEnumerator IEnumerable.GetEnumerator() {
557 return GetEnumerator();
558 return GetEnumerator();
558 }
559 }
559
560
560 #endregion
561 #endregion
561 }
562 }
562 }
563 }
@@ -1,27 +1,24
1 using System.Reflection;
1 using System.Reflection;
2 using System.Runtime.CompilerServices;
3 using System.Runtime.InteropServices;
2 using System.Runtime.InteropServices;
4
3
5 // Information about this assembly is defined by the following attributes.
4 // Information about this assembly is defined by the following attributes.
6 // Change them to the values specific to your project.
5 // Change them to the values specific to your project.
7
6
8 [assembly: AssemblyTitle("Implab")]
7 [assembly: AssemblyTitle("Implab")]
9 [assembly: AssemblyDescription("Tools")]
8 [assembly: AssemblyDescription("Tools")]
10 [assembly: AssemblyConfiguration("")]
9 [assembly: AssemblyCompany("Implab.org")]
11 [assembly: AssemblyCompany("")]
12 [assembly: AssemblyProduct("")]
13 [assembly: AssemblyCopyright("Implab")]
10 [assembly: AssemblyCopyright("Implab")]
14 [assembly: AssemblyTrademark("")]
11 [assembly: AssemblyTrademark("Implab")]
15 // The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}".
12 // The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}".
16 // The form "{Major}.{Minor}.*" will automatically update the build and revision,
13 // The form "{Major}.{Minor}.*" will automatically update the build and revision,
17 // and "{Major}.{Minor}.{Build}.*" will update just the revision.
14 // and "{Major}.{Minor}.{Build}.*" will update just the revision.
18
15
19 [assembly: AssemblyVersion("2.1.*")]
16 [assembly: AssemblyVersion("2.1.*")]
20 [assembly: ComVisible(false)]
17 [assembly: ComVisible(false)]
21
18
22 // The following attributes are used to specify the signing key for the assembly,
19 // The following attributes are used to specify the signing key for the assembly,
23 // if desired. See the Mono documentation for more information about signing.
20 // if desired. See the Mono documentation for more information about signing.
24
21
25 //[assembly: AssemblyDelaySign(false)]
22 //[assembly: AssemblyDelaySign(false)]
26 //[assembly: AssemblyKeyFile("")]
23 //[assembly: AssemblyKeyFile("")]
27
24
General Comments 3
Under Review
author

Auto status change to "Under Review"

Approved
author

ok, latest stable version should be in default

You need to be logged in to leave comments. Login now