4
4
using System ;
5
5
using System . Collections . Generic ;
6
6
using System . Runtime . CompilerServices ;
7
+ using System . Runtime . InteropServices ;
7
8
using System . Threading ;
8
9
using System . Threading . Tasks ;
9
10
@@ -18,6 +19,9 @@ internal static int Run()
18
19
19
20
ThreadStaticsTestWithTasks . Run ( ) ;
20
21
22
+ if ( ThreadStaticAlignmentTest . Run ( ) != Pass )
23
+ return Fail ;
24
+
21
25
if ( ThreadTest . Run ( ) != Pass )
22
26
return Fail ;
23
27
@@ -187,6 +191,59 @@ public static void Run()
187
191
}
188
192
}
189
193
194
+ class ThreadStaticAlignmentTest
195
+ {
196
+ public static int Run ( )
197
+ {
198
+ // Check for 8-byte alignment requirement
199
+ if ( RuntimeInformation . ProcessArchitecture is Architecture . Arm or Architecture . Wasm )
200
+ {
201
+ // Assume that these are allocated sequentially, use a padding object of size 12 (mod 8 is not 0)
202
+ // to move the alignment of the second AddressOfReturnArea in case the first is coincidentally aligned 8.
203
+ var ts1Addr = ThreadStaticAlignCheck1 . returnArea . AddressOfReturnArea ( ) ;
204
+ var p = new Padder ( ) ;
205
+ var ts2Addr = ThreadStaticAlignCheck2 . returnArea . AddressOfReturnArea ( ) ;
206
+
207
+ if ( ( ( nint ) ts1Addr ) % 8 != 0 )
208
+ return BasicThreading . Fail ;
209
+ if ( ( ( nint ) ts2Addr ) % 8 != 0 )
210
+ return BasicThreading . Fail ;
211
+ }
212
+
213
+ return BasicThreading . Pass ;
214
+ }
215
+
216
+ [ InlineArray ( 3 ) ]
217
+ private struct ReturnArea
218
+ {
219
+ private ulong buffer ;
220
+
221
+ internal unsafe nint AddressOfReturnArea ( )
222
+ {
223
+ return ( nint ) Unsafe . AsPointer ( ref buffer ) ;
224
+ }
225
+ }
226
+
227
+ private class ThreadStaticAlignCheck1
228
+ {
229
+ [ ThreadStatic ]
230
+ [ FixedAddressValueType ]
231
+ internal static ReturnArea returnArea = default ;
232
+ }
233
+
234
+ private class Padder
235
+ {
236
+ private object o1 ;
237
+ }
238
+
239
+ private class ThreadStaticAlignCheck2
240
+ {
241
+ [ ThreadStatic ]
242
+ [ FixedAddressValueType ]
243
+ internal static ReturnArea returnArea = default ;
244
+ }
245
+ }
246
+
190
247
class ThreadTest
191
248
{
192
249
private static readonly List < Thread > s_startedThreads = new List < Thread > ( ) ;
0 commit comments