Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[netcore] Add Monitor.LockContentionCount icall #16538

Merged
merged 2 commits into from
Aug 29, 2019

Conversation

filipnavara
Copy link
Contributor

Contributes to #14828.

The PR just wires up the Monitor.LockContentionCount API to an icall. The actual implementation is not done yet.

I wanted to reuse the existing thread_contentions performance counter but all performance counters unconditionally disabled on netcore builds. Also, the counter is 32-bit only while the managed API returns 64-bit values.

The CoreCLR implementation uses a neat trick to reduce the cost of counting. It stores a per-thread contention counter (eg. in MonoInternalThread field) and a global overflow counter. Up to 2^32 contentions could be recorded in the per-thread field with simple volatile incrementation. Once an overflow happens a slow path is taken that updates a global overflow counter. The LockContentionCount API enumerates all threads and adds up together all the per-thread values along with the global overflow counter. I tried to reimplement that in Mono but I didn't find any way to enumerate all threads and get MonoInternalThread from them.

@filipnavara
Copy link
Contributor Author

I guess I need to bump MONO_CORLIB_VERSION, right?

gint64
ves_icall_System_Threading_Monitor_Monitor_LockContentionCount (void)
{
#ifndef DISABLE_PERFCOUNTERS
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please favor if over #if, such as leaving the pointer null if not enabled.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That is preexisting code that is already compiled-out in this way.

@jaykrell
Copy link
Contributor

I was going to say that:

C:\s\mono2\msvc>findstr /i perl ..\*ac
..\configure.ac:# perl -pi.bak -e "s/^MONO_CORLIB_VERSION=\S+/MONO_CORLIB_VERSION=`uuidgen`/" configure.ac
..\configure.ac:                dnl we need to set some flags to build our 32-bit binaries on 10.6 properly

but for netcore I don't think so.

@filipnavara
Copy link
Contributor Author

In general, MONO_CORLIB_VERSION is also used on netcore builds, but there is no monolite bootstrapping issue that would force me to use it.

@@ -1438,3 +1438,15 @@ ves_icall_System_Threading_Monitor_Monitor_Enter (MonoObject *obj)
{
mono_monitor_enter_internal (obj);
}

#if ENABLE_NETCORE
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: #ifdef (we have a mix of #if ENABLE_NETCORE and #ifdef ENABLE_NETCORE makes sense to unify it

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I wanted to do that... but then I reverted the whole experiment and lost this small change. :)

I noticed that there's a mix already. Unless I will need to amend the PR due to some other change I'd prefer to do the #if/#ifdef unification in separate PR once there is agreement on the preferred way.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not #if vs. #ifdef, though that is something, but if vs. #if[def]. Less code should be explicitly configuration dependent.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jaykrell I don't disagree, in general. In this specific instance it is really #if vs #ifdef though. The netcore version is significantly different from the regular runtime. It is not just an optional feature where we can easily rely on compiler dead code elimination and regular if.

@vargaz
Copy link
Contributor

vargaz commented Aug 28, 2019

@monojenkins build failed

@@ -154,4 +154,10 @@ ICALL_EXPORT
void
ves_icall_System_Threading_Monitor_Monitor_Enter (MonoObject *obj);

#if ENABLE_NETCORE
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: ifdef here as well. Would be nice to get that consistent.

@vargaz vargaz merged commit e32fb11 into mono:master Aug 29, 2019
@marek-safar
Copy link
Member

@steveisok could we enable corefx tests for this?

@filipnavara
Copy link
Contributor Author

@marek-safar Unfortunately the test would not work yet. Performance counters are globally disabled in netcore build in configure script. We'd either need to re-enable it or offer an alternate implementation here.

lambdageek pushed a commit that referenced this pull request Nov 11, 2019
* [netcore] Complete Monitor.LockContentionCount implementation

Fixes #16538
ManickaP pushed a commit to ManickaP/runtime that referenced this pull request Jan 20, 2020
* Add Monitor.LockContentionCount icall

* Add NOHANDLES around the new icall


Commit migrated from mono/mono@e32fb11
ManickaP pushed a commit to ManickaP/runtime that referenced this pull request Jan 20, 2020
…ono#17719)

* [netcore] Complete Monitor.LockContentionCount implementation

Fixes mono/mono#16538



Commit migrated from mono/mono@722c6f7
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants