From dc95e23048c9ba245a8dc221ce43e92a4c103787 Mon Sep 17 00:00:00 2001 From: Marek Safar Date: Fri, 16 Jan 2015 18:23:12 +0100 Subject: Fixes build --- mcs/class/Mono.Parallel/Mono.Parallel.dll.sources | 8 +- .../Mono.Threading.Tasks/CyclicDeque.cs | 217 +++++++++++++++++++++ .../Mono.Threading.Tasks/IConcurrentDeque.cs | 49 +++++ .../Mono.Threading.Tasks/PopResult.cs | 47 +++++ .../Mono.Parallel/Mono.Threading/AtomicBoolean.cs | 186 ++++++++++++++++++ 5 files changed, 503 insertions(+), 4 deletions(-) create mode 100644 mcs/class/Mono.Parallel/Mono.Threading.Tasks/CyclicDeque.cs create mode 100644 mcs/class/Mono.Parallel/Mono.Threading.Tasks/IConcurrentDeque.cs create mode 100644 mcs/class/Mono.Parallel/Mono.Threading.Tasks/PopResult.cs create mode 100644 mcs/class/Mono.Parallel/Mono.Threading/AtomicBoolean.cs (limited to 'mcs/class/Mono.Parallel') diff --git a/mcs/class/Mono.Parallel/Mono.Parallel.dll.sources b/mcs/class/Mono.Parallel/Mono.Parallel.dll.sources index 57ec8a4604a..7ecbf05dd9f 100644 --- a/mcs/class/Mono.Parallel/Mono.Parallel.dll.sources +++ b/mcs/class/Mono.Parallel/Mono.Parallel.dll.sources @@ -6,8 +6,8 @@ Mono.Threading/CSnzi.cs Mono.Threading/Snzi.cs Mono.Threading/SpinLockWrapper.cs Mono.Threading/ReaderWriterLockSlimmer.cs -../corlib/System.Threading/AtomicBoolean.cs +Mono.Threading/AtomicBoolean.cs ../corlib/System.Collections.Concurrent/ConcurrentOrderedList.cs -../corlib/System.Threading.Tasks/CyclicDeque.cs -../corlib/System.Threading.Tasks/IConcurrentDeque.cs -../corlib/System.Threading.Tasks/PopResult.cs +Mono.Threading.Tasks/CyclicDeque.cs +Mono.Threading.Tasks/IConcurrentDeque.cs +Mono.Threading.Tasks/PopResult.cs diff --git a/mcs/class/Mono.Parallel/Mono.Threading.Tasks/CyclicDeque.cs b/mcs/class/Mono.Parallel/Mono.Threading.Tasks/CyclicDeque.cs new file mode 100644 index 00000000000..a972e9ee244 --- /dev/null +++ b/mcs/class/Mono.Parallel/Mono.Threading.Tasks/CyclicDeque.cs @@ -0,0 +1,217 @@ +// +// CyclicDeque.cs +// +// Author: +// Jérémie "Garuma" Laval +// +// Copyright (c) 2009 Jérémie "Garuma" Laval +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + + +using System; +using System.Collections.Generic; +using System.Threading; + +#if INSIDE_MONO_PARALLEL +namespace Mono.Threading.Tasks +#else +namespace System.Threading.Tasks +#endif +{ +#if INSIDE_MONO_PARALLEL + public +#endif + class CyclicDeque : IConcurrentDeque + { + const int BaseSize = 11; + + int bottom; + int top; + int upperBound; + CircularArray array = new CircularArray (BaseSize); + + public void PushBottom (T obj) + { + int b = bottom; + var a = array; + + // Take care of growing + var size = b - top - upperBound; + if (size >= a.Size) { + upperBound = top; + a = a.Grow (b, upperBound); + array = a; + } + + // Register the new value + a.segment[b % a.size] = obj; + Interlocked.Increment (ref bottom); + } + + public PopResult PopBottom (out T obj) + { + obj = default (T); + + int b = Interlocked.Decrement (ref bottom); + var a = array; + int t = top; + int size = b - t; + + if (size < 0) { + // Set bottom to t + Interlocked.Add (ref bottom, t - b); + return PopResult.Empty; + } + + obj = a.segment[b % a.size]; + if (size > 0) + return PopResult.Succeed; + Interlocked.Add (ref bottom, t + 1 - b); + + if (Interlocked.CompareExchange (ref top, t + 1, t) != t) + return PopResult.Empty; + + return PopResult.Succeed; + } + + public bool PeekBottom (out T obj) + { + obj = default (T); + + int b = Interlocked.Decrement (ref bottom); + var a = array; + int t = top; + int size = b - t; + + if (size < 0) + return false; + + obj = a.segment[b % a.size]; + return true; + } + + public PopResult PopTop (out T obj) + { + obj = default (T); + + int t = top; + int b = bottom; + + if (b - t <= 0) + return PopResult.Empty; + + if (Interlocked.CompareExchange (ref top, t + 1, t) != t) + return PopResult.Abort; + + var a = array; + obj = a.segment[t % a.size]; + + return PopResult.Succeed; + } + + internal bool PeekTop (out T obj) + { + obj = default (T); + + int t = top; + int b = bottom; + + if (b - t <= 0) + return false; + + var a = array; + obj = a.segment[t % a.size]; + + return true; + } + + public IEnumerable GetEnumerable () + { + var a = array; + return a.GetEnumerable (bottom, ref top); + } + + public bool IsEmpty { + get { + int t = top; + int b = bottom; + return b - t <= 0; + } + } + } + + internal class CircularArray + { + readonly int baseSize; + public readonly int size; + public readonly T[] segment; + + public CircularArray (int baseSize) + { + this.baseSize = baseSize; + this.size = 1 << baseSize; + this.segment = new T[size]; + } + + public int Size { + get { + return size; + } + } + + public T this[int index] { + get { + return segment[index % size]; + } + set { + segment[index % size] = value; + } + } + + public CircularArray Grow (int bottom, int top) + { + var grow = new CircularArray (baseSize + 1); + + for (int i = top; i < bottom; i++) { + grow.segment[i] = segment[i % size]; + } + + return grow; + } + + public IEnumerable GetEnumerable (int bottom, ref int top) + { + int instantTop = top; + T[] slice = new T[bottom - instantTop]; + int destIndex = -1; + for (int i = instantTop; i < bottom; i++) + slice[++destIndex] = segment[i % size]; + + return RealGetEnumerable (slice, bottom, top, instantTop); + } + + IEnumerable RealGetEnumerable (T[] slice, int bottom, int realTop, int initialTop) + { + int destIndex = (int)(realTop - initialTop - 1); + for (int i = realTop; i < bottom; ++i) + yield return slice[++destIndex]; + } + } +} diff --git a/mcs/class/Mono.Parallel/Mono.Threading.Tasks/IConcurrentDeque.cs b/mcs/class/Mono.Parallel/Mono.Threading.Tasks/IConcurrentDeque.cs new file mode 100644 index 00000000000..51d1c2d28f2 --- /dev/null +++ b/mcs/class/Mono.Parallel/Mono.Threading.Tasks/IConcurrentDeque.cs @@ -0,0 +1,49 @@ +// +// IConcurrentDeque.cs +// +// Author: +// Jérémie "Garuma" Laval +// +// Copyright (c) 2011 Jérémie "Garuma" Laval +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + + +using System; +using System.Collections.Generic; +using System.Threading; + +#if INSIDE_MONO_PARALLEL +namespace Mono.Threading.Tasks +#else +namespace System.Threading.Tasks +#endif +{ +#if INSIDE_MONO_PARALLEL + public +#endif + interface IConcurrentDeque + { + void PushBottom (T obj); + PopResult PopBottom (out T obj); + PopResult PopTop (out T obj); + IEnumerable GetEnumerable (); + } +} + diff --git a/mcs/class/Mono.Parallel/Mono.Threading.Tasks/PopResult.cs b/mcs/class/Mono.Parallel/Mono.Threading.Tasks/PopResult.cs new file mode 100644 index 00000000000..c8197b82d4a --- /dev/null +++ b/mcs/class/Mono.Parallel/Mono.Threading.Tasks/PopResult.cs @@ -0,0 +1,47 @@ +// +// PopResult.cs +// +// Author: +// Jérémie "Garuma" Laval +// +// Copyright (c) 2011 Jérémie "Garuma" Laval +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + + +using System; +using System.Collections.Generic; +using System.Threading; + +#if INSIDE_MONO_PARALLEL +namespace Mono.Threading.Tasks +#else +namespace System.Threading.Tasks +#endif +{ +#if INSIDE_MONO_PARALLEL + public +#endif + enum PopResult { + Succeed, + Empty, + Abort + } +} + diff --git a/mcs/class/Mono.Parallel/Mono.Threading/AtomicBoolean.cs b/mcs/class/Mono.Parallel/Mono.Threading/AtomicBoolean.cs new file mode 100644 index 00000000000..28faf014b29 --- /dev/null +++ b/mcs/class/Mono.Parallel/Mono.Threading/AtomicBoolean.cs @@ -0,0 +1,186 @@ +// AtomicBoolean.cs +// +// Copyright (c) 2008 Jérémie "Garuma" Laval +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// +// + +using System; + +#if INSIDE_MONO_PARALLEL +using System.Threading; + +namespace Mono.Threading +#else +namespace System.Threading +#endif +{ +#if INSIDE_MONO_PARALLEL + public +#endif + struct AtomicBooleanValue + { + int flag; + const int UnSet = 0; + const int Set = 1; + + public bool CompareAndExchange (bool expected, bool newVal) + { + int newTemp = newVal ? Set : UnSet; + int expectedTemp = expected ? Set : UnSet; + + return Interlocked.CompareExchange (ref flag, newTemp, expectedTemp) == expectedTemp; + } + + public static AtomicBooleanValue FromValue (bool value) + { + AtomicBooleanValue temp = new AtomicBooleanValue (); + temp.Value = value; + + return temp; + } + + public bool TrySet () + { + return !Exchange (true); + } + + public bool TryRelaxedSet () + { + return flag == UnSet && !Exchange (true); + } + + public bool Exchange (bool newVal) + { + int newTemp = newVal ? Set : UnSet; + return Interlocked.Exchange (ref flag, newTemp) == Set; + } + + public bool Value { + get { + return flag == Set; + } + set { + Exchange (value); + } + } + + public bool Equals (AtomicBooleanValue rhs) + { + return this.flag == rhs.flag; + } + + public override bool Equals (object rhs) + { + return rhs is AtomicBooleanValue ? Equals ((AtomicBooleanValue)rhs) : false; + } + + public override int GetHashCode () + { + return flag.GetHashCode (); + } + + public static explicit operator bool (AtomicBooleanValue rhs) + { + return rhs.Value; + } + + public static implicit operator AtomicBooleanValue (bool rhs) + { + return AtomicBooleanValue.FromValue (rhs); + } + } + +#if INSIDE_MONO_PARALLEL + public +#endif + class AtomicBoolean + { + int flag; + const int UnSet = 0; + const int Set = 1; + + public bool CompareAndExchange (bool expected, bool newVal) + { + int newTemp = newVal ? Set : UnSet; + int expectedTemp = expected ? Set : UnSet; + + return Interlocked.CompareExchange (ref flag, newTemp, expectedTemp) == expectedTemp; + } + + public static AtomicBoolean FromValue (bool value) + { + AtomicBoolean temp = new AtomicBoolean (); + temp.Value = value; + + return temp; + } + + public bool TrySet () + { + return !Exchange (true); + } + + public bool TryRelaxedSet () + { + return flag == UnSet && !Exchange (true); + } + + public bool Exchange (bool newVal) + { + int newTemp = newVal ? Set : UnSet; + return Interlocked.Exchange (ref flag, newTemp) == Set; + } + + public bool Value { + get { + return flag == Set; + } + set { + Exchange (value); + } + } + + public bool Equals (AtomicBoolean rhs) + { + return this.flag == rhs.flag; + } + + public override bool Equals (object rhs) + { + return rhs is AtomicBoolean ? Equals ((AtomicBoolean)rhs) : false; + } + + public override int GetHashCode () + { + return flag.GetHashCode (); + } + + public static explicit operator bool (AtomicBoolean rhs) + { + return rhs.Value; + } + + public static implicit operator AtomicBoolean (bool rhs) + { + return AtomicBoolean.FromValue (rhs); + } + } +} -- cgit v1.2.3