Welcome to mirror list, hosted at ThFree Co, Russian Federation.

Volatile.cs « Threading « System « src « System.Private.CoreLib « src - github.com/mono/corert.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 00543f82da29fe50029855fbcd50a97f59409b49 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

using System;
using System.Runtime.InteropServices;
using System.Runtime.CompilerServices;
using System.Runtime;

using Internal.Runtime.CompilerServices;

namespace System.Threading
{
    //
    // Methods for accessing memory with volatile semantics.
    //
    public static unsafe class Volatile
    {
        #region Boolean
        private struct VolatileBoolean { public volatile bool Value; }

        public static bool Read(ref bool location)
        {
            return Unsafe.As<bool, VolatileBoolean>(ref location).Value;
        }

        public static void Write(ref bool location, bool value)
        {
            Unsafe.As<bool, VolatileBoolean>(ref location).Value = value;
        }
        #endregion

        #region Byte
        private struct VolatileByte { public volatile byte Value; }

        public static byte Read(ref byte location)
        {
            return Unsafe.As<byte, VolatileByte>(ref location).Value;
        }

        public static void Write(ref byte location, byte value)
        {
            Unsafe.As<byte, VolatileByte>(ref location).Value = value;
        }
        #endregion

        #region Double
        public static double Read(ref double location)
        {
            long result = Read(ref Unsafe.As<double, long>(ref location));
            return *(double*)&result;
        }

        public static void Write(ref double location, double value)
        {
            Write(ref Unsafe.As<double, long>(ref location), *(long*)&value);
        }
        #endregion

        #region Int16
        private struct VolatileInt16 { public volatile short Value; }

        public static short Read(ref short location)
        {
            return Unsafe.As<short, VolatileInt16>(ref location).Value;
        }

        public static void Write(ref short location, short value)
        {
            Unsafe.As<short, VolatileInt16>(ref location).Value = value;
        }
        #endregion

        #region Int32
        private struct VolatileInt32 { public volatile int Value; }

        public static int Read(ref int location)
        {
            return Unsafe.As<int, VolatileInt32>(ref location).Value;
        }

        public static void Write(ref int location, int value)
        {
            Unsafe.As<int, VolatileInt32>(ref location).Value = value;
        }
        #endregion

        #region Int64
        public static long Read(ref long location)
        {
#if BIT64
            return (Int64)Unsafe.As<Int64, VolatileIntPtr>(ref location).Value;
#else
            return Interlocked.CompareExchange(ref location, 0, 0);
#endif
        }

        public static void Write(ref long location, long value)
        {
#if BIT64
            Unsafe.As<Int64, VolatileIntPtr>(ref location).Value = (IntPtr)value;
#else
            Interlocked.Exchange(ref location, value);
#endif
        }
        #endregion

        #region IntPtr
        private struct VolatileIntPtr { public volatile IntPtr Value; }

        public static IntPtr Read(ref IntPtr location)
        {
            return Unsafe.As<IntPtr, VolatileIntPtr>(ref location).Value;
        }

        public static void Write(ref IntPtr location, IntPtr value)
        {
            fixed (IntPtr* p = &location)
            {
                ((VolatileIntPtr*)p)->Value = value;
            }
        }
        #endregion

        #region SByte
        private struct VolatileSByte { public volatile sbyte Value; }

        [CLSCompliant(false)]
        public static sbyte Read(ref sbyte location)
        {
            return Unsafe.As<sbyte, VolatileSByte>(ref location).Value;
        }

        [CLSCompliant(false)]
        public static void Write(ref sbyte location, sbyte value)
        {
            Unsafe.As<sbyte, VolatileSByte>(ref location).Value = value;
        }
        #endregion

        #region Single
        private struct VolatileSingle { public volatile float Value; }

        public static float Read(ref float location)
        {
            return Unsafe.As<float, VolatileSingle>(ref location).Value;
        }

        public static void Write(ref float location, float value)
        {
            Unsafe.As<float, VolatileSingle>(ref location).Value = value;
        }
        #endregion

        #region UInt16
        private struct VolatileUInt16 { public volatile ushort Value; }

        [CLSCompliant(false)]
        public static ushort Read(ref ushort location)
        {
            return Unsafe.As<ushort, VolatileUInt16>(ref location).Value;
        }

        [CLSCompliant(false)]
        public static void Write(ref ushort location, ushort value)
        {
            Unsafe.As<ushort, VolatileUInt16>(ref location).Value = value;
        }
        #endregion

        #region UInt32
        private struct VolatileUInt32 { public volatile uint Value; }

        [CLSCompliant(false)]
        public static uint Read(ref uint location)
        {
            return Unsafe.As<uint, VolatileUInt32>(ref location).Value;
        }

        [CLSCompliant(false)]
        public static void Write(ref uint location, uint value)
        {
            Unsafe.As<uint, VolatileUInt32>(ref location).Value = value;
        }
        #endregion

        #region UInt64
        [CLSCompliant(false)]
        public static ulong Read(ref ulong location)
        {
            return (ulong)Read(ref Unsafe.As<ulong, long>(ref location));
        }

        [CLSCompliant(false)]
        public static void Write(ref ulong location, ulong value)
        {
            Write(ref Unsafe.As<ulong, long>(ref location), (long)value);
        }
        #endregion

        #region UIntPtr
        private struct VolatileUIntPtr { public volatile UIntPtr Value; }

        [CLSCompliant(false)]
        public static UIntPtr Read(ref UIntPtr location)
        {
            return Unsafe.As<UIntPtr, VolatileUIntPtr>(ref location).Value;
        }

        [CLSCompliant(false)]
        public static void Write(ref UIntPtr location, UIntPtr value)
        {
            Unsafe.As<UIntPtr, VolatileUIntPtr>(ref location).Value = value;
        }
        #endregion

        #region T
        private struct VolatileObject { public volatile object Value; }

        public static T Read<T>(ref T location) where T : class
        {
            return Unsafe.As<T>(Unsafe.As<T, VolatileObject>(ref location).Value);
        }

        public static void Write<T>(ref T location, T value) where T : class
        {
            Unsafe.As<T, VolatileObject>(ref location).Value = value;
        }
        #endregion
    }
}