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
Original file line number Diff line number Diff line change
Expand Up @@ -119,8 +119,6 @@ private void StartCallback()
[MethodImpl(MethodImplOptions.InternalCall)]
private static extern void SleepInternal(int millisecondsTimeout);

public static void Sleep(int millisecondsTimeout) => SleepInternal(millisecondsTimeout);

[DllImport(RuntimeHelpers.QCall)]
internal static extern void UninterruptibleSleep0();

Expand Down Expand Up @@ -221,9 +219,6 @@ public ThreadPriority Priority
[MethodImpl(MethodImplOptions.InternalCall)]
private extern void SetPriorityNative(int priority);

/// <summary>Returns the operating system identifier for the current thread.</summary>
internal static ulong CurrentOSThreadId => GetCurrentOSThreadId();

[DllImport(RuntimeHelpers.QCall)]
private static extern ulong GetCurrentOSThreadId();

Expand Down
4 changes: 0 additions & 4 deletions src/coreclr/vm/comsynchronizable.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -466,10 +466,6 @@ FCIMPL1(void, ThreadNative::Sleep, INT32 iTime)

HELPER_METHOD_FRAME_BEGIN_0();

// validate the sleep time
if ((iTime < 0) && (iTime != INFINITE_TIMEOUT))
COMPlusThrowArgumentOutOfRange(W("millisecondsTimeout"), W("ArgumentOutOfRange_NeedNonNegOrNegative1"));

GetThread()->UserSleep(iTime);

HELPER_METHOD_FRAME_END();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1998,6 +1998,7 @@
<Compile Include="$(MSBuildThisFileDirectory)System\Threading\RegisteredWaitHandle.Portable.cs" />
</ItemGroup>
<ItemGroup Condition="'$(FeatureCoreCLR)' != 'true' and ('$(TargetsUnix)' == 'true' or '$(TargetsBrowser)' == 'true')">
<Compile Include="$(MSBuildThisFileDirectory)System\Threading\Thread.Unix.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Microsoft\Win32\SafeHandles\SafeWaitHandle.Unix.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Threading\EventWaitHandle.Unix.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Threading\Mutex.Unix.cs" />
Expand All @@ -2009,6 +2010,7 @@
<Compile Include="$(MSBuildThisFileDirectory)System\Threading\WaitSubsystem.WaitableObject.Unix.cs" />
</ItemGroup>
<ItemGroup Condition="'$(FeatureCoreCLR)' != 'true' and '$(TargetsWindows)' == 'true'">
<Compile Include="$(MSBuildThisFileDirectory)System\Threading\Thread.Windows.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Threading\WaitHandle.Windows.cs" />
<Compile Include="$(CommonPath)\Interop\Windows\Kernel32\Interop.GetLastError.cs">
<Link>Interop\Windows\Kernel32\Interop.GetLastError.cs</Link>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using Microsoft.Win32.SafeHandles;
using System.Diagnostics;
using System.Runtime;
using System.Runtime.InteropServices;

namespace System.Threading
{
public sealed partial class Thread
{
internal static void UninterruptibleSleep0() => WaitSubsystem.UninterruptibleSleep0();

private static void SleepInternal(int millisecondsTimeout) => WaitSubsystem.Sleep(millisecondsTimeout);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using Microsoft.Win32.SafeHandles;
using System.Diagnostics;
using System.Runtime;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;

namespace System.Threading
{
public sealed partial class Thread
{
internal static void UninterruptibleSleep0() => Interop.Kernel32.Sleep(0);

private static void SleepInternal(int millisecondsTimeout)
{
Debug.Assert(millisecondsTimeout >= -1);
Interop.Kernel32.Sleep((uint)millisecondsTimeout);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -334,6 +334,17 @@ public static Thread CurrentThread
}
}

[MethodImpl(MethodImplOptions.NoInlining)] // Slow path method. Make sure that the caller frame does not pay for PInvoke overhead.
public static void Sleep(int millisecondsTimeout)
{
if (millisecondsTimeout < Timeout.Infinite)
throw new ArgumentOutOfRangeException(nameof(millisecondsTimeout), millisecondsTimeout, SR.ArgumentOutOfRange_NeedNonNegOrNegative1);
SleepInternal(millisecondsTimeout);
}

/// <summary>Returns the operating system identifier for the current thread.</summary>
internal static ulong CurrentOSThreadId => GetCurrentOSThreadId();

public ExecutionContext? ExecutionContext => ExecutionContext.Capture();

public string? Name
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,20 +81,9 @@ private Thread()

~Thread()
{
#if TARGET_UNIX || TARGET_BROWSER
_waitInfo?.OnThreadExiting();
#endif
FreeInternal();
}

internal static ulong CurrentOSThreadId
{
get
{
return GetCurrentOSThreadId();
}
}

public bool IsAlive
{
get
Expand Down Expand Up @@ -211,6 +200,7 @@ public bool Join(int millisecondsTimeout)

#if TARGET_UNIX || TARGET_BROWSER
[MemberNotNull(nameof(_waitInfo))]
[DynamicDependency(nameof(OnThreadExiting))]
#endif
private void Initialize()
{
Expand All @@ -237,16 +227,6 @@ public static void SpinWait(int iterations)
SpinWait_nop();
}

public static void Sleep(int millisecondsTimeout)
{
if (millisecondsTimeout < Timeout.Infinite)
throw new ArgumentOutOfRangeException(nameof(millisecondsTimeout), millisecondsTimeout, SR.ArgumentOutOfRange_NeedNonNegOrNegative1);

SleepInternal(millisecondsTimeout, true);
}

internal static void UninterruptibleSleep0() => SleepInternal(0, false);

// Called from the runtime
internal void StartCallback()
{
Expand Down Expand Up @@ -320,6 +300,13 @@ internal void ClearWaitSleepJoinState()
ClrState(this, ThreadState.WaitSleepJoin);
}

private static void OnThreadExiting(Thread thread)
{
#if TARGET_UNIX || TARGET_BROWSER
thread.WaitInfo.OnThreadExiting();
#endif
}

[MethodImplAttribute(MethodImplOptions.InternalCall)]
private static extern ulong GetCurrentOSThreadId();

Expand All @@ -328,15 +315,16 @@ internal void ClearWaitSleepJoinState()
private static extern void InitInternal(Thread thread);

[MethodImplAttribute(MethodImplOptions.InternalCall)]
private static extern void InitializeCurrentThread_icall([NotNull] ref Thread? thread);
private static extern Thread GetCurrentThread();

[MethodImpl(MethodImplOptions.NoInlining)]
private static Thread InitializeCurrentThread()
{
InitializeCurrentThread_icall(ref t_currentThread);
var current = GetCurrentThread();
#if TARGET_UNIX || TARGET_BROWSER
t_currentThread.EnsureWaitInfo();
current.EnsureWaitInfo();
#endif
t_currentThread = current;
return t_currentThread;
}

Expand Down Expand Up @@ -367,9 +355,6 @@ private static unsafe void SetName(Thread thread, string? name)
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private static extern bool YieldInternal();

[MethodImplAttribute(MethodImplOptions.InternalCall)]
private static extern void SleepInternal(int millisecondsTimeout, bool allowInterruption);

[Intrinsic]
private static void SpinWait_nop()
{
Expand Down
4 changes: 2 additions & 2 deletions src/mono/mono/metadata/domain-internals.h
Original file line number Diff line number Diff line change
Expand Up @@ -136,8 +136,8 @@ mono_runtime_register_runtimeconfig_json_properties (MonovmRuntimeConfigArgument
void
mono_runtime_install_appctx_properties (void);

gboolean
mono_domain_set_fast (MonoDomain *domain, gboolean force);
void
mono_domain_set_fast (MonoDomain *domain);

G_END_DECLS

Expand Down
5 changes: 2 additions & 3 deletions src/mono/mono/metadata/domain.c
Original file line number Diff line number Diff line change
Expand Up @@ -547,13 +547,12 @@ mono_domain_unset (void)
SET_APPDOMAIN (NULL);
}

gboolean
mono_domain_set_fast (MonoDomain *domain, gboolean force)
void
mono_domain_set_fast (MonoDomain *domain)
{
MONO_REQ_GC_UNSAFE_MODE;

mono_domain_set_internal_with_options (domain, TRUE);
return TRUE;
}

void
Expand Down
2 changes: 2 additions & 0 deletions src/mono/mono/metadata/gc.c
Original file line number Diff line number Diff line change
Expand Up @@ -830,6 +830,8 @@ mono_runtime_do_background_work (void)
{
mono_threads_perform_thread_dump ();

mono_threads_exiting ();

finalize_domain_objects ();

MONO_PROFILER_RAISE (gc_finalizing, ());
Expand Down
2 changes: 1 addition & 1 deletion src/mono/mono/metadata/icall-decl.h
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ ICALL_EXPORT MonoBoolean ves_icall_System_IO_DriveInfo_GetDiskFreeSpace (const g
ICALL_EXPORT MonoBoolean ves_icall_System_Reflection_AssemblyName_ParseAssemblyName (const char*, MonoAssemblyName*, MonoBoolean*, MonoBoolean* is_token_defined_arg);
ICALL_EXPORT MonoBoolean ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_SufficientExecutionStack (void);
ICALL_EXPORT MonoBoolean ves_icall_System_Threading_Thread_YieldInternal (void);
ICALL_EXPORT void ves_icall_System_Threading_Thread_GetCurrentThread (MonoThread * volatile *);
ICALL_EXPORT MonoThread *ves_icall_System_Threading_Thread_GetCurrentThread (void);
ICALL_EXPORT void ves_icall_System_ArgIterator_Setup (MonoArgIterator*, char*, char*);
ICALL_EXPORT MonoType* ves_icall_System_ArgIterator_IntGetNextArgType (MonoArgIterator*);
ICALL_EXPORT void ves_icall_System_ArgIterator_IntGetNextArg (MonoArgIterator*, MonoTypedRef*);
Expand Down
3 changes: 1 addition & 2 deletions src/mono/mono/metadata/icall-def-netcore.h
Original file line number Diff line number Diff line change
Expand Up @@ -487,15 +487,14 @@ HANDLES(THREAD_1, "ClrState", ves_icall_System_Threading_Thread_ClrState, void,
HANDLES(ITHREAD_2, "FreeInternal", ves_icall_System_Threading_InternalThread_Thread_free_internal, void, 1, (MonoInternalThread))
HANDLES(THREAD_15, "GetCurrentOSThreadId", ves_icall_System_Threading_Thread_GetCurrentOSThreadId, guint64, 0, ())
HANDLES(THREAD_16, "GetCurrentProcessorNumber", ves_icall_System_Threading_Thread_GetCurrentProcessorNumber, gint32, 0, ())
NOHANDLES(ICALL(THREAD_5, "GetCurrentThread", ves_icall_System_Threading_Thread_GetCurrentThread))
HANDLES(THREAD_3, "GetState", ves_icall_System_Threading_Thread_GetState, guint32, 1, (MonoInternalThread))
HANDLES(THREAD_4, "InitInternal", ves_icall_System_Threading_Thread_InitInternal, void, 1, (MonoThreadObject))
NOHANDLES(ICALL(THREAD_5, "InitializeCurrentThread_icall", ves_icall_System_Threading_Thread_GetCurrentThread))
HANDLES(THREAD_6, "InterruptInternal", ves_icall_System_Threading_Thread_Interrupt_internal, void, 1, (MonoThreadObject))
HANDLES(THREAD_7, "JoinInternal", ves_icall_System_Threading_Thread_Join_internal, MonoBoolean, 2, (MonoThreadObject, int))
HANDLES(THREAD_8, "SetName_icall", ves_icall_System_Threading_Thread_SetName_icall, void, 3, (MonoInternalThread, const_gunichar2_ptr, gint32))
HANDLES(THREAD_9, "SetPriority", ves_icall_System_Threading_Thread_SetPriority, void, 2, (MonoThreadObject, int))
HANDLES(THREAD_10, "SetState", ves_icall_System_Threading_Thread_SetState, void, 2, (MonoInternalThread, guint32))
HANDLES(THREAD_11, "SleepInternal", ves_icall_System_Threading_Thread_Sleep_internal, void, 2, (gint32, MonoBoolean))
HANDLES(THREAD_13, "StartInternal", ves_icall_System_Threading_Thread_StartInternal, void, 2, (MonoThreadObject, gint32))
NOHANDLES(ICALL(THREAD_14, "YieldInternal", ves_icall_System_Threading_Thread_YieldInternal))

Expand Down
9 changes: 6 additions & 3 deletions src/mono/mono/metadata/threads-types.h
Original file line number Diff line number Diff line change
Expand Up @@ -323,11 +323,11 @@ mono_threads_attach_coop (MonoDomain *domain, gpointer *dummy);
MONO_API void
mono_threads_detach_coop (gpointer cookie, gpointer *dummy);

MonoDomain*
mono_threads_attach_coop_internal (MonoDomain *domain, gpointer *cookie, MonoStackData *stackdata);
void
mono_threads_attach_coop_internal (gpointer *cookie, MonoStackData *stackdata);

void
mono_threads_detach_coop_internal (MonoDomain *orig_domain, gpointer cookie, MonoStackData *stackdata);
mono_threads_detach_coop_internal (gpointer cookie, MonoStackData *stackdata);

void mono_threads_begin_abort_protected_block (void);
gboolean mono_threads_end_abort_protected_block (void);
Expand Down Expand Up @@ -461,6 +461,9 @@ mono_threads_summarize_execute (MonoContext *ctx, gchar **out, MonoStackHash *ha
gboolean
mono_threads_summarize_one (MonoThreadSummary *out, MonoContext *ctx);

void
mono_threads_exiting (void);

#if SIZEOF_VOID_P == 4
/* Spin lock for unaligned InterlockedXXX 64 bit functions on 32bit platforms. */
extern mono_mutex_t mono_interlocked_mutex;
Expand Down
Loading