1
0
Fork 0
mirror of https://github.com/beefytech/Beef.git synced 2025-06-16 15:24:10 +02:00

Moving corlib files out of "System" directory into root

This commit is contained in:
Brian Fiete 2019-09-19 05:46:35 -07:00
parent 4cd58262e4
commit 7dbfd15292
179 changed files with 3 additions and 0 deletions

View file

@ -0,0 +1,32 @@
// This file contains portions of code released by Microsoft under the MIT license as part
// of an open-sourcing initiative in 2014 of the C# core libraries.
// The original source was submitted to https://github.com/Microsoft/referencesource
namespace System.Threading
{
struct CancellationToken
{
private CancellationTokenSource m_source;
public static CancellationToken None
{
get { return default(CancellationToken); }
}
public bool IsCancellationRequested
{
get
{
return m_source != null && m_source.IsCancellationRequested;
}
}
public bool CanBeCanceled
{
get
{
return m_source != null && m_source.CanBeCanceled;
}
}
}
}

View file

@ -0,0 +1,26 @@
// This file contains portions of code released by Microsoft under the MIT license as part
// of an open-sourcing initiative in 2014 of the C# core libraries.
// The original source was submitted to https://github.com/Microsoft/referencesource
namespace System.Threading
{
class CancellationTokenSource
{
private const int CANNOT_BE_CANCELED = 0;
private const int NOT_CANCELED = 1;
private const int NOTIFYING = 2;
private const int NOTIFYINGCOMPLETE = 3;
private volatile int m_state;
public bool IsCancellationRequested
{
get { return m_state >= NOTIFYING; }
}
internal bool CanBeCanceled
{
get { return m_state != CANNOT_BE_CANCELED; }
}
}
}

View file

@ -0,0 +1,35 @@
namespace System.Threading
{
public class WaitEvent
{
Platform.BfpEvent* mEvent;
public this(bool initiallySet = false)
{
Platform.BfpEventFlags flags = .AllowAutoReset | .AllowManualReset;
if (initiallySet)
flags |= .InitiallySet_Manual;
mEvent = Platform.BfpEvent_Create(flags);
}
public ~this()
{
Platform.BfpEvent_Release(mEvent);
}
public void Set(bool requireManualReset = false)
{
Platform.BfpEvent_Set(mEvent, requireManualReset);
}
public void Reset()
{
Platform.BfpEvent_Reset(mEvent, null);
}
public bool WaitFor(int waitMS = -1)
{
return Platform.BfpEvent_WaitFor(mEvent, (int32)waitMS);
}
}
}

View file

