diff --git a/Implab.Playground/Program.cs b/Implab.Playground/Program.cs --- a/Implab.Playground/Program.cs +++ b/Implab.Playground/Program.cs @@ -49,7 +49,6 @@ namespace Implab.Playground { return actual != 0; } - /* static void EnqueueRange(AsyncQueue q, T[] data, int offset, int len) { for (var i = offset; i < offset + len; i++) q.Enqueue(data[i]); @@ -66,15 +65,15 @@ namespace Implab.Playground { } return actual != 0; } - */ + - static void EnqueueRange(AsyncQueue q, T[] data, int offset, int len) { + /*static void EnqueueRange(AsyncQueue q, T[] data, int offset, int len) { q.EnqueueRange(data, offset, len); } static bool TryDequeueRange(AsyncQueue q, T[] buffer, int offset, int len, out int actual) { return q.TryDequeueRange(buffer, offset, len, out actual); - } + }*/ static void Main(string[] args) { diff --git a/Implab/Implab.csproj b/Implab/Implab.csproj --- a/Implab/Implab.csproj +++ b/Implab/Implab.csproj @@ -67,6 +67,12 @@ 4 false + + true + + + implab.snk + @@ -207,7 +213,12 @@ - + + + Designer + + + @@ -279,5 +290,7 @@ - + + + \ No newline at end of file diff --git a/Implab/Implab.nuspec b/Implab/Implab.nuspec new file mode 100644 --- /dev/null +++ b/Implab/Implab.nuspec @@ -0,0 +1,17 @@ + + + + Implab + $version$ + $title$ + Implab team + Implab team + https://implab.org/ + + false + Common components for asynchronous applications, tracing, logging, json and xml traits. + Added strong name. + Copyright 2017 + async xml json + + \ No newline at end of file diff --git a/Implab/Parallels/AsyncQueue.cs b/Implab/Parallels/AsyncQueue.cs --- a/Implab/Parallels/AsyncQueue.cs +++ b/Implab/Parallels/AsyncQueue.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System; using System.Collections; using System.Diagnostics; +using System.Runtime.CompilerServices; namespace Implab.Parallels { public class AsyncQueue : IEnumerable { @@ -51,6 +52,16 @@ namespace Implab.Parallels { get { return m_size; } } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + void AwaitWrites(int mark) { + if (m_hi != mark) { + SpinWait spin = new SpinWait(); + do { + spin.SpinOnce(); + } while (m_hi != mark); + } + } + public bool TryEnqueue(T value) { int alloc; do { @@ -61,12 +72,7 @@ namespace Implab.Parallels { m_data[alloc] = value; - SpinWait spin = new SpinWait(); - // m_hi is volatile - while (alloc != m_hi) { - // spin wait for commit - spin.SpinOnce(); - } + AwaitWrites(alloc); m_hi = alloc + 1; return true; @@ -77,10 +83,7 @@ namespace Implab.Parallels { /// public void Seal() { var actual = Math.Min(Interlocked.Exchange(ref m_alloc, m_size), m_size); - SpinWait spin = new SpinWait(); - while (m_hi != actual) { - spin.SpinOnce(); - } + AwaitWrites(actual); } public bool TryDequeue(out T value, out bool recycle) { @@ -114,11 +117,7 @@ namespace Implab.Parallels { Array.Copy(batch, offset, m_data, alloc, enqueued); - SpinWait spin = new SpinWait(); - while (alloc != m_hi) { - spin.SpinOnce(); - } - + AwaitWrites(alloc); m_hi = alloc + enqueued; return true; } @@ -361,9 +360,7 @@ namespace Implab.Parallels { } public List Drain() { - // start the new queue - var chunk = new Chunk(DEFAULT_CHUNK_SIZE); - + Chunk chunk = null; do { var first = m_first; // first.next is volatile @@ -374,6 +371,10 @@ namespace Implab.Parallels { return new List(); } + // start the new queue + if (chunk == null) + chunk = new Chunk(DEFAULT_CHUNK_SIZE); + // here we will create inconsistency which will force others to spin // and prevent from fetching. chunk.next = null if (first != Interlocked.CompareExchange(ref m_first, chunk, first)) diff --git a/Implab/Properties/AssemblyInfo.cs b/Implab/Properties/AssemblyInfo.cs --- a/Implab/Properties/AssemblyInfo.cs +++ b/Implab/Properties/AssemblyInfo.cs @@ -1,5 +1,4 @@ using System.Reflection; -using System.Runtime.CompilerServices; using System.Runtime.InteropServices; // Information about this assembly is defined by the following attributes. @@ -7,11 +6,9 @@ using System.Runtime.InteropServices; [assembly: AssemblyTitle("Implab")] [assembly: AssemblyDescription("Tools")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("")] +[assembly: AssemblyCompany("Implab.org")] [assembly: AssemblyCopyright("Implab")] -[assembly: AssemblyTrademark("")] +[assembly: AssemblyTrademark("Implab")] // The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}". // The form "{Major}.{Minor}.*" will automatically update the build and revision, // and "{Major}.{Minor}.{Build}.*" will update just the revision. diff --git a/Implab/implab.snk b/Implab/implab.snk new file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..2a97e5bd29ee66d5071da2075f5e6471e9418560 GIT binary patch literal 596 zc$@)L0;~N80ssI2Bme+XQ$aES1ONa50097>8h#|4vJ)g>rhZCkG@b$eW)d55JbM%cx|Eq*jW%iTc*wDy z=nX8^^ZeEm2Kw%Q(-NIcCe`?0SQp2vk2<2D59vJ#-^38)QA@>+9Kd>r=&+r|h(_-B zT<3J#>{@uc*l?`s~%-VX@7 z&)eD_@-zp-KxVqv5vC@m*d|_D@!Efr-e0UFc&t6G>#M2>k57u?tk*d#p*`{$8=CfB zt5S9K_M1j@6Q+>r`r%C&v0edT;8{+5CERgD1P*K~sefevEZJshQkU5s{VtEo^mU!c zE5_2Pa)Jlm##;S!2}-MPMBB+)APHoX;bziy9XYG1A1}2;e4XHG9wX@cJZ8M&wjtay z&Vlfmgx+R>dG$!%t0!veEMORO*fm^1m@FO=PDV)El`Y?s9ZT)dGFoKWl@R`yz1E!? zW-Nd|wE7&fCz5#c$EQO~%&&SXocLUC?cz1#H4%;ZfX|!