using System.Runtime.ConstrainedExecution;
using System.Runtime.Versioning;
using System.Diagnostics;
+using System.Runtime.InteropServices;
namespace System.Threading
{
/// <summary>
/// Gets the number of times there was contention upon trying to take a <see cref="Monitor"/>'s lock so far.
/// </summary>
- public static extern long LockContentionCount
- {
- [MethodImpl(MethodImplOptions.InternalCall)]
- get;
- }
+ public static long LockContentionCount => GetLockContentionCount();
+
+ [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
+ private static extern long GetLockContentionCount();
}
}
/// <remarks>
/// For a thread pool implementation that may have different types of work items, the count includes all types.
/// </remarks>
- public static extern long CompletedWorkItemCount
- {
- [MethodImpl(MethodImplOptions.InternalCall)]
- get;
- }
+ public static long CompletedWorkItemCount => GetCompletedWorkItemCount();
+
+ [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
+ private static extern long GetCompletedWorkItemCount();
private static extern long PendingUnmanagedWorkItemCount
{
}
FCIMPLEND
-FCIMPL0(INT64, ObjectNative::GetMonitorLockContentionCount)
+INT64 QCALLTYPE ObjectNative::GetMonitorLockContentionCount()
{
- FCALL_CONTRACT;
- return (INT64)Thread::GetTotalMonitorLockContentionCount();
+ QCALL_CONTRACT;
+
+ INT64 result = 0;
+
+ BEGIN_QCALL;
+
+ result = (INT64)Thread::GetTotalMonitorLockContentionCount();
+
+ END_QCALL;
+ return result;
}
-FCIMPLEND
static FCDECL1(void, Pulse, Object* pThisUNSAFE);
static FCDECL1(void, PulseAll, Object* pThisUNSAFE);
static FCDECL1(FC_BOOL_RET, IsLockHeld, Object* pThisUNSAFE);
- static FCDECL0(INT64, GetMonitorLockContentionCount);
+ static INT64 QCALLTYPE GetMonitorLockContentionCount();
};
#endif // _OBJECTNATIVE_H_
FCIMPLEND
/*****************************************************************************************************/
-FCIMPL0(INT64, ThreadPoolNative::GetCompletedWorkItemCount)
+INT64 QCALLTYPE ThreadPoolNative::GetCompletedWorkItemCount()
{
- FCALL_CONTRACT;
- return (INT64)Thread::GetTotalThreadPoolCompletionCount();
+ QCALL_CONTRACT;
+
+ INT64 result = 0;
+
+ BEGIN_QCALL;
+
+ result = (INT64)Thread::GetTotalThreadPoolCompletionCount();
+
+ END_QCALL;
+ return result;
}
-FCIMPLEND
/*****************************************************************************************************/
FCIMPL0(INT64, ThreadPoolNative::GetPendingUnmanagedWorkItemCount)
static FCDECL2(VOID, CorGetMinThreads, DWORD* workerThreads, DWORD* completionPortThreads);
static FCDECL2(VOID, CorGetAvailableThreads, DWORD* workerThreads, DWORD* completionPortThreads);
static FCDECL0(INT32, GetThreadCount);
- static FCDECL0(INT64, GetCompletedWorkItemCount);
+ static INT64 QCALLTYPE GetCompletedWorkItemCount();
static FCDECL0(INT64, GetPendingUnmanagedWorkItemCount);
static FCDECL0(VOID, NotifyRequestProgress);
FCFuncElement("SetMinThreadsNative", ThreadPoolNative::CorSetMinThreads)
FCFuncElement("GetMinThreadsNative", ThreadPoolNative::CorGetMinThreads)
FCFuncElement("get_ThreadCount", ThreadPoolNative::GetThreadCount)
- FCFuncElement("get_CompletedWorkItemCount", ThreadPoolNative::GetCompletedWorkItemCount)
+ QCFuncElement("GetCompletedWorkItemCount", ThreadPoolNative::GetCompletedWorkItemCount)
FCFuncElement("get_PendingUnmanagedWorkItemCount", ThreadPoolNative::GetPendingUnmanagedWorkItemCount)
FCFuncElement("RegisterWaitForSingleObjectNative", ThreadPoolNative::CorRegisterWaitForSingleObject)
FCFuncElement("BindIOCompletionCallbackNative", ThreadPoolNative::CorBindIoCompletionCallback)
FCFuncElement("ObjPulse", ObjectNative::Pulse)
FCFuncElement("ObjPulseAll", ObjectNative::PulseAll)
FCFuncElement("IsEnteredNative", ObjectNative::IsLockHeld)
- FCFuncElement("get_LockContentionCount", ObjectNative::GetMonitorLockContentionCount)
+ QCFuncElement("GetLockContentionCount", ObjectNative::GetMonitorLockContentionCount)
FCFuncEnd()
FCFuncStart(gOverlappedFuncs)
UINT64 Thread::GetTotalCount(SIZE_T threadLocalCountOffset, UINT64 *overflowCount)
{
- CONTRACTL
- {
+ CONTRACTL {
NOTHROW;
- MODE_ANY;
+ GC_TRIGGERS;
}
CONTRACTL_END;
+ _ASSERTE(overflowCount != nullptr);
+
// enumerate all threads, summing their local counts.
ThreadStoreLockHolder tsl;
UINT64 Thread::GetTotalThreadPoolCompletionCount()
{
- CONTRACTL
- {
+ CONTRACTL {
NOTHROW;
- MODE_ANY;
+ GC_TRIGGERS;
}
CONTRACTL_END;