44using System ;
55using System . Collections . Generic ;
66using System . Runtime . CompilerServices ;
7+ using System . Runtime . InteropServices ;
78using System . Threading ;
89using System . Threading . Tasks ;
910
@@ -18,6 +19,9 @@ internal static int Run()
1819
1920 ThreadStaticsTestWithTasks . Run ( ) ;
2021
22+ if ( ThreadStaticAlignmentTest . Run ( ) != Pass )
23+ return Fail ;
24+
2125 if ( ThreadTest . Run ( ) != Pass )
2226 return Fail ;
2327
@@ -187,6 +191,59 @@ public static void Run()
187191 }
188192}
189193
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+
190247class ThreadTest
191248{
192249 private static readonly List < Thread > s_startedThreads = new List < Thread > ( ) ;
0 commit comments