@ -0,0 +1,967 @@
using System.Diagnostics;
namespace System.Threading
{
static class Interlocked
{
public enum AtomicOrdering : uint8
{
Unordered,
Relaxed,
Acquire,
Release,
AcqRel,
SeqCst,
ORDERMASK = 7,
Flag_Volatile = 8,
Flag_ReturnModified = 0x10 // Generally atomic instructions return original value, this overrides that
}
public enum RMWAtomicOrdering : uint8
{
Relaxed = (.)AtomicOrdering.Relaxed,
Acquire = (.)AtomicOrdering.Acquire,
Release = (.)AtomicOrdering.Release,
AcqRel = (.)AtomicOrdering.AcqRel,
SeqCst = (.)AtomicOrdering.SeqCst,
Flag_Volatile = (.)AtomicOrdering.Flag_Volatile,
}
public enum LoadAtomicOrdering : uint8
{
Relaxed = (.)AtomicOrdering.Relaxed,
Acquire = (.)AtomicOrdering.Acquire,
SeqCst = (.)AtomicOrdering.SeqCst,
Flag_Volatile = (.)AtomicOrdering.Flag_Volatile,
}
public enum StoreAtomicOrdering : uint8
{
Relaxed = (.)AtomicOrdering.Relaxed,
Release = (.)AtomicOrdering.Release,
SeqCst = (.)AtomicOrdering.SeqCst,
Flag_Volatile = (.)AtomicOrdering.Flag_Volatile,
}
public enum FenceAtomicOrdering : uint8
{
Acquire = (.)AtomicOrdering.Acquire,
Release = (.)AtomicOrdering.Release,
AcqRel = (.)AtomicOrdering.AcqRel,
SeqCst = (.)AtomicOrdering.SeqCst
}
[Intrinsic("atomic_fence")]
static extern void AtomicFence(AtomicOrdering ordering);
[Inline]
public static void Fence<TAtomicOrdering>(TAtomicOrdering ordering = .SeqCst) where TAtomicOrdering : const FenceAtomicOrdering
{
AtomicFence((AtomicOrdering)ordering);
}
[Intrinsic("atomic_fence")]
public static extern void CompilerBarrier();
[Intrinsic("atomic_load")]
static extern uint8 Load(ref uint8 location, AtomicOrdering ordering);
[Intrinsic("atomic_load")]
static extern uint16 Load(ref uint16 location, AtomicOrdering ordering);
[Intrinsic("atomic_load")]
public static extern uint32 Load(ref uint32 location, AtomicOrdering ordering);
[Intrinsic("atomic_load")]
static extern uint64 Load(ref uint64 location, AtomicOrdering ordering);
[Inline]
public static T Load<T, TAtomicOrdering>(ref T location, TAtomicOrdering ordering = .SeqCst) where TAtomicOrdering : const LoadAtomicOrdering
{
if (sizeof(T) == sizeof(uint8))
{
var result = Load(ref *(uint8*)&location, (AtomicOrdering)ordering);
return *(T*)&result;
}
else if (sizeof(T) == sizeof(uint16))
{
var result = Load(ref *(uint16*)&location, (AtomicOrdering)ordering);
return *(T*)&result;
}
else if (sizeof(T) == sizeof(uint32))
{
var result = Load(ref *(uint32*)&location, (AtomicOrdering)ordering);
return *(T*)&result;
}
else if (sizeof(T) == sizeof(uint64))
{
var result = Load(ref *(uint64*)&location, (AtomicOrdering)ordering);
return *(T*)&result;
}
else
FailOnDataSize();
}
[Intrinsic("atomic_store")]
static extern void Store(ref uint8 location, uint8 value, AtomicOrdering ordering);
[Intrinsic("atomic_store")]
static extern void Store(ref uint16 location, uint16 value, AtomicOrdering ordering);
[Intrinsic("atomic_store")]
static extern void Store(ref uint32 location, uint32 value, AtomicOrdering ordering);
[Intrinsic("atomic_store")]
static extern void Store(ref uint64 location, uint64 value, AtomicOrdering ordering);
[Inline]
public static void Store<T, TAtomicOrdering>(ref T location, T value, TAtomicOrdering ordering = .SeqCst) where TAtomicOrdering : const StoreAtomicOrdering
{
var value;
if (sizeof(T) == sizeof(uint8))
Store(ref *(uint8*)&location, *(uint8*)&value, (AtomicOrdering)ordering);
else if (sizeof(T) == sizeof(uint16))
Store(ref *(uint16*)&location, *(uint16*)&value, (AtomicOrdering)ordering);
else if (sizeof(T) == sizeof(uint32))
Store(ref *(uint32*)&location, *(uint32*)&value, (AtomicOrdering)ordering);
else if (sizeof(T) == sizeof(uint64))
Store(ref *(uint64*)&location, *(uint64*)&value, (AtomicOrdering)ordering);
else
FailOnDataSize();
}
[Intrinsic("atomic_xchg")]
extern static uint8 Exchange(ref uint8 location, uint8 value, AtomicOrdering ordering);
[Intrinsic("atomic_xchg")]
extern static uint16 Exchange(ref uint16 location, uint16 value, AtomicOrdering ordering);
[Intrinsic("atomic_xchg")]
extern static uint32 Exchange(ref uint32 location, uint32 value, AtomicOrdering ordering);
[Intrinsic("atomic_xchg")]
extern static uint64 Exchange(ref uint64 location, uint64 value, AtomicOrdering ordering);
/// Atomically sets a value and returns the original value.
public static T Exchange<T, TAtomicOrdering>(ref T location, T value, TAtomicOrdering ordering = .SeqCst) where TAtomicOrdering : const RMWAtomicOrdering
{
var value;
if (sizeof(T) == sizeof(int8))
{
var result = Exchange(ref *(uint8*)&location, *(uint8*)&value, (AtomicOrdering)ordering);
return *(T*)&result;
}
else if (sizeof(T) == sizeof(int16))
{
var result = Exchange(ref *(uint16*)&location, *(uint16*)&value, (AtomicOrdering)ordering);
return *(T*)&result;
}
else if (sizeof(T) == sizeof(int32))
{
var result = Exchange(ref *(uint32*)&location, *(uint32*)&value, (AtomicOrdering)ordering);
return *(T*)&result;
}
else if (sizeof(T) == sizeof(int64))
{
var result = Exchange(ref *(uint64*)&location, *(uint64*)&value, (AtomicOrdering)ordering);
return *(T*)&result;
}
else
FailOnDataSize();
}
[Intrinsic("atomic_cmpxchg")]
extern static uint8 CompareExchange(ref uint8 location, uint8 comparand, uint8 value, AtomicOrdering successOrdering);
[Intrinsic("atomic_cmpxchg")]
extern static uint16 CompareExchange(ref uint16 location, uint16 comparand, uint16 value, AtomicOrdering successOrdering);
[Intrinsic("atomic_cmpxchg")]
extern static uint32 CompareExchange(ref uint32 location, uint32 comparand, uint32 value, AtomicOrdering successOrdering);
[Intrinsic("atomic_cmpxchg")]
extern static uint64 CompareExchange(ref uint64 location, uint64 comparand, uint64 value, AtomicOrdering successOrdering);
/// Compares 'location' to 'comparand' for equality and, if they are equal, replaces 'location' with 'value' and returns the original value in 'location'.
/// @param location The destination, whose value is compared with comparand and possibly replaced.
/// @param value The value that replaces the destination value if the comparison results in equality.
/// @param comparand The value that is compared to the value at location.
[Inline]
public static T CompareExchange<T, TAtomicOrdering>(ref T location, T comparand, T value, TAtomicOrdering successOrdering = .SeqCst) where TAtomicOrdering : const RMWAtomicOrdering
{
var value;
var comparand;
if (sizeof(T) == sizeof(int8))
{
var result = CompareExchange(ref *(uint8*)&location, *(uint8*)&comparand, *(uint8*)&value, (AtomicOrdering)successOrdering);
return *(T*)&result;
}
else if (sizeof(T) == sizeof(int16))
{
var result = CompareExchange(ref *(uint16*)&location, *(uint16*)&comparand, *(uint16*)&value, (AtomicOrdering)successOrdering);
return *(T*)&result;
}
else if (sizeof(T) == sizeof(int32))
{
var result = CompareExchange(ref *(uint32*)&location, *(uint32*)&comparand, *(uint32*)&value, (AtomicOrdering)successOrdering);
return *(T*)&result;
}
else if (sizeof(T) == sizeof(int64))
{
var result = CompareExchange(ref *(uint64*)&location, *(uint64*)&comparand, *(uint64*)&value, (AtomicOrdering)successOrdering);
return *(T*)&result;
}
else
FailOnDataSize();
}
[Intrinsic("atomic_cmpxchg")]
extern static uint8 CompareExchange(ref uint8 location, uint8 comparand, uint8 value, AtomicOrdering successOrdering, AtomicOrdering failOrdering);
[Intrinsic("atomic_cmpxchg")]
extern static uint16 CompareExchange(ref uint16 location, uint16 comparand, uint16 value, AtomicOrdering successOrdering, AtomicOrdering failOrdering);
[Intrinsic("atomic_cmpxchg")]
extern static uint32 CompareExchange(ref uint32 location, uint32 comparand, uint32 value, AtomicOrdering successOrdering, AtomicOrdering failOrdering);
[Intrinsic("atomic_cmpxchg")]
extern static uint64 CompareExchange(ref uint64 location, uint64 comparand, uint64 value, AtomicOrdering successOrdering, AtomicOrdering failOrdering);
/// Compares 'location' to 'comparand' for equality and, if they are equal, replaces 'location' with 'value' and returns the original value in 'location'.
/// @param location The destination, whose value is compared with comparand and possibly replaced.
/// @param value The value that replaces the destination value if the comparison results in equality.
/// @param comparand The value that is compared to the value at location.
[Inline]
public static T CompareExchange<T, TSuccessOrdering, TFailOrdering>(ref T location, T comparand, T value, TSuccessOrdering successOrdering, TFailOrdering failOrdering)
where TSuccessOrdering : const RMWAtomicOrdering
where TFailOrdering : const LoadAtomicOrdering
{
var value;
var comparand;
if (sizeof(T) == sizeof(int8))
{
var result = CompareExchange(ref *(uint8*)&location, *(uint8*)&comparand, *(uint8*)&value, (AtomicOrdering)successOrdering, (AtomicOrdering)failOrdering);
return *(T*)&result;
}
else if (sizeof(T) == sizeof(int16))
{
var result = CompareExchange(ref *(uint16*)&location, *(uint16*)&comparand, *(uint16*)&value, (AtomicOrdering)successOrdering, (AtomicOrdering)failOrdering);
return *(T*)&result;
}
else if (sizeof(T) == sizeof(int32))
{
var result = CompareExchange(ref *(uint32*)&location, *(uint32*)&comparand, *(uint32*)&value, (AtomicOrdering)successOrdering, (AtomicOrdering)failOrdering);
return *(T*)&result;
}
else if (sizeof(T) == sizeof(int64))
{
var result = CompareExchange(ref *(uint64*)&location, *(uint64*)&comparand, *(uint64*)&value, (AtomicOrdering)successOrdering, (AtomicOrdering)failOrdering);
return *(T*)&result;
}
else
FailOnDataSize();
}
[Intrinsic("atomic_cmpstore")]
extern static bool CompareStore(ref uint8 location, uint8 comparand, uint8 value, AtomicOrdering ordering);
[Intrinsic("atomic_cmpstore")]
extern static bool CompareStore(ref uint16 location, uint16 comparand, uint16 value, AtomicOrdering ordering);
[Intrinsic("atomic_cmpstore")]
extern static bool CompareStore(ref uint32 location, uint32 comparand, uint32 value, AtomicOrdering ordering);
[Intrinsic("atomic_cmpstore")]
extern static bool CompareStore(ref uint64 location, uint64 comparand, uint64 value, AtomicOrdering ordering);
/// Compares 'location' to 'comparand' for equality and, if they are equal, replaces 'location' with 'value' and returns the original value in 'location'.
/// @param location The destination, whose value is compared with comparand and possibly replaced.
/// @param value The value that replaces the destination value if the comparison results in equality.
/// @param comparand The value that is compared to the value at location.
[Inline]
public static bool CompareStore<T, TAtomicOrdering>(ref T location, T comparand, T value, TAtomicOrdering ordering = .SeqCst) where TAtomicOrdering : const RMWAtomicOrdering
{
var value;
var comparand;
if (sizeof(T) == sizeof(int8))
return CompareStore(ref *(uint8*)&location, *(uint8*)&comparand, *(uint8*)&value, (AtomicOrdering)ordering);
else if (sizeof(T) == sizeof(int16))
return CompareStore(ref *(uint16*)&location, *(uint16*)&comparand, *(uint16*)&value, (AtomicOrdering)ordering);
else if (sizeof(T) == sizeof(int32))
return CompareStore(ref *(uint32*)&location, *(uint32*)&comparand, *(uint32*)&value, (AtomicOrdering)ordering);
else if (sizeof(T) == sizeof(int64))
return CompareStore(ref *(uint64*)&location, *(uint64*)&comparand, *(uint64*)&value, (AtomicOrdering)ordering);
else
FailOnDataSize();
}
[Intrinsic("atomic_cmpstore_weak")]
extern static bool CompareStoreWeak(ref uint8 location, uint8 comparand, uint8 value, AtomicOrdering ordering);
[Intrinsic("atomic_cmpstore_weak")]
extern static bool CompareStoreWeak(ref uint16 location, uint16 comparand, uint16 value, AtomicOrdering ordering);
[Intrinsic("atomic_cmpstore_weak")]
extern static bool CompareStoreWeak(ref uint32 location, uint32 comparand, uint32 value, AtomicOrdering ordering);
[Intrinsic("atomic_cmpstore_weak")]
extern static bool CompareStoreWeak(ref uint64 location, uint64 comparand, uint64 value, AtomicOrdering ordering);
/// Compares 'location' to 'comparand' for equality and, if they are equal, replaces 'location' with 'value' and returns the original value in 'location'.
/// @param location The destination, whose value is compared with comparand and possibly replaced.
/// @param value The value that replaces the destination value if the comparison results in equality.
/// @param comparand The value that is compared to the value at location.
[Inline]
public static bool CompareStoreWeak<T, TAtomicOrdering>(ref T location, T comparand, T value, TAtomicOrdering ordering = .SeqCst) where TAtomicOrdering : const RMWAtomicOrdering
{
var value;
var comparand;
if (sizeof(T) == sizeof(int8))
return CompareStoreWeak(ref *(uint8*)&location, *(uint8*)&comparand, *(uint8*)&value, (AtomicOrdering)ordering);
else if (sizeof(T) == sizeof(int16))
return CompareStoreWeak(ref *(uint16*)&location, *(uint16*)&comparand, *(uint16*)&value, (AtomicOrdering)ordering);
else if (sizeof(T) == sizeof(int32))
return CompareStoreWeak(ref *(uint32*)&location, *(uint32*)&comparand, *(uint32*)&value, (AtomicOrdering)ordering);
else if (sizeof(T) == sizeof(int64))
return CompareStoreWeak(ref *(uint64*)&location, *(uint64*)&comparand, *(uint64*)&value, (AtomicOrdering)ordering);
else
FailOnDataSize();
}
//////
[Intrinsic("atomic_add")]
extern static float Add(ref float location, float value, AtomicOrdering ordering);
[Intrinsic("atomic_add")]
extern static double Add(ref double location, double value, AtomicOrdering ordering);
[Intrinsic("atomic_add")]
extern static uint8 Add(ref uint8 location, uint8 value, AtomicOrdering ordering);
[Intrinsic("atomic_add")]
extern static uint16 Add(ref uint16 location, uint16 value, AtomicOrdering ordering);
[Intrinsic("atomic_add")]
extern static uint32 Add(ref uint32 location, uint32 value, AtomicOrdering ordering);
[Intrinsic("atomic_add")]
extern static uint64 Add(ref uint64 location, uint64 value, AtomicOrdering ordering);
[Inline]
public static T Add<T, TAtomicOrdering>(ref T location, T value, TAtomicOrdering ordering = .SeqCst) where T : IInteger where TAtomicOrdering : const RMWAtomicOrdering
{
var value;
if (sizeof(T) == sizeof(int8))
{
var result = Add(ref *(uint8*)&location, *(uint8*)&value, (AtomicOrdering)ordering | .Flag_ReturnModified);
return *(T*)&result;
}
else if (sizeof(T) == sizeof(int16))
{
var result = Add(ref *(uint16*)&location, *(uint16*)&value, (AtomicOrdering)ordering | .Flag_ReturnModified);
return *(T*)&result;
}
else if (sizeof(T) == sizeof(int32))
{
var result = Add(ref *(uint32*)&location, *(uint32*)&value, (AtomicOrdering)ordering | .Flag_ReturnModified);
return *(T*)&result;
}
else if (sizeof(T) == sizeof(int64))
{
var result = Add(ref *(uint64*)&location, *(uint64*)&value, (AtomicOrdering)ordering | .Flag_ReturnModified);
return *(T*)&result;
}
else
FailOnDataSize();
}
[Inline]
public static T Add<T, TAtomicOrdering>(ref T location, T value, TAtomicOrdering ordering = .SeqCst) where T : IFloating where TAtomicOrdering : const RMWAtomicOrdering
{
var value;
if (sizeof(T) == sizeof(float))
{
var result = Add(ref *(float*)&location, *(float*)&value, (AtomicOrdering)ordering | .Flag_ReturnModified);
return *(T*)&result;
}
else if (sizeof(T) == sizeof(double))
{
var result = Add(ref *(double*)&location, *(double*)&value, (AtomicOrdering)ordering | .Flag_ReturnModified);
return *(T*)&result;
}
else
FailOnDataSize();
}
[Inline]
public static T ExchangeAdd<T, TAtomicOrdering>(ref T location, T value, TAtomicOrdering ordering = .SeqCst) where T : IInteger where TAtomicOrdering : const RMWAtomicOrdering
{
var value;
if (sizeof(T) == sizeof(int8))
{
var result = Add(ref *(uint8*)&location, *(uint8*)&value, (AtomicOrdering)ordering);
return *(T*)&result;
}
else if (sizeof(T) == sizeof(int16))
{
var result = Add(ref *(uint16*)&location, *(uint16*)&value, (AtomicOrdering)ordering);
return *(T*)&result;
}
else if (sizeof(T) == sizeof(int32))
{
var result = Add(ref *(uint32*)&location, *(uint32*)&value, (AtomicOrdering)ordering);
return *(T*)&result;
}
else if (sizeof(T) == sizeof(int64))
{
var result = Add(ref *(uint64*)&location, *(uint64*)&value, (AtomicOrdering)ordering);
return *(T*)&result;
}
else
FailOnDataSize();
}
[Inline]
public static T ExchangeAdd<T, TAtomicOrdering>(ref T location, T value, TAtomicOrdering ordering = .SeqCst) where T : IFloating where TAtomicOrdering : const RMWAtomicOrdering
{
var value;
if (sizeof(T) == sizeof(float))
{
var result = Add(ref *(float*)&location, *(float*)&value, (AtomicOrdering)ordering);
return *(T*)&result;
}
else if (sizeof(T) == sizeof(double))
{
var result = Add(ref *(double*)&location, *(double*)&value, (AtomicOrdering)ordering);
return *(T*)&result;
}
else
FailOnDataSize();
}
[Inline]
public static T Increment<T, TAtomicOrdering>(ref T location, TAtomicOrdering ordering = .SeqCst) where T : IInteger where TAtomicOrdering : const RMWAtomicOrdering
{
if (sizeof(T) == sizeof(int8))
{
var result = Add(ref *(uint8*)&location, 1, (AtomicOrdering)ordering | .Flag_ReturnModified);
return *(T*)&result;
}
else if (sizeof(T) == sizeof(int16))
{
var result = Add(ref *(uint16*)&location, 1, (AtomicOrdering)ordering | .Flag_ReturnModified);
return *(T*)&result;
}
else if (sizeof(T) == sizeof(int32))
{
var result = Add(ref *(uint32*)&location, 1, (AtomicOrdering)ordering | .Flag_ReturnModified);
return *(T*)&result;
}
else if (sizeof(T) == sizeof(int64))
{
var result = Add(ref *(uint64*)&location, 1, (AtomicOrdering)ordering | .Flag_ReturnModified);
return *(T*)&result;
}
else
FailOnDataSize();
}
[Intrinsic("atomic_and")]
extern static float And(ref float location, float value, AtomicOrdering ordering);
[Intrinsic("atomic_and")]
extern static double And(ref double location, double value, AtomicOrdering ordering);
[Intrinsic("atomic_and")]
extern static uint8 And(ref uint8 location, uint8 value, AtomicOrdering ordering);
[Intrinsic("atomic_and")]
extern static uint16 And(ref uint16 location, uint16 value, AtomicOrdering ordering);
[Intrinsic("atomic_and")]
extern static uint32 And(ref uint32 location, uint32 value, AtomicOrdering ordering);
[Intrinsic("atomic_and")]
extern static uint64 And(ref uint64 location, uint64 value, AtomicOrdering ordering);
[Inline]
public static T And<T, TAtomicOrdering>(ref T location, T value, TAtomicOrdering ordering = .SeqCst) where T : IInteger where TAtomicOrdering : const RMWAtomicOrdering
{
var value;
if (sizeof(T) == sizeof(int8))
{
var result = And(ref *(uint8*)&location, *(uint8*)&value, (AtomicOrdering)ordering | .Flag_ReturnModified);
return *(T*)&result;
}
else if (sizeof(T) == sizeof(int16))
{
var result = And(ref *(uint16*)&location, *(uint16*)&value, (AtomicOrdering)ordering | .Flag_ReturnModified);
return *(T*)&result;
}
else if (sizeof(T) == sizeof(int32))
{
var result = And(ref *(uint32*)&location, *(uint32*)&value, (AtomicOrdering)ordering | .Flag_ReturnModified);
return *(T*)&result;
}
else if (sizeof(T) == sizeof(int64))
{
var result = And(ref *(uint64*)&location, *(uint64*)&value, (AtomicOrdering)ordering | .Flag_ReturnModified);
return *(T*)&result;
}
else
FailOnDataSize();
}
[Inline]
public static T ExchangeAnd<T, TAtomicOrdering>(ref T location, T value, TAtomicOrdering ordering = .SeqCst) where T : IInteger where TAtomicOrdering : const RMWAtomicOrdering
{
var value;
if (sizeof(T) == sizeof(int8))
{
var result = And(ref *(uint8*)&location, *(uint8*)&value, (AtomicOrdering)ordering);
return *(T*)&result;
}
else if (sizeof(T) == sizeof(int16))
{
var result = And(ref *(uint16*)&location, *(uint16*)&value, (AtomicOrdering)ordering);
return *(T*)&result;
}
else if (sizeof(T) == sizeof(int32))
{
var result = And(ref *(uint32*)&location, *(uint32*)&value, (AtomicOrdering)ordering);
return *(T*)&result;
}
else if (sizeof(T) == sizeof(int64))
{
var result = And(ref *(uint64*)&location, *(uint64*)&value, (AtomicOrdering)ordering);
return *(T*)&result;
}
else
FailOnDataSize();
}
[Intrinsic("atomic_max")]
extern static float Max(ref float location, float value, AtomicOrdering ordering);
[Intrinsic("atomic_max")]
extern static double Max(ref double location, double value, AtomicOrdering ordering);
[Intrinsic("atomic_max")]
extern static uint8 Max(ref uint8 location, uint8 value, AtomicOrdering ordering);
[Intrinsic("atomic_max")]
extern static uint16 Max(ref uint16 location, uint16 value, AtomicOrdering ordering);
[Intrinsic("atomic_max")]
extern static uint32 Max(ref uint32 location, uint32 value, AtomicOrdering ordering);
[Intrinsic("atomic_max")]
extern static uint64 Max(ref uint64 location, uint64 value, AtomicOrdering ordering);
[Inline]
public static T Max<T, TAtomicOrdering>(ref T location, T value, TAtomicOrdering ordering = .SeqCst) where T : IInteger where TAtomicOrdering : const RMWAtomicOrdering
{
var value;
if (sizeof(T) == sizeof(int8))
{
var result = Max(ref *(uint8*)&location, *(uint8*)&value, (AtomicOrdering)ordering | .Flag_ReturnModified);
return *(T*)&result;
}
else if (sizeof(T) == sizeof(int16))
{
var result = Max(ref *(uint16*)&location, *(uint16*)&value, (AtomicOrdering)ordering | .Flag_ReturnModified);
return *(T*)&result;
}
else if (sizeof(T) == sizeof(int32))
{
var result = Max(ref *(uint32*)&location, *(uint32*)&value, (AtomicOrdering)ordering | .Flag_ReturnModified);
return *(T*)&result;
}
else if (sizeof(T) == sizeof(int64))
{
var result = Max(ref *(uint64*)&location, *(uint64*)&value, (AtomicOrdering)ordering | .Flag_ReturnModified);
return *(T*)&result;
}
else
FailOnDataSize();
}
[Inline]
public static T ExchangeMax<T, TAtomicOrdering>(ref T location, T value, TAtomicOrdering ordering = .SeqCst) where T : IInteger where TAtomicOrdering : const RMWAtomicOrdering
{
var value;
if (sizeof(T) == sizeof(int8))
{
var result = Max(ref *(uint8*)&location, *(uint8*)&value, (AtomicOrdering)ordering);
return *(T*)&result;
}
else if (sizeof(T) == sizeof(int16))
{
var result = Max(ref *(uint16*)&location, *(uint16*)&value, (AtomicOrdering)ordering);
return *(T*)&result;
}
else if (sizeof(T) == sizeof(int32))
{
var result = Max(ref *(uint32*)&location, *(uint32*)&value, (AtomicOrdering)ordering);
return *(T*)&result;
}
else if (sizeof(T) == sizeof(int64))
{
var result = Max(ref *(uint64*)&location, *(uint64*)&value, (AtomicOrdering)ordering);
return *(T*)&result;
}
else
FailOnDataSize();
}
[Intrinsic("atomic_min")]
extern static float Min(ref float location, float value, AtomicOrdering ordering);
[Intrinsic("atomic_min")]
extern static double Min(ref double location, double value, AtomicOrdering ordering);
[Intrinsic("atomic_min")]
extern static uint8 Min(ref uint8 location, uint8 value, AtomicOrdering ordering);
[Intrinsic("atomic_min")]
extern static uint16 Min(ref uint16 location, uint16 value, AtomicOrdering ordering);
[Intrinsic("atomic_min")]
extern static uint32 Min(ref uint32 location, uint32 value, AtomicOrdering ordering);
[Intrinsic("atomic_min")]
extern static uint64 Min(ref uint64 location, uint64 value, AtomicOrdering ordering);
[Inline]
public static T Min<T, TAtomicOrdering>(ref T location, T value, TAtomicOrdering ordering = .SeqCst) where T : IInteger where TAtomicOrdering : const RMWAtomicOrdering
{
var value;
if (sizeof(T) == sizeof(int8))
{
var result = Min(ref *(uint8*)&location, *(uint8*)&value, (AtomicOrdering)ordering | .Flag_ReturnModified);
return *(T*)&result;
}
else if (sizeof(T) == sizeof(int16))
{
var result = Min(ref *(uint16*)&location, *(uint16*)&value, (AtomicOrdering)ordering | .Flag_ReturnModified);
return *(T*)&result;
}
else if (sizeof(T) == sizeof(int32))
{
var result = Min(ref *(uint32*)&location, *(uint32*)&value, (AtomicOrdering)ordering | .Flag_ReturnModified);
return *(T*)&result;
}
else if (sizeof(T) == sizeof(int64))
{
var result = Min(ref *(uint64*)&location, *(uint64*)&value, (AtomicOrdering)ordering | .Flag_ReturnModified);
return *(T*)&result;
}
else
FailOnDataSize();
}
[Inline]
public static T ExchangeMin<T, TAtomicOrdering>(ref T location, T value, TAtomicOrdering ordering = .SeqCst) where T : IInteger where TAtomicOrdering : const RMWAtomicOrdering
{
var value;
if (sizeof(T) == sizeof(int8))
{
var result = Min(ref *(uint8*)&location, *(uint8*)&value, (AtomicOrdering)ordering);
return *(T*)&result;
}
else if (sizeof(T) == sizeof(int16))
{
var result = Min(ref *(uint16*)&location, *(uint16*)&value, (AtomicOrdering)ordering);
return *(T*)&result;
}
else if (sizeof(T) == sizeof(int32))
{
var result = Min(ref *(uint32*)&location, *(uint32*)&value, (AtomicOrdering)ordering);
return *(T*)&result;
}
else if (sizeof(T) == sizeof(int64))
{
var result = Min(ref *(uint64*)&location, *(uint64*)&value, (AtomicOrdering)ordering);
return *(T*)&result;
}
else
FailOnDataSize();
}
[Intrinsic("atomic_nand")]
extern static float Nand(ref float location, float value, AtomicOrdering ordering);
[Intrinsic("atomic_nand")]
extern static double Nand(ref double location, double value, AtomicOrdering ordering);
[Intrinsic("atomic_nand")]
extern static uint8 Nand(ref uint8 location, uint8 value, AtomicOrdering ordering);
[Intrinsic("atomic_nand")]
extern static uint16 Nand(ref uint16 location, uint16 value, AtomicOrdering ordering);
[Intrinsic("atomic_nand")]
extern static uint32 Nand(ref uint32 location, uint32 value, AtomicOrdering ordering);
[Intrinsic("atomic_nand")]
extern static uint64 Nand(ref uint64 location, uint64 value, AtomicOrdering ordering);
[Inline]
public static T Nand<T, TAtomicOrdering>(ref T location, T value, TAtomicOrdering ordering = .SeqCst) where T : IInteger where TAtomicOrdering : const RMWAtomicOrdering
{
var value;
if (sizeof(T) == sizeof(int8))
{
var result = Nand(ref *(uint8*)&location, *(uint8*)&value, (AtomicOrdering)ordering | .Flag_ReturnModified);
return *(T*)&result;
}
else if (sizeof(T) == sizeof(int16))
{
var result = Nand(ref *(uint16*)&location, *(uint16*)&value, (AtomicOrdering)ordering | .Flag_ReturnModified);
return *(T*)&result;
}
else if (sizeof(T) == sizeof(int32))
{
var result = Nand(ref *(uint32*)&location, *(uint32*)&value, (AtomicOrdering)ordering | .Flag_ReturnModified);
return *(T*)&result;
}
else if (sizeof(T) == sizeof(int64))
{
var result = Nand(ref *(uint64*)&location, *(uint64*)&value, (AtomicOrdering)ordering | .Flag_ReturnModified);
return *(T*)&result;
}
else
FailOnDataSize();
}
[Inline]
public static T ExchangeNand<T, TAtomicOrdering>(ref T location, T value, TAtomicOrdering ordering = .SeqCst) where T : IInteger where TAtomicOrdering : const RMWAtomicOrdering
{
var value;
if (sizeof(T) == sizeof(int8))
{
var result = Nand(ref *(uint8*)&location, *(uint8*)&value, (AtomicOrdering)ordering);
return *(T*)&result;
}
else if (sizeof(T) == sizeof(int16))
{
var result = Nand(ref *(uint16*)&location, *(uint16*)&value, (AtomicOrdering)ordering);
return *(T*)&result;
}
else if (sizeof(T) == sizeof(int32))
{
var result = Nand(ref *(uint32*)&location, *(uint32*)&value, (AtomicOrdering)ordering);
return *(T*)&result;
}
else if (sizeof(T) == sizeof(int64))
{
var result = Nand(ref *(uint64*)&location, *(uint64*)&value, (AtomicOrdering)ordering);
return *(T*)&result;
}
else
FailOnDataSize();
}
[Intrinsic("atomic_or")]
extern static float Or(ref float location, float value, AtomicOrdering ordering);
[Intrinsic("atomic_or")]
extern static double Or(ref double location, double value, AtomicOrdering ordering);
[Intrinsic("atomic_or")]
extern static uint8 Or(ref uint8 location, uint8 value, AtomicOrdering ordering);
[Intrinsic("atomic_or")]
extern static uint16 Or(ref uint16 location, uint16 value, AtomicOrdering ordering);
[Intrinsic("atomic_or")]
extern static uint32 Or(ref uint32 location, uint32 value, AtomicOrdering ordering);
[Intrinsic("atomic_or")]
extern static uint64 Or(ref uint64 location, uint64 value, AtomicOrdering ordering);
[Inline]
public static T Or<T, TAtomicOrdering>(ref T location, T value, TAtomicOrdering ordering = .SeqCst) where T : IInteger where TAtomicOrdering : const RMWAtomicOrdering
{
var value;
if (sizeof(T) == sizeof(int8))
{
var result = Or(ref *(uint8*)&location, *(uint8*)&value, (AtomicOrdering)ordering | .Flag_ReturnModified);
return *(T*)&result;
}
else if (sizeof(T) == sizeof(int16))
{
var result = Or(ref *(uint16*)&location, *(uint16*)&value, (AtomicOrdering)ordering | .Flag_ReturnModified);
return *(T*)&result;
}
else if (sizeof(T) == sizeof(int32))
{
var result = Or(ref *(uint32*)&location, *(uint32*)&value, (AtomicOrdering)ordering | .Flag_ReturnModified);
return *(T*)&result;
}
else if (sizeof(T) == sizeof(int64))
{
var result = Or(ref *(uint64*)&location, *(uint64*)&value, (AtomicOrdering)ordering | .Flag_ReturnModified);
return *(T*)&result;
}
else
FailOnDataSize();
}
[Inline]
public static T ExchangeOr<T, TAtomicOrdering>(ref T location, T value, TAtomicOrdering ordering = .SeqCst) where T : IInteger where TAtomicOrdering : const RMWAtomicOrdering
{
var value;
if (sizeof(T) == sizeof(int8))
{
var result = Or(ref *(uint8*)&location, *(uint8*)&value, (AtomicOrdering)ordering);
return *(T*)&result;
}
else if (sizeof(T) == sizeof(int16))
{
var result = Or(ref *(uint16*)&location, *(uint16*)&value, (AtomicOrdering)ordering);
return *(T*)&result;
}
else if (sizeof(T) == sizeof(int32))
{
var result = Or(ref *(uint32*)&location, *(uint32*)&value, (AtomicOrdering)ordering);
return *(T*)&result;
}
else if (sizeof(T) == sizeof(int64))
{
var result = Or(ref *(uint64*)&location, *(uint64*)&value, (AtomicOrdering)ordering);
return *(T*)&result;
}
else
FailOnDataSize();
}
[Intrinsic("atomic_sub")]
extern static float Sub(ref float location, float value, AtomicOrdering ordering);
[Intrinsic("atomic_sub")]
extern static double Sub(ref double location, double value, AtomicOrdering ordering);
[Intrinsic("atomic_sub")]
extern static uint8 Sub(ref uint8 location, uint8 value, AtomicOrdering ordering);
[Intrinsic("atomic_sub")]
extern static uint16 Sub(ref uint16 location, uint16 value, AtomicOrdering ordering);
[Intrinsic("atomic_sub")]
extern static uint32 Sub(ref uint32 location, uint32 value, AtomicOrdering ordering);
[Intrinsic("atomic_sub")]
extern static uint64 Sub(ref uint64 location, uint64 value, AtomicOrdering ordering);
[Inline]
public static T Sub<T, TAtomicOrdering>(ref T location, T value, TAtomicOrdering ordering = .SeqCst) where T : IInteger where TAtomicOrdering : const RMWAtomicOrdering
{
var value;
if (sizeof(T) == sizeof(int8))
{
var result = Sub(ref *(uint8*)&location, *(uint8*)&value, (AtomicOrdering)ordering | .Flag_ReturnModified);
return *(T*)&result;
}
else if (sizeof(T) == sizeof(int16))
{
var result = Sub(ref *(uint16*)&location, *(uint16*)&value, (AtomicOrdering)ordering | .Flag_ReturnModified);
return *(T*)&result;
}
else if (sizeof(T) == sizeof(int32))
{
var result = Sub(ref *(uint32*)&location, *(uint32*)&value, (AtomicOrdering)ordering | .Flag_ReturnModified);
return *(T*)&result;
}
else if (sizeof(T) == sizeof(int64))
{
var result = Sub(ref *(uint64*)&location, *(uint64*)&value, (AtomicOrdering)ordering | .Flag_ReturnModified);
return *(T*)&result;
}
else
FailOnDataSize();
}
[Inline]
public static T Sub<T, TAtomicOrdering>(ref T location, T value, TAtomicOrdering ordering = .SeqCst) where T : IFloating where TAtomicOrdering : const RMWAtomicOrdering
{
var value;
if (sizeof(T) == sizeof(float))
{
var result = Sub(ref *(float*)&location, *(float*)&value, (AtomicOrdering)ordering | .Flag_ReturnModified);
return *(T*)&result;
}
else if (sizeof(T) == sizeof(double))
{
var result = Sub(ref *(double*)&location, *(double*)&value, (AtomicOrdering)ordering | .Flag_ReturnModified);
return *(T*)&result;
}
else
FailOnDataSize();
}
[Inline]
public static T ExchangeSub<T, TAtomicOrdering>(ref T location, T value, TAtomicOrdering ordering = .SeqCst) where T : IInteger where TAtomicOrdering : const RMWAtomicOrdering
{
var value;
if (sizeof(T) == sizeof(int8))
{
var result = Sub(ref *(uint8*)&location, *(uint8*)&value, (AtomicOrdering)ordering);
return *(T*)&result;
}
else if (sizeof(T) == sizeof(int16))
{
var result = Sub(ref *(uint16*)&location, *(uint16*)&value, (AtomicOrdering)ordering);
return *(T*)&result;
}
else if (sizeof(T) == sizeof(int32))
{
var result = Sub(ref *(uint32*)&location, *(uint32*)&value, (AtomicOrdering)ordering);
return *(T*)&result;
}
else if (sizeof(T) == sizeof(int64))
{
var result = Sub(ref *(uint64*)&location, *(uint64*)&value, (AtomicOrdering)ordering);
return *(T*)&result;
}
else
FailOnDataSize();
}
[Inline]
public static T ExchangeSub<T, TAtomicOrdering>(ref T location, T value, TAtomicOrdering ordering = .SeqCst) where T : IFloating where TAtomicOrdering : const RMWAtomicOrdering
{
var value;
if (sizeof(T) == sizeof(float))
{
var result = Sub(ref *(float*)&location, *(float*)&value, (AtomicOrdering)ordering);
return *(T*)&result;
}
else if (sizeof(T) == sizeof(double))
{
var result = Sub(ref *(double*)&location, *(double*)&value, (AtomicOrdering)ordering);
return *(T*)&result;
}
else
FailOnDataSize();
}
[Inline]
public static T Decrement<T, TAtomicOrdering>(ref T location, TAtomicOrdering ordering = .SeqCst) where T : IInteger where TAtomicOrdering : const RMWAtomicOrdering
{
if (sizeof(T) == sizeof(int8))
{
var result = Sub(ref *(uint8*)&location, 1, (AtomicOrdering)ordering | .Flag_ReturnModified);
return *(T*)&result;
}
else if (sizeof(T) == sizeof(int16))
{
var result = Sub(ref *(uint16*)&location, 1, (AtomicOrdering)ordering | .Flag_ReturnModified);
return *(T*)&result;
}
else if (sizeof(T) == sizeof(int32))
{
var result = Sub(ref *(uint32*)&location, 1, (AtomicOrdering)ordering | .Flag_ReturnModified);
return *(T*)&result;
}
else if (sizeof(T) == sizeof(int64))
{
var result = Sub(ref *(uint64*)&location, 1, (AtomicOrdering)ordering | .Flag_ReturnModified);
return *(T*)&result;
}
else
FailOnDataSize();
}
[Intrinsic("atomic_xor")]
extern static float Xor(ref float location, float value, AtomicOrdering ordering);
[Intrinsic("atomic_xor")]
extern static double Xor(ref double location, double value, AtomicOrdering ordering);
[Intrinsic("atomic_xor")]
extern static uint8 Xor(ref uint8 location, uint8 value, AtomicOrdering ordering);
[Intrinsic("atomic_xor")]
extern static uint16 Xor(ref uint16 location, uint16 value, AtomicOrdering ordering);
[Intrinsic("atomic_xor")]
extern static uint32 Xor(ref uint32 location, uint32 value, AtomicOrdering ordering);
[Intrinsic("atomic_xor")]
extern static uint64 Xor(ref uint64 location, uint64 value, AtomicOrdering ordering);
[Inline]
public static T Xor<T, TAtomicOrdering>(ref T location, T value, TAtomicOrdering ordering = .SeqCst) where T : IInteger where TAtomicOrdering : const RMWAtomicOrdering
{
var value;
if (sizeof(T) == sizeof(int8))
{
var result = Xor(ref *(uint8*)&location, *(uint8*)&value, (AtomicOrdering)ordering | .Flag_ReturnModified);
return *(T*)&result;
}
else if (sizeof(T) == sizeof(int16))
{
var result = Xor(ref *(uint16*)&location, *(uint16*)&value, (AtomicOrdering)ordering | .Flag_ReturnModified);
return *(T*)&result;
}
else if (sizeof(T) == sizeof(int32))
{
var result = Xor(ref *(uint32*)&location, *(uint32*)&value, (AtomicOrdering)ordering | .Flag_ReturnModified);
return *(T*)&result;
}
else if (sizeof(T) == sizeof(int64))
{
var result = Xor(ref *(uint64*)&location, *(uint64*)&value, (AtomicOrdering)ordering | .Flag_ReturnModified);
return *(T*)&result;
}
else
FailOnDataSize();
}
[Inline]
public static T ExchangeXor<T, TAtomicOrdering>(ref T location, T value, TAtomicOrdering ordering = .SeqCst) where T : IInteger where TAtomicOrdering : const RMWAtomicOrdering
{
var value;
if (sizeof(T) == sizeof(int8))
{
var result = Xor(ref *(uint8*)&location, *(uint8*)&value, (AtomicOrdering)ordering);
return *(T*)&result;
}
else if (sizeof(T) == sizeof(int16))
{
var result = Xor(ref *(uint16*)&location, *(uint16*)&value, (AtomicOrdering)ordering);
return *(T*)&result;
}
else if (sizeof(T) == sizeof(int32))
{
var result = Xor(ref *(uint32*)&location, *(uint32*)&value, (AtomicOrdering)ordering);
return *(T*)&result;
}
else if (sizeof(T) == sizeof(int64))
{
var result = Xor(ref *(uint64*)&location, *(uint64*)&value, (AtomicOrdering)ordering);
return *(T*)&result;
}
else
FailOnDataSize();
}
[NoReturn]
static void FailOnDataSize()
{
Runtime.FatalError("Data size not supported");
}
}
}

