diff --git a/NuGet.config b/NuGet.config index 3b939ea5b91ab9..e4806514865c0f 100644 --- a/NuGet.config +++ b/NuGet.config @@ -9,8 +9,10 @@ + + diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index b9570bb70fbd77..fba68f6cdfd5ee 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -12,37 +12,37 @@ https://github.com/dotnet/wcf 7f504aabb1988e9a093c1e74d8040bd52feb2f01 - + https://github.com/dotnet/llvm-project - 615d41dd7f8de828f0bd0b6f65f7de4864ae8d12 + daa0939940ad46ff17734d8eb0b795d711d3ca69 - + https://github.com/dotnet/llvm-project - 615d41dd7f8de828f0bd0b6f65f7de4864ae8d12 + daa0939940ad46ff17734d8eb0b795d711d3ca69 - + https://github.com/dotnet/llvm-project - 615d41dd7f8de828f0bd0b6f65f7de4864ae8d12 + daa0939940ad46ff17734d8eb0b795d711d3ca69 - + https://github.com/dotnet/llvm-project - 615d41dd7f8de828f0bd0b6f65f7de4864ae8d12 + daa0939940ad46ff17734d8eb0b795d711d3ca69 - + https://github.com/dotnet/llvm-project - 615d41dd7f8de828f0bd0b6f65f7de4864ae8d12 + daa0939940ad46ff17734d8eb0b795d711d3ca69 - + https://github.com/dotnet/llvm-project - 615d41dd7f8de828f0bd0b6f65f7de4864ae8d12 + daa0939940ad46ff17734d8eb0b795d711d3ca69 - + https://github.com/dotnet/llvm-project - 615d41dd7f8de828f0bd0b6f65f7de4864ae8d12 + daa0939940ad46ff17734d8eb0b795d711d3ca69 - + https://github.com/dotnet/llvm-project - 615d41dd7f8de828f0bd0b6f65f7de4864ae8d12 + daa0939940ad46ff17734d8eb0b795d711d3ca69 https://github.com/dotnet/command-line-api @@ -64,18 +64,18 @@ bbb895e8e9f2d566eae04f09977b8c5f895057d2 - + https://github.com/dotnet/emsdk - 78f6f07d38e8755e573039a8aa04e131d3e59b76 + b567cdb6b8b461de79f2a2536a22ca3a67f2f33e - + https://github.com/dotnet/emsdk - 78f6f07d38e8755e573039a8aa04e131d3e59b76 + b567cdb6b8b461de79f2a2536a22ca3a67f2f33e - + https://github.com/dotnet/emsdk - 78f6f07d38e8755e573039a8aa04e131d3e59b76 + b567cdb6b8b461de79f2a2536a22ca3a67f2f33e @@ -226,61 +226,61 @@ https://github.com/dotnet/runtime-assets c9371153c0f06168c3344b806331a29389d1171e - + https://github.com/dotnet/llvm-project - 615d41dd7f8de828f0bd0b6f65f7de4864ae8d12 + daa0939940ad46ff17734d8eb0b795d711d3ca69 - + https://github.com/dotnet/llvm-project - 615d41dd7f8de828f0bd0b6f65f7de4864ae8d12 + daa0939940ad46ff17734d8eb0b795d711d3ca69 - + https://github.com/dotnet/llvm-project - 615d41dd7f8de828f0bd0b6f65f7de4864ae8d12 + daa0939940ad46ff17734d8eb0b795d711d3ca69 - + https://github.com/dotnet/llvm-project - 615d41dd7f8de828f0bd0b6f65f7de4864ae8d12 + daa0939940ad46ff17734d8eb0b795d711d3ca69 - + https://github.com/dotnet/llvm-project - 615d41dd7f8de828f0bd0b6f65f7de4864ae8d12 + daa0939940ad46ff17734d8eb0b795d711d3ca69 - + https://github.com/dotnet/llvm-project - 615d41dd7f8de828f0bd0b6f65f7de4864ae8d12 + daa0939940ad46ff17734d8eb0b795d711d3ca69 - + https://github.com/dotnet/llvm-project - 615d41dd7f8de828f0bd0b6f65f7de4864ae8d12 + daa0939940ad46ff17734d8eb0b795d711d3ca69 - + https://github.com/dotnet/llvm-project - 615d41dd7f8de828f0bd0b6f65f7de4864ae8d12 + daa0939940ad46ff17734d8eb0b795d711d3ca69 - + https://github.com/dotnet/llvm-project - 615d41dd7f8de828f0bd0b6f65f7de4864ae8d12 + daa0939940ad46ff17734d8eb0b795d711d3ca69 - + https://github.com/dotnet/llvm-project - 615d41dd7f8de828f0bd0b6f65f7de4864ae8d12 + daa0939940ad46ff17734d8eb0b795d711d3ca69 - + https://github.com/dotnet/llvm-project - 615d41dd7f8de828f0bd0b6f65f7de4864ae8d12 + daa0939940ad46ff17734d8eb0b795d711d3ca69 - + https://github.com/dotnet/llvm-project - 615d41dd7f8de828f0bd0b6f65f7de4864ae8d12 + daa0939940ad46ff17734d8eb0b795d711d3ca69 - + https://github.com/dotnet/llvm-project - 615d41dd7f8de828f0bd0b6f65f7de4864ae8d12 + daa0939940ad46ff17734d8eb0b795d711d3ca69 - + https://github.com/dotnet/llvm-project - 615d41dd7f8de828f0bd0b6f65f7de4864ae8d12 + daa0939940ad46ff17734d8eb0b795d711d3ca69 https://github.com/dotnet/runtime diff --git a/eng/Versions.props b/eng/Versions.props index 65b6d9e27ea9d1..9d543eb0909dbd 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -1,11 +1,11 @@ - 9.0.5 + 9.0.7 9 0 - 5 + 7 9.0.100 8.0.$([MSBuild]::Add($(PatchVersion),11)) 7.0.20 @@ -225,39 +225,39 @@ 2.4.8 9.0.0-alpha.1.24167.3 - 19.1.0-alpha.1.25209.2 - 19.1.0-alpha.1.25209.2 - 19.1.0-alpha.1.25209.2 - 19.1.0-alpha.1.25209.2 - 19.1.0-alpha.1.25209.2 - 19.1.0-alpha.1.25209.2 - 19.1.0-alpha.1.25209.2 - 19.1.0-alpha.1.25209.2 - 19.1.0-alpha.1.25209.2 - 19.1.0-alpha.1.25209.2 - 19.1.0-alpha.1.25209.2 - 19.1.0-alpha.1.25209.2 - 19.1.0-alpha.1.25209.2 - 19.1.0-alpha.1.25209.2 + 19.1.0-alpha.1.25266.1 + 19.1.0-alpha.1.25266.1 + 19.1.0-alpha.1.25266.1 + 19.1.0-alpha.1.25266.1 + 19.1.0-alpha.1.25266.1 + 19.1.0-alpha.1.25266.1 + 19.1.0-alpha.1.25266.1 + 19.1.0-alpha.1.25266.1 + 19.1.0-alpha.1.25266.1 + 19.1.0-alpha.1.25266.1 + 19.1.0-alpha.1.25266.1 + 19.1.0-alpha.1.25266.1 + 19.1.0-alpha.1.25266.1 + 19.1.0-alpha.1.25266.1 - 9.0.5-servicing.25212.1 - 9.0.5 + 9.0.7-servicing.25304.2 + 9.0.7 $(MicrosoftNETWorkloadEmscriptenCurrentManifest90100Version) 1.1.87-gba258badda 1.0.0-v3.14.0.5722 - 19.1.0-alpha.1.25209.2 - 19.1.0-alpha.1.25209.2 - 19.1.0-alpha.1.25209.2 - 19.1.0-alpha.1.25209.2 - 19.1.0-alpha.1.25209.2 - 19.1.0-alpha.1.25209.2 - 19.1.0-alpha.1.25209.2 - 19.1.0-alpha.1.25209.2 + 19.1.0-alpha.1.25266.1 + 19.1.0-alpha.1.25266.1 + 19.1.0-alpha.1.25266.1 + 19.1.0-alpha.1.25266.1 + 19.1.0-alpha.1.25266.1 + 19.1.0-alpha.1.25266.1 + 19.1.0-alpha.1.25266.1 + 19.1.0-alpha.1.25266.1 3.1.7 1.0.406601 diff --git a/eng/pipelines/common/macos-sign-with-entitlements.yml b/eng/pipelines/common/macos-sign-with-entitlements.yml index 72a03b90f340d6..6a20a31481eb9d 100644 --- a/eng/pipelines/common/macos-sign-with-entitlements.yml +++ b/eng/pipelines/common/macos-sign-with-entitlements.yml @@ -30,12 +30,13 @@ steps: - task: EsrpCodeSigning@5 displayName: 'ESRP CodeSigning' inputs: - ConnectedServiceName: 'DotNet-Engineering-Services_KeyVault' - AppRegistrationClientId: '28ec6507-2167-4eaa-a294-34408cf5dd0e' - AppRegistrationTenantId: '72f988bf-86f1-41af-91ab-2d7cd011db47' - AuthAKVName: 'EngKeyVault' - AuthCertName: 'DotNetCore-ESRP-AuthCert' - AuthSignCertName: 'DotNetCore-ESRP-AuthSignCert' + ConnectedServiceName: 'DotNetBuildESRP' + UseMSIAuthentication: true + EsrpClientId: '28ec6507-2167-4eaa-a294-34408cf5dd0e' + AppRegistrationClientId: '0ecbcdb7-8451-4cbe-940a-4ed97b08b955' + AppRegistrationTenantId: '975f013f-7f24-47e8-a7d3-abc4752bf346' + AuthAKVName: 'DotNetEngKeyVault' + AuthSignCertName: 'DotNet-ESRP-AuthSignCert' FolderPath: '$(Build.ArtifactStagingDirectory)/' Pattern: 'mac_entitled_to_sign.zip' UseMinimatch: true diff --git a/src/libraries/System.Threading.Tasks.Parallel/tests/ParallelForEachAsyncTests.cs b/src/libraries/System.Threading.Tasks.Parallel/tests/ParallelForEachAsyncTests.cs index 77c16ddd72c928..093d35bb55e0e9 100644 --- a/src/libraries/System.Threading.Tasks.Parallel/tests/ParallelForEachAsyncTests.cs +++ b/src/libraries/System.Threading.Tasks.Parallel/tests/ParallelForEachAsyncTests.cs @@ -1393,6 +1393,32 @@ static async IAsyncEnumerable Iterate() await t; } + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsThreadingSupported))] + public async Task GitHubIssue_114262_Async() + { + var options = new ParallelOptions + { + MaxDegreeOfParallelism = 5, + CancellationToken = new CancellationTokenSource().Token + }; + + var range = Enumerable.Range(1, 1000); + + for (int i = 0; i < 100; i++) + { + await Parallel.ForEachAsync(range, options, async (data, token) => + { + for (int i = 0; i < 5; i++) + { + await Task.Yield(); + var buffer = new byte[10_000]; + await Task.Run(() => {var _ = buffer[0];} ); + await Task.Yield(); + } + }); + } + } + private static async IAsyncEnumerable EnumerableRangeAsync(int start, int count, bool yield = true) { for (int i = start; i < start + count; i++) diff --git a/src/mono/mono/utils/atomic.h b/src/mono/mono/utils/atomic.h index 3f0a01e6beb428..9d4459d932fb1a 100644 --- a/src/mono/mono/utils/atomic.h +++ b/src/mono/mono/utils/atomic.h @@ -95,11 +95,25 @@ Apple targets have historically being problematic, xcode 4.6 would miscompile th #include +#if defined(HOST_ARM64) +// C11 atomics on ARM64 offers a weaker version of sequential consistent, not expected by mono atomics operations. +// C11 seq_cst on ARM64 corresponds to acquire/release semantics, but mono expects these functions to emit a full memory +// barrier preventing any kind of reordering around the atomic operation. GCC atomics on ARM64 had similar limitations, +// see comments on GCC atomics below and mono injected full memory barriers around GCC atomic functions to mitigate this. +// Since mono GCC atomics implementation ended up even stronger (full memory barrier before/after), the C11 atomics +// implementation is still a little weaker, but should correspond to the exact same semantics as implemented by JIT +// compiler for sequential consistent atomic load/store/add/exchange/cas op codes on ARM64. +#define C11_MEMORY_ORDER_SEQ_CST() atomic_thread_fence (memory_order_seq_cst) +#else +#define C11_MEMORY_ORDER_SEQ_CST() +#endif + static inline guint8 mono_atomic_cas_u8 (volatile guint8 *dest, guint8 exch, guint8 comp) { g_static_assert (sizeof (atomic_char) == sizeof (*dest) && ATOMIC_CHAR_LOCK_FREE == 2); (void)atomic_compare_exchange_strong ((volatile atomic_char *)dest, (char*)&comp, exch); + C11_MEMORY_ORDER_SEQ_CST (); return comp; } @@ -108,6 +122,7 @@ mono_atomic_cas_u16 (volatile guint16 *dest, guint16 exch, guint16 comp) { g_static_assert (sizeof (atomic_short) == sizeof (*dest) && ATOMIC_SHORT_LOCK_FREE == 2); (void)atomic_compare_exchange_strong ((volatile atomic_short *)dest, (short*)&comp, exch); + C11_MEMORY_ORDER_SEQ_CST (); return comp; } @@ -116,6 +131,7 @@ mono_atomic_cas_i32 (volatile gint32 *dest, gint32 exch, gint32 comp) { g_static_assert (sizeof (atomic_int) == sizeof (*dest) && ATOMIC_INT_LOCK_FREE == 2); (void)atomic_compare_exchange_strong ((volatile atomic_int *)dest, &comp, exch); + C11_MEMORY_ORDER_SEQ_CST (); return comp; } @@ -125,14 +141,14 @@ mono_atomic_cas_i64 (volatile gint64 *dest, gint64 exch, gint64 comp) #if SIZEOF_LONG == 8 g_static_assert (sizeof (atomic_long) == sizeof (*dest) && ATOMIC_LONG_LOCK_FREE == 2); (void)atomic_compare_exchange_strong ((volatile atomic_long *)dest, (long*)&comp, exch); - return comp; #elif SIZEOF_LONG_LONG == 8 g_static_assert (sizeof (atomic_llong) == sizeof (*dest) && ATOMIC_LLONG_LOCK_FREE == 2); (void)atomic_compare_exchange_strong ((volatile atomic_llong *)dest, (long long*)&comp, exch); - return comp; #else #error "gint64 not same size atomic_llong or atomic_long, don't define MONO_USE_STDATOMIC" #endif + C11_MEMORY_ORDER_SEQ_CST (); + return comp; } static inline gpointer @@ -140,6 +156,7 @@ mono_atomic_cas_ptr (volatile gpointer *dest, gpointer exch, gpointer comp) { g_static_assert(ATOMIC_POINTER_LOCK_FREE == 2); (void)atomic_compare_exchange_strong ((volatile _Atomic(gpointer) *)dest, &comp, exch); + C11_MEMORY_ORDER_SEQ_CST (); return comp; } @@ -191,21 +208,27 @@ static inline guint8 mono_atomic_xchg_u8 (volatile guint8 *dest, guint8 exch) { g_static_assert (sizeof (atomic_char) == sizeof (*dest) && ATOMIC_CHAR_LOCK_FREE == 2); - return atomic_exchange ((volatile atomic_char *)dest, exch); + guint8 old = atomic_exchange ((volatile atomic_char *)dest, exch); + C11_MEMORY_ORDER_SEQ_CST (); + return old; } static inline guint16 mono_atomic_xchg_u16 (volatile guint16 *dest, guint16 exch) { g_static_assert (sizeof (atomic_short) == sizeof (*dest) && ATOMIC_SHORT_LOCK_FREE == 2); - return atomic_exchange ((volatile atomic_short *)dest, exch); + guint16 old = atomic_exchange ((volatile atomic_short *)dest, exch); + C11_MEMORY_ORDER_SEQ_CST (); + return old; } static inline gint32 mono_atomic_xchg_i32 (volatile gint32 *dest, gint32 exch) { g_static_assert (sizeof (atomic_int) == sizeof (*dest) && ATOMIC_INT_LOCK_FREE == 2); - return atomic_exchange ((volatile atomic_int *)dest, exch); + gint32 old = atomic_exchange ((volatile atomic_int *)dest, exch); + C11_MEMORY_ORDER_SEQ_CST (); + return old; } static inline gint64 @@ -213,27 +236,33 @@ mono_atomic_xchg_i64 (volatile gint64 *dest, gint64 exch) { #if SIZEOF_LONG == 8 g_static_assert (sizeof (atomic_long) == sizeof (*dest) && ATOMIC_LONG_LOCK_FREE == 2); - return atomic_exchange ((volatile atomic_long *)dest, exch); + gint64 old = atomic_exchange ((volatile atomic_long *)dest, exch); #elif SIZEOF_LONG_LONG == 8 g_static_assert (sizeof (atomic_llong) == sizeof (*dest) && ATOMIC_LLONG_LOCK_FREE == 2); - return atomic_exchange ((volatile atomic_llong *)dest, exch); + gint64 old = atomic_exchange ((volatile atomic_llong *)dest, exch); #else #error "gint64 not same size atomic_llong or atomic_long, don't define MONO_USE_STDATOMIC" #endif + C11_MEMORY_ORDER_SEQ_CST (); + return old; } static inline gpointer mono_atomic_xchg_ptr (volatile gpointer *dest, gpointer exch) { g_static_assert (ATOMIC_POINTER_LOCK_FREE == 2); - return atomic_exchange ((volatile _Atomic(gpointer) *)dest, exch); + gpointer old = atomic_exchange ((volatile _Atomic(gpointer) *)dest, exch); + C11_MEMORY_ORDER_SEQ_CST (); + return old; } static inline gint32 mono_atomic_fetch_add_i32 (volatile gint32 *dest, gint32 add) { g_static_assert (sizeof (atomic_int) == sizeof (*dest) && ATOMIC_INT_LOCK_FREE == 2); - return atomic_fetch_add ((volatile atomic_int *)dest, add); + gint32 old = atomic_fetch_add ((volatile atomic_int *)dest, add); + C11_MEMORY_ORDER_SEQ_CST (); + return old; } static inline gint64 @@ -241,33 +270,41 @@ mono_atomic_fetch_add_i64 (volatile gint64 *dest, gint64 add) { #if SIZEOF_LONG == 8 g_static_assert (sizeof (atomic_long) == sizeof (*dest) && ATOMIC_LONG_LOCK_FREE == 2); - return atomic_fetch_add ((volatile atomic_long *)dest, add); + gint64 old = atomic_fetch_add ((volatile atomic_long *)dest, add); #elif SIZEOF_LONG_LONG == 8 g_static_assert (sizeof (atomic_llong) == sizeof (*dest) && ATOMIC_LLONG_LOCK_FREE == 2); - return atomic_fetch_add ((volatile atomic_llong *)dest, add); + gint64 old = atomic_fetch_add ((volatile atomic_llong *)dest, add); #else #error "gint64 not same size atomic_llong or atomic_long, don't define MONO_USE_STDATOMIC" #endif + C11_MEMORY_ORDER_SEQ_CST (); + return old; } static inline gint8 mono_atomic_load_i8 (volatile gint8 *src) { g_static_assert (sizeof (atomic_char) == sizeof (*src) && ATOMIC_CHAR_LOCK_FREE == 2); - return atomic_load ((volatile atomic_char *)src); + C11_MEMORY_ORDER_SEQ_CST (); + gint8 val = atomic_load ((volatile atomic_char *)src); + return val; } static inline gint16 mono_atomic_load_i16 (volatile gint16 *src) { g_static_assert (sizeof (atomic_short) == sizeof (*src) && ATOMIC_SHORT_LOCK_FREE == 2); - return atomic_load ((volatile atomic_short *)src); + C11_MEMORY_ORDER_SEQ_CST (); + gint16 val = atomic_load ((volatile atomic_short *)src); + return val; } static inline gint32 mono_atomic_load_i32 (volatile gint32 *src) { g_static_assert (sizeof (atomic_int) == sizeof (*src) && ATOMIC_INT_LOCK_FREE == 2); - return atomic_load ((volatile atomic_int *)src); + C11_MEMORY_ORDER_SEQ_CST (); + gint32 val = atomic_load ((volatile atomic_int *)src); + return val; } static inline gint64 @@ -275,20 +312,25 @@ mono_atomic_load_i64 (volatile gint64 *src) { #if SIZEOF_LONG == 8 g_static_assert (sizeof (atomic_long) == sizeof (*src) && ATOMIC_LONG_LOCK_FREE == 2); - return atomic_load ((volatile atomic_long *)src); + C11_MEMORY_ORDER_SEQ_CST (); + gint64 val = atomic_load ((volatile atomic_long *)src); #elif SIZEOF_LONG_LONG == 8 g_static_assert (sizeof (atomic_llong) == sizeof (*src) && ATOMIC_LLONG_LOCK_FREE == 2); - return atomic_load ((volatile atomic_llong *)src); + C11_MEMORY_ORDER_SEQ_CST (); + gint64 val = atomic_load ((volatile atomic_llong *)src); #else #error "gint64 not same size atomic_llong or atomic_long, don't define MONO_USE_STDATOMIC" #endif + return val; } static inline gpointer mono_atomic_load_ptr (volatile gpointer *src) { g_static_assert (ATOMIC_POINTER_LOCK_FREE == 2); - return atomic_load ((volatile _Atomic(gpointer) *)src); + C11_MEMORY_ORDER_SEQ_CST (); + gpointer val = atomic_load ((volatile _Atomic(gpointer) *)src); + return val; } static inline void @@ -296,6 +338,7 @@ mono_atomic_store_i8 (volatile gint8 *dst, gint8 val) { g_static_assert (sizeof (atomic_char) == sizeof (*dst) && ATOMIC_CHAR_LOCK_FREE == 2); atomic_store ((volatile atomic_char *)dst, val); + C11_MEMORY_ORDER_SEQ_CST (); } static inline void @@ -303,6 +346,7 @@ mono_atomic_store_i16 (volatile gint16 *dst, gint16 val) { g_static_assert (sizeof (atomic_short) == sizeof (*dst) && ATOMIC_SHORT_LOCK_FREE == 2); atomic_store ((volatile atomic_short *)dst, val); + C11_MEMORY_ORDER_SEQ_CST (); } static inline void @@ -310,6 +354,7 @@ mono_atomic_store_i32 (volatile gint32 *dst, gint32 val) { g_static_assert (sizeof (atomic_int) == sizeof (*dst) && ATOMIC_INT_LOCK_FREE == 2); atomic_store ((atomic_int *)dst, val); + C11_MEMORY_ORDER_SEQ_CST (); } static inline void @@ -324,6 +369,7 @@ mono_atomic_store_i64 (volatile gint64 *dst, gint64 val) #else #error "gint64 not same size atomic_llong or atomic_long, don't define MONO_USE_STDATOMIC" #endif + C11_MEMORY_ORDER_SEQ_CST (); } static inline void @@ -331,6 +377,7 @@ mono_atomic_store_ptr (volatile gpointer *dst, gpointer val) { g_static_assert (ATOMIC_POINTER_LOCK_FREE == 2); atomic_store ((volatile _Atomic(gpointer) *)dst, val); + C11_MEMORY_ORDER_SEQ_CST (); } #elif defined(MONO_USE_WIN32_ATOMIC) diff --git a/src/tests/FunctionalTests/iOS/Device/ParallelForEachAsync/Program.cs b/src/tests/FunctionalTests/iOS/Device/ParallelForEachAsync/Program.cs new file mode 100644 index 00000000000000..493efaae51f91a --- /dev/null +++ b/src/tests/FunctionalTests/iOS/Device/ParallelForEachAsync/Program.cs @@ -0,0 +1,50 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Threading; +using System.Threading.Tasks; +using System.Runtime.InteropServices; +using System.Linq; + +public static class Program +{ + [DllImport("__Internal")] + public static extern void mono_ios_set_summary (string value); + + private static async Task GitHubIssue_114262_Async() + { + var options = new ParallelOptions + { + MaxDegreeOfParallelism = 5, + CancellationToken = new CancellationTokenSource().Token + }; + + var range = Enumerable.Range(1, 1000); + + for (int i = 0; i < 100; i++) + { + await Parallel.ForEachAsync(range, options, async (data, token) => + { + for (int i = 0; i < 5; i++) + { + await Task.Yield(); + var buffer = new byte[10_000]; + await Task.Run(() => {var _ = buffer[0];} ); + await Task.Yield(); + } + }); + } + } + + public static async Task Main(string[] args) + { + mono_ios_set_summary($"Starting functional test"); + + await GitHubIssue_114262_Async(); + + Console.WriteLine("Done!"); + + return 42; + } +} diff --git a/src/tests/FunctionalTests/iOS/Device/ParallelForEachAsync/iOS.Device.ParallelForEachAsync.Test.csproj b/src/tests/FunctionalTests/iOS/Device/ParallelForEachAsync/iOS.Device.ParallelForEachAsync.Test.csproj new file mode 100644 index 00000000000000..ae748949616933 --- /dev/null +++ b/src/tests/FunctionalTests/iOS/Device/ParallelForEachAsync/iOS.Device.ParallelForEachAsync.Test.csproj @@ -0,0 +1,22 @@ + + + Exe + true + $(NetCoreAppCurrent) + ios + arm64 + false + 42 + true + + + + true + false + iOS.Device.ParallelForEachAsync.Test.dll + + + + + +