Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 12 additions & 11 deletions docs/coding-guidelines/interop-guidelines.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ internal static partial class Interop
...
internal static partial class Interop
{
internal static partial class Mincore { ... }
internal static partial class mincore { ... }
}
```
- With few exceptions, the only methods that should be defined in these interop types are DllImports.
Expand All @@ -49,9 +49,7 @@ internal static partial class Interop
```
\Common\src\Interop
\Windows
\Kernel32
... interop files
\Mincore
\mincore
... interop files
\Unix
\libc
Expand All @@ -73,8 +71,8 @@ As shown above, platforms may be additive, in that an assembly may use functiona
\libc
\Interop.strerror.cs
\Windows
\Mincore
\Interop.WaitOnAddress.cs <-- Also contains WakeByAddressSingle
\mincore
\Interop.OutputDebugString.cs
```

- If structs/constants will be used on their own without an associated DllImport, or if they may be used with multiple DllImports not in the same file, they should be declared in a separate file.
Expand All @@ -83,9 +81,9 @@ As shown above, platforms may be additive, in that an assembly may use functiona
```
\Common\src\Interop
\Windows
\Kernel32
\Interop.DuplicateHandle_SafeFileHandle.cs
\Interop.DuplicateHandle_SafePipeHandle.cs
\mincore
\Interop.DuplicateHandle_SafeTokenHandle.cs
\Interop.DuplicateHandle_IntPtr.cs
```

- The library names used per-platform are stored in internal constants in the Interop class in a private Libraries class in a per-platform file named Interop.Libraries.cs. These constants are then used for all DllImports to that library, rather than having the string duplicated each time, e.g.
Expand All @@ -96,9 +94,12 @@ internal static partial class Interop // contents of Common\src\Interop\Windows\
private static class Libraries
{
internal const string Kernel32 = "kernel32.dll";
internal const string OleAut32 = "oleaut32.dll";
internal const string Localization = "api-ms-win-core-localization-l1-2-0.dll";
internal const string Synch = "api-ms-win-core-synch-l1-2-0.dll";
internal const string Handle = "api-ms-win-core-handle-l1-1-0.dll";
internal const string ProcessThreads = "api-ms-win-core-processthreads-l1-1-0.dll";
internal const string File = "api-ms-win-core-file-l1-1-0.dll";
internal const string NamedPipe = "api-ms-win-core-namedpipe-l1-1-0.dll";
internal const string IO = "api-ms-win-core-io-l1-1-0.dll";
...
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,6 @@ The .NET Foundation licenses this file to you under the MIT license.
<SdkNativeLibrary Include="user32.lib" />
<SdkNativeLibrary Include="version.lib" />
<SdkNativeLibrary Include="ws2_32.lib" />
<SdkNativeLibrary Include="Synchronization.lib" />
</ItemGroup>

<ItemGroup>
Expand Down
6 changes: 0 additions & 6 deletions src/coreclr/nativeaot/BuildIntegration/WindowsAPIs.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2340,12 +2340,6 @@ ws2_32!WSCUpdateProvider
ws2_32!WSCWriteNameSpaceOrder
ws2_32!WSCWriteProviderOrder

#
# Synchronization.lib
#
api-ms-win-core-synch-l1-2-0!WaitOnAddress
api-ms-win-core-synch-l1-2-0!WakeByAddressSingle

#
# Include all memory allocation APIs from ucrt to ensure that all of them use allocator
# from the same ucrt copy. Also include the frequently used basic memory manipulation APIs.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@
<NativeAotSourceRoot>$(CoreClrSourceRoot)nativeaot\</NativeAotSourceRoot>
<ArtifactsRoot>$(CoreClrSourceRoot)..\..\artifacts\</ArtifactsRoot>
<NativeRoot>$(CoreClrSourceRoot)..\native\</NativeRoot>
<Win32SDKLibs>advapi32.lib;bcrypt.lib;crypt32.lib;iphlpapi.lib;kernel32.lib;mswsock.lib;ncrypt.lib;normaliz.lib;ntdll.lib;ole32.lib;oleaut32.lib;secur32.lib;user32.lib;version.lib;ws2_32.lib;Synchronization.lib</Win32SDKLibs>
<Win32SDKLibs>advapi32.lib;bcrypt.lib;crypt32.lib;iphlpapi.lib;kernel32.lib;mswsock.lib;ncrypt.lib;normaliz.lib;ntdll.lib;ole32.lib;oleaut32.lib;secur32.lib;user32.lib;version.lib;ws2_32.lib</Win32SDKLibs>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ internal static partial class Sys
[LibraryImport(Libraries.SystemNative, EntryPoint = "SystemNative_LowLevelMonitor_Acquire")]
internal static partial void LowLevelMonitor_Acquire(IntPtr monitor);

[SuppressGCTransition]
[LibraryImport(Libraries.SystemNative, EntryPoint = "SystemNative_LowLevelMonitor_Release")]
internal static partial void LowLevelMonitor_Release(IntPtr monitor);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ internal static partial class Libraries
internal const string Xolehlp = "xolehlp.dll";
internal const string Comdlg32 = "comdlg32.dll";
internal const string Gdiplus = "gdiplus.dll";
internal const string Oleaut32 = "oleaut32.dll";
internal const string Winspool = "winspool.drv";
internal const string Synch = "api-ms-win-core-synch-l1-2-0.dll";
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ internal struct CRITICAL_SECTION
[LibraryImport(Libraries.Kernel32)]
internal static unsafe partial void EnterCriticalSection(CRITICAL_SECTION* lpCriticalSection);

[SuppressGCTransition]
[LibraryImport(Libraries.Kernel32)]
internal static unsafe partial void LeaveCriticalSection(CRITICAL_SECTION* lpCriticalSection);

Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -1852,9 +1852,6 @@
<Compile Include="$(CommonPath)Interop\Windows\Kernel32\Interop.CreateSymbolicLink.cs">
<Link>Common\Interop\Windows\Kernel32\Interop.CreateSymbolicLink.cs</Link>
</Compile>
<Compile Include="$(CommonPath)Interop\Windows\Mincore\Interop.WaitOnAddress.cs">
<Link>Common\Interop\Windows\Mincore\Interop.WaitOnAddress.cs</Link>
</Compile>
<Compile Include="$(CommonPath)Interop\Windows\Kernel32\Interop.CriticalSection.cs">
<Link>Common\Interop\Windows\Kernel32\Interop.CriticalSection.cs</Link>
</Compile>
Expand Down Expand Up @@ -2486,9 +2483,6 @@
<Compile Include="$(CommonPath)Interop\Unix\System.Native\Interop.LowLevelMonitor.cs">
<Link>Common\Interop\Unix\System.Native\Interop.LowLevelMonitor.cs</Link>
</Compile>
<Compile Include="$(CommonPath)Interop\Unix\System.Native\Interop.Futex.cs">
<Link>Common\Interop\Unix\System.Native\Interop.Futex.cs</Link>
</Compile>
<Compile Include="$(CommonPath)Interop\Unix\System.Native\Interop.LSeek.cs">
<Link>Common\Interop\Unix\System.Native\Interop.LSeek.cs</Link>
</Compile>
Expand Down Expand Up @@ -2845,9 +2839,8 @@
<Compile Include="$(MSBuildThisFileDirectory)System\Threading\PortableThreadPool.Unix.cs" Condition="'$(TargetsUnix)' == 'true' or ('$(TargetsBrowser)' == 'true' and '$(FeatureWasmManagedThreads)' != 'true') or '$(TargetsWasi)' == 'true'" />
<Compile Include="$(MSBuildThisFileDirectory)System\Threading\PortableThreadPool.Windows.cs" Condition="'$(TargetsWindows)' == 'true'" />
<Compile Include="$(MSBuildThisFileDirectory)System\Threading\LowLevelLifoSemaphore.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Threading\LowLevelThreadBlocker.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Threading\LowLevelFutex.Windows.cs" Condition="'$(TargetsWindows)' == 'true'" />
<Compile Include="$(MSBuildThisFileDirectory)System\Threading\LowLevelFutex.Unix.cs" Condition="'$(TargetsUnix)' == 'true'" />
<Compile Include="$(MSBuildThisFileDirectory)System\Threading\LowLevelLifoSemaphore.Windows.cs" Condition="'$(TargetsWindows)' == 'true'" />
<Compile Include="$(MSBuildThisFileDirectory)System\Threading\LowLevelLifoSemaphore.Unix.cs" Condition="'$(TargetsUnix)' == 'true' or '$(TargetsBrowser)' == 'true' or '$(TargetsWasi)' == 'true'" />
<Compile Include="$(MSBuildThisFileDirectory)System\Threading\PreAllocatedOverlapped.Windows.cs" Condition="'$(TargetsWindows)' == 'true'" />
<Compile Include="$(MSBuildThisFileDirectory)System\Threading\PreAllocatedOverlapped.Unix.cs" Condition="'$(TargetsUnix)' == 'true' or ('$(TargetsBrowser)' == 'true' and '$(FeatureWasmManagedThreads)' == 'true')" />
<Compile Include="$(MSBuildThisFileDirectory)System\Threading\PreAllocatedOverlapped.Portable.cs" Condition="('$(TargetsBrowser)' != 'true' and '$(TargetsWasi)' != 'true') or '$(FeatureWasmManagedThreads)' == 'true'" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,27 +15,21 @@ internal static class Backoff
// the exponential backoff will generally be not more than 2X worse than the perfect guess and
// will do a lot less attempts than a simple retry. On multiprocessor machine fruitless attempts
// will cause unnecessary sharing of the contended state which may make modifying the state more expensive.
// To protect against degenerate cases we will cap the per-iteration wait to 1-2 thousand spinwaits.
private const uint MaxExponentialBackoffBits = 10;
// To protect against degenerate cases we will cap the per-iteration wait to a few thousand spinwaits.
private const uint MaxExponentialBackoffBits = 14;

internal static unsafe int Exponential(uint attempt)
internal static unsafe void Exponential(uint attempt)
{
if (attempt > 0)
{
attempt = Math.Min(attempt, MaxExponentialBackoffBits);
// We will backoff for some random number of spins that roughly grows as attempt^2
// No need for much randomness here, randomness is "good to have", we could do without it,
// so we will just cheaply hash in the stack location.
uint rand = (uint)&attempt * 2654435769u;
// Set the highmost bit to ensure minimum number of spins is exponentially increasing.
// It basically guarantees that we spin at least 0, 1, 2, 4, 8, 16, times, and so on
rand |= (1u << 31);
uint spins = rand >> (byte)(32 - attempt);
Thread.SpinWait((int)spins);
return (int)spins;
}

return 0;
attempt = Math.Min(attempt, MaxExponentialBackoffBits);
// We will backoff for some random number of spins that roughly grows as attempt^2
// No need for much randomness here, randomness is "good to have", we could do without it,
// so we will just cheaply hash in the stack location.
uint rand = (uint)&attempt * 2654435769u;
// Set the highmost bit to ensure minimum number of spins is exponentially increasing.
// It basically guarantees that we spin at least 0, 1, 2, 4, 8, 16, times, and so on
rand |= (1u << 31);
uint spins = rand >> (byte)(32 - attempt);
Thread.SpinWait((int)spins);
}
}
}

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;

namespace System.Threading
{
/// <summary>
/// A LIFO semaphore.
/// Waits on this semaphore are uninterruptible.
/// </summary>
internal sealed partial class LowLevelLifoSemaphore : IDisposable
{
private WaitSubsystem.WaitableObject _semaphore;

[MemberNotNull(nameof(_semaphore))]
private void Create(int maximumSignalCount)
{
_semaphore = WaitSubsystem.WaitableObject.NewSemaphore(0, maximumSignalCount);
}

public void Dispose()
{
}

private bool WaitCore(int timeoutMs)
{
return WaitSubsystem.Wait(_semaphore, timeoutMs, false, true) == WaitHandle.WaitSuccess;
}

private void ReleaseCore(int count)
{
WaitSubsystem.ReleaseSemaphore(_semaphore, count);
}
}
}
Loading
Loading