singrdk/base/Applications/Runtime/Full/System/Threading/Interlocked.cs

330 lines
10 KiB
C#

// ==++==
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// ==--==
namespace System.Threading
{
using System;
using System.Runtime.CompilerServices;
#if SINGULARITY_KERNEL
using Microsoft.Singularity.Memory;
#endif
#if ISA_ARM
using Microsoft.Singularity;
using Microsoft.Singularity.Isal;
#endif
//| <include path='docs/doc[@for="Interlocked"]/*' />
#if ISA_ARM
[AccessedByRuntime("Routines defined in interlocked.cpp")]
#endif
public sealed class Interlocked
{
private Interlocked() {
}
//| <include path='docs/doc[@for="Interlocked.Increment"]/*' />
#if ISA_IX
[Intrinsic]
#elif ISA_ARM
[AccessedByRuntime("defined in interlocked.cpp")]
[MethodImpl(MethodImplOptions.InternalCall)]
[StackBound(64)]
#endif
[NoHeapAllocation]
public static extern int Increment(ref int location);
//| <include path='docs/doc[@for="Interlocked.Decrement"]/*' />
#if ISA_IX
[Intrinsic]
#elif ISA_ARM
[AccessedByRuntime("defined in interlocked.cpp")]
[MethodImpl(MethodImplOptions.InternalCall)]
[StackBound(64)]
#endif
[NoHeapAllocation]
public static extern int Decrement(ref int location);
//| <include path='docs/doc[@for="Interlocked.Increment1"]/*' />
[NoHeapAllocation]
public static long Increment(ref long location) {
long value = location;
while (CompareExchange(ref location, value + 1, value) != value) {
value = location;
}
return value+1;
}
//| <include path='docs/doc[@for="Interlocked.Decrement1"]/*' />
[NoHeapAllocation]
public static long Decrement(ref long location) {
long value = location;
while (CompareExchange(ref location, value - 1, value) != value) {
value = location;
}
return value-1;
}
//| <include path='docs/doc[@for="Interlocked.Increment1"]/*' />
[CLSCompliant(false)]
[NoHeapAllocation]
public static ulong Increment(ref ulong location) {
ulong value = location;
while (CompareExchange(ref location, value + 1, value) != value) {
value = location;
}
return value+1;
}
//| <include path='docs/doc[@for="Interlocked.Decrement1"]/*' />
[CLSCompliant(false)]
[NoHeapAllocation]
public static ulong Decrement(ref ulong location) {
ulong value = location;
while (CompareExchange(ref location, value - 1, value) != value) {
value = location;
}
return value-1;
}
[CLSCompliant(false)]
[NoHeapAllocation]
public static ulong Add(ref ulong location, ulong value) {
ulong tmp = location;
ulong newValue = tmp + value;
while (CompareExchange(ref location, newValue, tmp) != tmp) {
tmp = location;
newValue = tmp + value;
}
return newValue;
}
[CLSCompliant(false)]
[NoHeapAllocation]
public static ulong Subtract(ref ulong location, ulong value) {
ulong tmp = location;
ulong newValue = tmp - value;
while (CompareExchange(ref location, newValue, tmp) != tmp) {
tmp = location;
newValue = tmp - value;
}
return newValue;
}
//| <include path='docs/doc[@for="Interlocked.Exchange"]/*' />
#if ISA_IX
[Intrinsic]
#elif ISA_ARM
[AccessedByRuntime("defined in interlocked.cpp")]
[MethodImpl(MethodImplOptions.InternalCall)]
[StackBound(64)]
#endif
[NoHeapAllocation]
public static extern int Exchange(ref int location1, int value);
//| <include path='docs/doc[@for="Interlocked.CompareExchange"]/*' />
#if ISA_IX
[Intrinsic]
#elif ISA_ARM
[AccessedByRuntime("defined in interlocked.cpp")]
[MethodImpl(MethodImplOptions.InternalCall)]
[StackBound(64)]
#endif
[NoHeapAllocation]
public static extern int CompareExchange(ref int location1, int value, int comparand);
//| <include path='docs/doc[@for="Interlocked.Exchange1"]/*' />
#if ISA_IX
[Intrinsic]
#elif ISA_ARM
[AccessedByRuntime("defined in interlocked.cpp")]
[MethodImpl(MethodImplOptions.InternalCall)]
[StackBound(64)]
#endif
[NoHeapAllocation]
public static extern float Exchange(ref float location1, float value);
//| <include path='docs/doc[@for="Interlocked.CompareExchange1"]/*' />
#if ISA_IX
[Intrinsic]
#elif ISA_ARM
[AccessedByRuntime("defined in interlocked.cpp")]
[MethodImpl(MethodImplOptions.InternalCall)]
[StackBound(64)]
#endif
[NoHeapAllocation]
public static extern float CompareExchange(ref float location1, float value, float comparand);
// Added for thread initialization.
#if ISA_IX
[Intrinsic]
#elif ISA_ARM
[AccessedByRuntime("defined in interlocked.cpp")]
[MethodImpl(MethodImplOptions.InternalCall)]
[StackBound(64)]
#endif
[NoHeapAllocation]
public static extern ThreadState CompareExchange(ref ThreadState location1, ThreadState value, ThreadState comparand);
#if ISA_IX
[Intrinsic]
#elif ISA_ARM
[AccessedByRuntime("defined in interlocked.cpp")]
[MethodImpl(MethodImplOptions.InternalCall)]
[StackBound(64)]
#endif
[NoHeapAllocation]
public static extern long CompareExchange(ref long location1, long value, long comparand);
[CLSCompliant(false)]
#if ISA_IX
[Intrinsic]
#elif ISA_ARM
[AccessedByRuntime("defined in interlocked.cpp")]
[MethodImpl(MethodImplOptions.InternalCall)]
[StackBound(64)]
#endif
[NoHeapAllocation]
public static extern ulong CompareExchange(ref ulong location1, ulong value, ulong comparand);
//| <include path='docs/doc[@for="Interlocked.Exchange2"]/*' />
#if ISA_IX
[Intrinsic]
#elif ISA_ARM
[AccessedByRuntime("defined in interlocked.cpp")]
[MethodImpl(MethodImplOptions.InternalCall)]
[StackBound(64)]
#endif
[NoHeapAllocation]
public static extern Object Exchange(ref Object location1, Object value);
//| <include path='docs/doc[@for="Interlocked.CompareExchange2"]/*' />
#if ISA_IX
[Intrinsic]
#elif ISA_ARM
[AccessedByRuntime("defined in interlocked.cpp")]
[MethodImpl(MethodImplOptions.InternalCall)]
[StackBound(64)]
#endif
[NoHeapAllocation]
public static extern Object CompareExchange(ref Object location1, Object value, Object comparand);
[CLSCompliant(false)]
#if ISA_IX
[Intrinsic]
#elif ISA_ARM
[AccessedByRuntime("defined in interlocked.cpp")]
[MethodImpl(MethodImplOptions.InternalCall)]
[StackBound(64)]
#endif
[NoHeapAllocation]
public static extern uint Exchange(ref uint location1, uint value);
[CLSCompliant(false)]
#if ISA_IX
[Intrinsic]
#elif ISA_ARM
[AccessedByRuntime("defined in interlocked.cpp")]
[MethodImpl(MethodImplOptions.InternalCall)]
[StackBound(64)]
#endif
[NoHeapAllocation]
public static extern uint CompareExchange(ref uint location1, uint value, uint comparand);
[CLSCompliant(false)]
#if ISA_IX
[Intrinsic]
#elif ISA_ARM
// [AccessedByRuntime("defined in interlocked.cpp")]
[MethodImpl(MethodImplOptions.InternalCall)]
[StackBound(64)]
#endif
[NoHeapAllocation]
public static extern UIntPtr Exchange(ref UIntPtr location1, UIntPtr value);
[CLSCompliant(false)]
#if ISA_IX
[Intrinsic]
#elif ISA_ARM
// [AccessedByRuntime("defined in interlocked.cpp")]
[MethodImpl(MethodImplOptions.InternalCall)]
[StackBound(64)]
#endif
[NoHeapAllocation]
public static extern UIntPtr CompareExchange(ref UIntPtr location1, UIntPtr value, UIntPtr comparand);
[CLSCompliant(false)]
#if ISA_IX
[Intrinsic]
#elif ISA_ARM
[AccessedByRuntime("defined in interlocked.cpp")]
[MethodImpl(MethodImplOptions.InternalCall)]
[StackBound(64)]
#endif
[NoHeapAllocation]
public static extern unsafe UIntPtr Exchange(UIntPtr * location1, UIntPtr value);
[CLSCompliant(false)]
#if ISA_IX
[Intrinsic]
#elif ISA_ARM
[AccessedByRuntime("defined in interlocked.cpp")]
[MethodImpl(MethodImplOptions.InternalCall)]
[StackBound(64)]
#endif
[NoHeapAllocation]
public static extern unsafe UIntPtr CompareExchange(UIntPtr * location1, UIntPtr value, UIntPtr comparand);
[CLSCompliant(false)]
#if ISA_IX
[Intrinsic]
#elif ISA_ARM
[AccessedByRuntime("defined in interlocked.cpp")]
[MethodImpl(MethodImplOptions.InternalCall)]
[StackBound(64)]
#endif
[NoHeapAllocation]
public static extern unsafe void * CompareExchange(ref void * location1, void * value, void * comparand);
#if SINGULARITY_KERNEL
[CLSCompliant(false)]
#if ISA_IX
[Intrinsic]
#elif ISA_ARM
[AccessedByRuntime("defined in interlocked.cpp")]
[MethodImpl(MethodImplOptions.InternalCall)]
[StackBound(64)]
#endif
[NoHeapAllocation]
internal static extern unsafe HandleTable.HandlePage * CompareExchange(
ref HandleTable.HandlePage * location1,
HandleTable.HandlePage * value,
HandleTable.HandlePage * comparand);
[CLSCompliant(false)]
#if ISA_IX
[Intrinsic]
#elif ISA_ARM
[AccessedByRuntime("defined in interlocked.cpp")]
[MethodImpl(MethodImplOptions.InternalCall)]
[StackBound(64)]
#endif
[NoHeapAllocation]
internal static extern unsafe HandleTable.HandleEntry * CompareExchange(
ref HandleTable.HandleEntry * location1,
HandleTable.HandleEntry * value,
HandleTable.HandleEntry * comparand);
#endif
}
}