View file

@ -0,0 +1,76 @@
using System;
using System.Diagnostics;
namespace System.Threading
{
public class Monitor
{
public struct MonitorLockInstance
{
public Monitor mMonitor;
public void Dispose()
{
mMonitor.Exit();
}
}
Platform.BfpCritSect* mCritSect;
public this()
{
mCritSect = Platform.BfpCritSect_Create();
}
public ~this()
{
Platform.BfpCritSect_Release(mCritSect);
}
/// Acquires the monitor lock. Will block if another thread holds the lock.
///
/// Multiple calls to Enter can be issued, and an equivalent number of Exits
/// must be issued to allow another thread to enter.
public MonitorLockInstance Enter()
{
MonitorLockInstance monitorLockInstance;
monitorLockInstance.mMonitor = this;
Platform.BfpCritSect_Enter(mCritSect);
return monitorLockInstance;
}
/// Releases the monitor lock.
///
/// Other threads will be able to enter the monitor unless this thread has issued
/// multiple Enters which have not all be Exited.
public void Exit()
{
Platform.BfpCritSect_Leave(mCritSect);
}
/// Attempt to enter the monitor without waiting.
/// @return true if the monitor was entered
public bool TryEnter()
{
return Platform.BfpCritSect_TryEnter(mCritSect, 0);
}
/// Blocks up to a timeout, or if millisecondsTimeout is -1, will wait forever.
/// @return true if the monitor was entered
public bool TryEnter(int millisecondsTimeout)
{
return Platform.BfpCritSect_TryEnter(mCritSect, (int32)millisecondsTimeout);
}
private static int32 MillisecondsTimeoutFromTimeSpan(TimeSpan timeout)
{
int64 tm = int64(timeout.TotalMilliseconds);
Debug.Assert((uint64)tm <= Int32.MaxValue);
return int32(tm);
}
public bool TryEnter(TimeSpan timeout)
{
return TryEnter(MillisecondsTimeoutFromTimeSpan(timeout));
}
}
}

View file

@ -0,0 +1,10 @@
namespace System.Threading
{
class SemaphoreSlim
{
public void Release()
{
}
}
}

View file

@ -0,0 +1,26 @@
namespace System.Threading
{
struct SpinWait
{
internal const int YIELD_THRESHOLD = 10; // When to switch over to a true yield.
internal const int SLEEP_0_EVERY_HOW_MANY_TIMES = 5; // After how many yields should we Sleep(0)?
internal const int SLEEP_1_EVERY_HOW_MANY_TIMES = 20; // After how many yields should we Sleep(1)?
private int m_count;
public int Count
{
get { return m_count; }
}
public void SpinOnce() mut
{
//TODO: Implement
}
public void Reset() mut
{
m_count = 0;
}
}
}

View file

@ -0,0 +1,143 @@
// This file contains portions of code released by Microsoft under the MIT license as part
// of an open-sourcing initiative in 2014 of the C# core libraries.
// The original source was submitted to https://github.com/Microsoft/referencesource
using System.Runtime.CompilerServices;
using System.Collections.Generic;
using System.Diagnostics;
namespace System.Threading.Tasks
{
public class Task<TResult> : Task
{
internal TResult m_result; // The value itself, if set.
protected bool mHasCompleted;
protected int32 mRefCount = 1;
internal TResult ResultOnSuccess
{
get
{
//Contract.Assert(!IsWaitNotificationEnabledOrNotRanToCompletion, "Should only be used when the task completed successfully and there's no wait notification enabled");
return m_result;
}
}
public TResult Result
{
get { return IsWaitNotificationEnabledOrNotRanToCompletion ? GetResultCore(true) : m_result; }
}
public this(Func<Object, TResult> func, Object state, CancellationToken cancellationToken, TaskCreationOptions creationOptions)
: this(func, state, Task.InternalCurrentIfAttached(creationOptions), cancellationToken,
creationOptions, InternalTaskOptions.None, null)
{
//StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
//PossiblyCaptureContext(ref stackMark);
}
internal this(Func<TResult> valueSelector, Task parent, CancellationToken cancellationToken,
TaskCreationOptions creationOptions, InternalTaskOptions internalOptions, TaskScheduler scheduler) :
base(valueSelector, null, parent, cancellationToken, creationOptions, internalOptions, scheduler)
{
if ((internalOptions & InternalTaskOptions.SelfReplicating) != 0)
{
Runtime.FatalError();
}
}
internal this(Delegate valueSelector, Object state, Task parent, CancellationToken cancellationToken,
TaskCreationOptions creationOptions, InternalTaskOptions internalOptions, TaskScheduler scheduler) :
base(valueSelector, state, parent, cancellationToken, creationOptions, internalOptions, scheduler)
{
if ((internalOptions & InternalTaskOptions.SelfReplicating) != 0)
{
Runtime.FatalError();
}
}
public new TaskAwaiter<TResult> GetAwaiter()
{
return TaskAwaiter<TResult>(this);
}
public void Ref()
{
//Interlocked.Increment(ref mRefCount);
mRefCount++;
}
public void Deref()
{
//if (Interlocked.Decrement(ref mRefCount) == 1)
if (--mRefCount == 0)
delete this;
}
public void Dispose()
{
Deref();
}
// Implements Result. Result delegates to this method if the result isn't already available.
internal TResult GetResultCore(bool waitCompletionNotification)
{
// If the result has not been calculated yet, wait for it.
if (!IsCompleted) InternalWait(Timeout.Infinite, default(CancellationToken)); // won't throw if task faulted or canceled; that's handled below
// Notify the debugger of the wait completion if it's requested such a notification
//TODO: Implement
//if (waitCompletionNotification) NotifyDebuggerOfWaitCompletionIfNecessary();
// Throw an exception if appropriate.
//TODO: ? if (!IsRanToCompletion) ThrowIfExceptional(true);
// We shouldn't be here if the result has not been set.
//Contract.Assert(IsRanToCompletion, "Task<T>.Result getter: Expected result to have been set.");
return m_result;
}
List<Action<Task<TResult>>> mContinuations = new List<Action<Task<TResult>>>() ~ delete _;
public Task ContinueWith(Action<Task<TResult>> continuationAction)
{
bool callDirectly = false;
using (mMonitor.Enter())
{
if (!mHasCompleted)
mContinuations.Add(continuationAction);
else
callDirectly = true;
}
if (callDirectly)
{
// The task has already completed, call directly
Ref();
continuationAction(this);
Deref();
}
return null;
//TODO: Not correct implementation
//StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
//return ContinueWith(continuationAction, TaskScheduler.Current, default(CancellationToken), TaskContinuationOptions.None, ref stackMark);
}
public void Notify(bool allowDelete = true)
{
var continueList = scope List<Action<Task<TResult>>>(16);
using (mMonitor.Enter())
{
mHasCompleted = true;
for (var action in mContinuations)
continueList.Add(action);
}
Ref();
for (var action in continueList)
action(this);
Deref();
}
}
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,108 @@
// This file contains portions of code released by Microsoft under the MIT license as part
// of an open-sourcing initiative in 2014 of the C# core libraries.
// The original source was submitted to https://github.com/Microsoft/referencesource
namespace System.Threading.Tasks
{
abstract class TaskScheduler
{
private static readonly TaskScheduler s_defaultTaskScheduler = new ThreadPoolTaskScheduler() ~ delete _;
public static TaskScheduler Default
{
get
{
return s_defaultTaskScheduler;
}
}
public static TaskScheduler Current
{
get
{
TaskScheduler current = InternalCurrent;
return current ?? TaskScheduler.Default;
}
}
internal static TaskScheduler InternalCurrent
{
get
{
Task currentTask = Task.InternalCurrent;
return ( (currentTask != null)
&& ((currentTask.CreationOptions & TaskCreationOptions.HideScheduler) == 0)
) ? currentTask.ExecutingTaskScheduler : null;
}
}
protected internal abstract void QueueTask(Task task);
protected abstract bool TryExecuteTaskInline(Task task, bool taskWasPreviouslyQueued);
/// <summary>
/// Notifies the scheduler that a work item has made progress.
/// </summary>
internal virtual void NotifyWorkItemProgress()
{
}
internal bool TryRunInline(Task task, bool taskWasPreviouslyQueued)
{
TaskScheduler ets = task.ExecutingTaskScheduler;
// Delegate cross-scheduler inlining requests to target scheduler
if(ets != this && ets !=null) return ets.TryRunInline(task, taskWasPreviouslyQueued);
//StackGuard currentStackGuard;
if( (ets == null) ||
(task.m_action == null) ||
task.IsDelegateInvoked ||
task.IsCanceled
//|| (currentStackGuard = Task.CurrentStackGuard).TryBeginInliningScope() == false
)
{
return false;
}
// Task class will still call into TaskScheduler.TryRunInline rather than TryExecuteTaskInline() so that
// 1) we can adjust the return code from TryExecuteTaskInline in case a buggy custom scheduler lies to us
// 2) we maintain a mechanism for the TLS lookup optimization that we used to have for the ConcRT scheduler (will potentially introduce the same for TP)
bool bInlined = false;
//try
{
task.FireTaskScheduledIfNeeded(this);
bInlined = TryExecuteTaskInline(task, taskWasPreviouslyQueued);
}
/*finally
{
currentStackGuard.EndInliningScope();
}*/
// If the custom scheduler returned true, we should either have the TASK_STATE_DELEGATE_INVOKED or TASK_STATE_CANCELED bit set
// Otherwise the scheduler is buggy
/*if (bInlined && !(task.IsDelegateInvoked || task.IsCanceled))
{
throw new InvalidOperationException(Environment.GetResourceString("TaskScheduler_InconsistentStateAfterTryExecuteTaskInline"));
}*/
return bInlined;
}
internal void InternalQueueTask(Task task)
{
//task.FireTaskScheduledIfNeeded(this);
this.QueueTask(task);
}
protected internal virtual bool TryDequeue(Task task)
{
return false;
}
internal virtual bool RequiresAtomicStartTransition
{
get { return true; }
}
}
}

View file

@ -0,0 +1,107 @@
// This file contains portions of code released by Microsoft under the MIT license as part
// of an open-sourcing initiative in 2014 of the C# core libraries.
// The original source was submitted to https://github.com/Microsoft/referencesource
namespace System.Threading.Tasks
{
class ThreadPoolTaskScheduler : TaskScheduler
{
/// Constructs a new ThreadPool task scheduler object
internal this()
{
}
// static delegate for threads allocated to handle LongRunning tasks.
//private static readonly ParameterizedThreadStart s_longRunningThreadWork = new => LongRunningThreadWork;
private static void LongRunningThreadWork(Object obj)
{
//Contract.Requires(obj != null, "TaskScheduler.LongRunningThreadWork: obj is null");
Task t = obj as Task;
//Contract.Assert(t != null, "TaskScheduler.LongRunningThreadWork: t is null");
t.ExecuteEntry(false);
}
/// Schedules a task to the ThreadPool.
/// @param task The task to schedule.
protected internal override void QueueTask(Task task)
{
if ((task.Options & TaskCreationOptions.LongRunning) != 0)
{
// Run LongRunning tasks on their own dedicated thread.
Thread thread = new Thread(new => LongRunningThreadWork);
thread.IsBackground = true; // Keep this thread from blocking process shutdown
thread.Start(task);
}
else
{
// Normal handling for non-LongRunning tasks.
//bool forceToGlobalQueue = ((task.Options & TaskCreationOptions.PreferFairness) != 0);
ThreadPool.QueueUserWorkItem(task);
}
}
/// This internal function will do this:
/// (1) If the task had previously been queued, attempt to pop it and return false if that fails.
/// (2) Propagate the return value from Task.ExecuteEntry() back to the caller.
///
/// IMPORTANT NOTE: TryExecuteTaskInline will NOT throw task exceptions itself. Any wait code path using this function needs
/// to account for exceptions that need to be propagated, and throw themselves accordingly.
protected override bool TryExecuteTaskInline(Task task, bool taskWasPreviouslyQueued)
{
// If the task was previously scheduled, and we can't pop it, then return false.
if (taskWasPreviouslyQueued && !ThreadPool.TryPopCustomWorkItem(task))
return false;
// Propagate the return value of Task.ExecuteEntry()
bool rval = false;
//try
{
rval = task.ExecuteEntry(false); // handles switching Task.Current etc.
}
/*finally
{
// Only call NWIP() if task was previously queued
if(taskWasPreviouslyQueued) NotifyWorkItemProgress();
}*/
return rval;
}
protected internal override bool TryDequeue(Task task)
{
// just delegate to TP
return ThreadPool.TryPopCustomWorkItem(task);
}
/*protected override IEnumerable<Task> GetScheduledTasks()
{
return FilterTasksFromWorkItems(ThreadPool.GetQueuedWorkItems());
}
private IEnumerable<Task> FilterTasksFromWorkItems(IEnumerable<IThreadPoolWorkItem> tpwItems)
{
for (IThreadPoolWorkItem tpwi in tpwItems)
{
if (tpwi is Task)
{
yield return (Task)tpwi;
}
}
}*/
/// Notifies the scheduler that work is progressing (no-op).
internal override void NotifyWorkItemProgress()
{
//ThreadPool.NotifyWorkItemProgress();
}
/// This is the only scheduler that returns false for this property, indicating that the task entry codepath is unsafe (CAS free)
/// since we know that the underlying scheduler already takes care of atomic transitions from queued to non-queued.
internal override bool RequiresAtomicStartTransition
{
get { return false; }
}
}
}

View file

@ -0,0 +1,364 @@
namespace System.Threading
{
using System;
using System.Diagnostics;
internal delegate Object InternalCrossContextDelegate(Object[] args);
public delegate void ThreadStart();
public delegate void ParameterizedThreadStart(Object obj);
public sealed class Thread
{
private int mInternalThread;
private int32 mPriority;
public int32 mMaxStackSize;
private String mName ~ delete _;
private Delegate mDelegate;
private Object mThreadStartArg;
bool mAutoDelete;
public static Thread sMainThread = new Thread() ~ delete _;
[StaticInitPriority(101)]
struct RuntimeThreadInit
{
static Object Thread_Alloc()
{
return Thread.[Friend]CreateEmptyThread();
}
static Object Thread_GetMainThread()
{
return Thread.[Friend]sMainThread;
}
static void* Thread_GetInternalThread(Object thread)
{
return (void*)((Thread)thread).[Friend]mInternalThread;
}
static void Thread_SetInternalThread(Object thread, void* internalThread)
{
((Thread)thread).[Friend]mInternalThread = (int)internalThread;
}
static bool Thread_IsAutoDelete(Object thread)
{
return ((Thread)thread).[Friend]mAutoDelete;
}
static void Thread_AutoDelete(Object thread)
{
delete thread;
}
static int32 Thread_GetMaxStackSize(Object thread)
{
return ((Thread)thread).mMaxStackSize;
}
static void Thread_StartProc(Object threadObj)
{
Thread thread = (Thread)threadObj;
if (thread.mName != null)
thread.InformThreadNameChange(thread.mName);
int32 stackStart = 0;
thread.SetStackStart((void*)&stackStart);
if (thread.mDelegate is ThreadStart)
{
((ThreadStart)thread.mDelegate)();
}
else
{
((ParameterizedThreadStart)thread.mDelegate)(thread.mThreadStartArg);
}
}
public static this()
{
var cb = ref Runtime.BfRtCallbacks.sCallbacks;
cb.[Friend]mThread_Alloc = => Thread_Alloc;
cb.[Friend]mThread_GetMainThread = => Thread_GetMainThread;
cb.[Friend]mThread_ThreadProc = => Thread_StartProc;
cb.[Friend]mThread_GetInternalThread = => Thread_GetInternalThread;
cb.[Friend]mThread_SetInternalThread = => Thread_SetInternalThread;
cb.[Friend]mThread_IsAutoDelete = => Thread_IsAutoDelete;
cb.[Friend]mThread_AutoDelete = => Thread_AutoDelete;
cb.[Friend]mThread_GetMaxStackSize = => Thread_GetMaxStackSize;
}
}
public this(ThreadStart start)
{
if (start == null)
{
Runtime.FatalError();
}
SetStart((Delegate)start, 0); //0 will setup Thread with default stackSize
}
public this(ThreadStart start, int32 maxStackSize)
{
if (start == null)
{
Runtime.FatalError();
}
if (0 > maxStackSize)
Runtime.FatalError();
SetStart((Delegate)start, maxStackSize);
}
public this(ParameterizedThreadStart start)
{
if (start == null)
{
Runtime.FatalError();
}
SetStart((Delegate)start, 0);
}
public this(ParameterizedThreadStart start, int32 maxStackSize)
{
if (start == null)
{
Runtime.FatalError();
}
if (0 > maxStackSize)
Runtime.FatalError();
SetStart((Delegate)start, maxStackSize);
}
static this()
{
#unwarn
RuntimeThreadInit runtimeThreadInitRef = ?;
sMainThread.ManualThreadInit();
}
static Thread CreateEmptyThread()
{
return new Thread();
}
public bool AutoDelete
{
set
{
// Changing AutoDelete from another thread while we are running is a race condition
Runtime.Assert((CurrentThread == this) || (!IsAlive));
mAutoDelete = value;
}
get
{
return mAutoDelete;
}
}
extern void ManualThreadInit();
extern void StartInternal();
extern void SetStackStart(void* ptr);
public void Start(bool autoDelete = true)
{
mAutoDelete = autoDelete;
StartInternal();
}
public void Start(Object parameter, bool autoDelete = true)
{
mAutoDelete = autoDelete;
if (mDelegate is ThreadStart)
{
Runtime.FatalError();
}
mThreadStartArg = parameter;
StartInternal();
}
#if BF_PLATFORM_WINDOWS
[CLink]
static extern int32 _tls_index;
#endif
public static int ModuleTLSIndex
{
get
{
#if BF_PLATFORM_WINDOWS
return _tls_index;
#else
return 0;
#endif
}
}
public void Suspend() { SuspendInternal(); }
private extern void SuspendInternal();
public void Resume() { ResumeInternal(); }
private extern void ResumeInternal();
public void Interrupt() { InterruptInternal(); }
private extern void InterruptInternal();
public ThreadPriority Priority
{
get { return (ThreadPriority)GetPriorityNative(); }
set { SetPriorityNative((int32)value); }
}
private extern int32 GetPriorityNative();
private extern void SetPriorityNative(int32 priority);
extern bool GetIsAlive();
public bool IsAlive
{
get
{
return GetIsAlive();
}
}
extern bool GetIsThreadPoolThread();
public bool IsThreadPoolThread
{
get
{
return GetIsThreadPoolThread();
}
}
private extern bool JoinInternal(int32 millisecondsTimeout);
public void Join()
{
JoinInternal(Timeout.Infinite);
}
public bool Join(int32 millisecondsTimeout)
{
return JoinInternal(millisecondsTimeout);
}
public bool Join(TimeSpan timeout)
{
int64 tm = (int64)timeout.TotalMilliseconds;
if (tm < -1 || tm > (int64)Int32.MaxValue)
Runtime.FatalError();
return Join((int32)tm);
}
private static extern void SleepInternal(int32 millisecondsTimeout);
public static void Sleep(int32 millisecondsTimeout)
{
SleepInternal(millisecondsTimeout);
}
public static void Sleep(TimeSpan timeout)
{
int64 tm = (int64)timeout.TotalMilliseconds;
if (tm < -1 || tm > (int64)Int32.MaxValue)
Runtime.FatalError();
Sleep((int32)tm);
}
private static extern void SpinWaitInternal(int32 iterations);
public static void SpinWait(int iterations)
{
SpinWaitInternal((int32)iterations);
}
private static extern bool YieldInternal();
public static bool Yield()
{
return YieldInternal();
}
public static Thread CurrentThread
{
get
{
return GetCurrentThreadNative();
}
}
extern int32 GetThreadId();
public int32 Id
{
get
{
return GetThreadId();
}
}
private static extern Thread GetCurrentThreadNative();
void SetStart(Delegate start, int32 maxStackSize)
{
mDelegate = start;
mMaxStackSize = maxStackSize;
}
public ~this()
{
// Make sure we're not deleting manually it mAutoDelete is set
Debug.Assert((!mAutoDelete) || (CurrentThread == this));
// Delegate to the unmanaged portion.
InternalFinalize();
// Thread owns delegate
delete mDelegate;
}
private extern void InternalFinalize();
public bool IsBackground
{
get { return IsBackgroundNative(); }
set { SetBackgroundNative(value); }
}
private extern bool IsBackgroundNative();
private extern void SetBackgroundNative(bool isBackground);
public extern void SetJoinOnDelete(bool joinOnDelete);
public ThreadState ThreadState
{
get { return (ThreadState)GetThreadStateNative(); }
}
private extern int32 GetThreadStateNative();
public void SetName(String name)
{
if (name == null)
{
delete mName;
mName = null;
}
else
{
String.NewOrSet!(mName, name);
}
if (mInternalThread != 0)
InformThreadNameChange(name);
}
public void GetName(String outName)
{
if (mName != null)
outName.Append(mName);
}
private extern void InformThreadNameChange(String name);
}
}

View file

@ -0,0 +1,182 @@
using System;
using System.Diagnostics;
using System.Collections.Generic;
//#define DISABLE_THREADS
namespace System.Threading
{
public delegate void WorkDelegate();
enum WorkEntry
{
case WorkDelegate(WorkDelegate callback);
case WorkItem(IThreadPoolWorkItem workItem);
}
struct ThreadStats
{
public volatile int32 mCount;
public volatile int32 mMax;
public volatile int32 mActive;
}
internal interface IThreadPoolWorkItem
{
void ExecuteWorkItem();
void MarkAborted();
}
public static class ThreadPool
{
static int32 sConcurrency = 8;
static bool sStarted = false;
static List<Thread> sThreads = new List<Thread>() ~ delete _;
static bool sShuttingDown;
static Monitor sMonitor = new Monitor() ~ delete _;
static Monitor sBindingMonitor = new Monitor() ~ delete _;
static WaitEvent sThreadWakeEvent = new WaitEvent() ~ delete _;
static WaitEvent sThreadClosedEvent = new WaitEvent() ~ delete _;
static ThreadStats sWorkerThreadStats;
static ThreadStats sIOThreadStats;
static List<WorkEntry> mWorkEntries = new List<WorkEntry>() ~ delete _;
static this()
{
//TODO: This is really bad, fix this pool!
sWorkerThreadStats.mMax = 4;
sIOThreadStats.mMax = 4;
}
static ~this()
{
sShuttingDown = true;
while (true)
{
sThreadWakeEvent.Set(true);
using (sMonitor.Enter())
if (sThreads.Count == 0)
break;
sThreadClosedEvent.WaitFor();
}
//Console.WriteLine("ThreadPool.~this done");
}
static void CheckSpawnWorkerThread()
{
using (sMonitor.Enter())
{
if ((sWorkerThreadStats.mActive == sWorkerThreadStats.mCount) && (sWorkerThreadStats.mCount < sWorkerThreadStats.mMax))
{
int threadId = sThreads.Count;
sWorkerThreadStats.mCount++;
sWorkerThreadStats.mActive++; // We know the thread will immediately become active
Thread thread = new Thread(new () => { WorkerProc(threadId); });
sThreads.Add(thread);
thread.Start(false);
}
}
}
static bool TryPopCustomWorkItem(WorkEntry workEntry)
{
using (sMonitor.Enter())
{
return mWorkEntries.Remove(workEntry);
}
}
public static bool TryPopCustomWorkItem(IThreadPoolWorkItem workItem)
{
return TryPopCustomWorkItem(.WorkItem(workItem));
}
public static bool QueueUserWorkItem(IThreadPoolWorkItem workItem)
{
using (sMonitor.Enter())
{
mWorkEntries.Add(.WorkItem(workItem));
CheckSpawnWorkerThread();
sThreadWakeEvent.Set();
}
return true;
}
public static bool QueueUserWorkItem(WorkDelegate waitCallback)
{
#if DISABLE_THREADS
waitCallback(userState);
return true;
#endif
Debug.AssertNotStack(waitCallback);
using (sMonitor.Enter())
{
mWorkEntries.Add(.WorkDelegate(waitCallback));
CheckSpawnWorkerThread();
sThreadWakeEvent.Set();
}
return true;
}
public static int32 sBindCount = 0;
public static int32 sReleaseBindCount = 0;
static void Start()
{
sStarted = true;
}
static void ThreadDone()
{
using (sMonitor.Enter())
{
Thread currentThread = Thread.CurrentThread;
sThreads.Remove(currentThread);
delete currentThread;
sThreadClosedEvent.Set();
}
}
static void WorkerProc(int id)
{
let threadName = scope String();
threadName.AppendF("ThreadPool Worker {0}", id);
Thread.CurrentThread.SetName(threadName);
while (true)
{
WorkEntry? workEntryOptional = null;
using (sMonitor.Enter())
{
if (mWorkEntries.Count != 0)
workEntryOptional = mWorkEntries.PopFront();
}
if (!workEntryOptional.HasValue)
{
sThreadWakeEvent.WaitFor();
if (sShuttingDown)
break;
continue;
}
var workEntry = workEntryOptional.Value;
switch (workEntry)
{
case .WorkDelegate(let callback):
callback();
delete callback;
case .WorkItem(let workItem):
workItem.ExecuteWorkItem();
}
}
ThreadDone();
}
}
}

View file

@ -0,0 +1,13 @@
using System.Threading;
namespace System.Threading
{
public enum ThreadPriority
{
Lowest = 0,
BelowNormal = 1,
Normal = 2,
AboveNormal = 3,
Highest = 4
}
}

View file

@ -0,0 +1,16 @@
namespace System.Threading
{
public enum ThreadState
{
Running = 0,
StopRequested = 1,
SuspendRequested = 2,
Background = 4,
Unstarted = 8,
Stopped = 16,
WaitSleepJoin = 32,
Suspended = 64,
AbortRequested = 128,
Aborted = 256
}
}

View file

@ -0,0 +1,13 @@
using System.Threading;
using System;
namespace System.Threading {
public static class Timeout
{
public const int32 Infinite = -1;
internal const uint32 UnsignedInfinite = (uint32)-1;
}
}

View file

@ -0,0 +1,58 @@
namespace System.Threading
{
static class Volatile
{
//static volatile int32 gAtomicIdx;
public static T Read<T>(ref T location)
{
T value = location;
Interlocked.Fence();
return value;
}
public static void Write<T>(ref T location, T value)
{
Interlocked.Fence();
location = value;
}
/*public static void MoveAtomic(void* dest, void* src, int size)
{
while (true)
{
int startAtomicIdx = gAtomicIdx;
Thread.MemoryBarrier();
Internal.MemCpy(dest, src, size);
Thread.MemoryBarrier();
int endAtomicIdx = Interlocked.Increment(ref gAtomicIdx);
if (endAtomicIdx == startAtomicIdx)
break;
}
}
public static T ReadAtomic<T>(ref T location)
{
if (sizeof(T) > sizeof(int))
{
if (sizeof(T) == sizeof(int64))
{
// Handle 64-bit values on 32-bit machines
var location;
int64 result = Interlocked.CompareExchange(ref *(int64*)&location, 0, 0);
return *(T*)&result;
}
var location;
T value = ?;
MoveAtomic(&value, &location, sizeof(T));
Thread.MemoryBarrier();
return value;
}
T value = location;
Thread.MemoryBarrier();
return value;
}*/
}
}