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

[threading] Switch to a native implementation of LowLevelLifoSemaphore #2098

Merged
merged 1 commit into from
Feb 12, 2020

Conversation

CoffeeFlux
Copy link
Contributor

This change is motivated on two main fronts. The first is maintainability - the current managed implementation is difficult to understand and I worry diagnosing any potential issues would be a massive time sink. The second is performance - the current implementation appears to suffer from significant lock contention when running the TechEmpower plaintext benchmark. My hope is that the simpler, cleaner native implementation here will avoid both problems, but I don't want to merge it until we have benchmarking data. However, even if the numbers are similar, I still think it's worth merging just from a maintainability perspective.

The native LifoSemaphore implementation has only ever been tested on posix-like platforms, so Windows behavior is unknown. Currently the Windows implementation of LowLevelLifoSemaphore is very different, so unless we have need for the LifoSemaphore elsewhere in the runtime this isn't a concern.

Many thanks to @filipnavara for the initial implementation.

@marek-safar marek-safar marked this pull request as ready for review January 24, 2020 08:59
@CoffeeFlux CoffeeFlux added the NO-MERGE The PR is not ready for merge yet (see discussion for detailed reasons) label Jan 24, 2020
@CoffeeFlux
Copy link
Contributor Author

Blocking merge until I have benchmarking numbers.

@lambdageek lambdageek changed the title [threading] Switch to a native implementation of LowLevelLifoSemaphore wip [threading] Switch to a native implementation of LowLevelLifoSemaphore Jan 24, 2020
@CoffeeFlux CoffeeFlux changed the title wip [threading] Switch to a native implementation of LowLevelLifoSemaphore [WIP][threading] Switch to a native implementation of LowLevelLifoSemaphore Jan 24, 2020
@CoffeeFlux CoffeeFlux removed the NO-MERGE The PR is not ready for merge yet (see discussion for detailed reasons) label Jan 24, 2020
mono_lifo_semaphore_init (void)
{
LifoSemaphore *semaphore = g_new0 (LifoSemaphore, 1);
if (semaphore == NULL)
Copy link
Contributor

Choose a reason for hiding this comment

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

I think you have to use try_new or somesuch, which might not exist, to actually get null, vs. abort.
Systematic problem in runtime imho -- doesn't want to handle out of memory in many places.


#include <mono/utils/mono-coop-mutex.h>

typedef struct _LifoSemaphore LifoSemaphore;
Copy link
Contributor

Choose a reason for hiding this comment

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

Can we maybe drop the leading underscore:
Pro underscore: It means don't use that identifier, it is private, i.e. say foo, not struct _foo.
Con underscore: Consider what the C++ would look like.

ves_icall_System_Threading_LowLevelLifoSemaphore_DeleteInternal (gpointer sem_ptr)
{
LifoSemaphore *sem = (LifoSemaphore *)sem_ptr;
mono_lifo_semaphore_delete (sem);
Copy link
Contributor

Choose a reason for hiding this comment

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

These lines could be combined.
In fact, you could just declare the function to be taking LifoSemaphore* and remove the cast.
You could also expose mono_lifo_semaphore_delete and save the call/jmp.

@CoffeeFlux
Copy link
Contributor Author

Still blocked on benchmarking, but hopefully it'll be resolved this week.

@CoffeeFlux CoffeeFlux added the runtime-mono specific to the Mono runtime label Feb 11, 2020
This change is motivated on two main fronts. The first is maintainability - the current managed implementation is difficult to understand and I worry diagnosing any potential issues would be a massive time sink. The second is performance - the current implementation appears to suffer from significant lock contention when running the TechEmpower plaintext benchmark. My hope is that the simpler, cleaner native implementation here will avoid both problems, but I don't want to merge it until we have benchmarking data. However, even if the numbers are similar, I still think it's worth merging just from a maintainability perspective.

The native LifoSemaphore implementation has only ever been tested on posix-like platforms, so Windows behavior is unknown. Currently the Windows implementation of LowLevelLifoSemaphore is very different, so unless we have need for the LifoSemaphore elsewhere in the runtime this isn't a concern.

Many thanks to @filipnavara for the initial implementation.
@CoffeeFlux
Copy link
Contributor Author

Finally was able to run the TE benchmark with this PR, and the performance looks similar to before. Will merge regardless for maintainability, and if the lock contention issue remains it should be easier to investigate after this.

@CoffeeFlux CoffeeFlux changed the title [WIP][threading] Switch to a native implementation of LowLevelLifoSemaphore [threading] Switch to a native implementation of LowLevelLifoSemaphore Feb 12, 2020
@CoffeeFlux CoffeeFlux merged commit 3eaff60 into dotnet:master Feb 12, 2020
@ghost ghost locked as resolved and limited conversation to collaborators Dec 11, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area-VM-threading-mono runtime-mono specific to the Mono runtime
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants