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

New mutex and condition variable implementation on Windows #550

Merged
merged 7 commits into from
Feb 12, 2019

Conversation

rdb
Copy link
Member

@rdb rdb commented Feb 6, 2019

This PR replaces Panda's Mutex and ConditionVar implementation on Windows to no longer use critical sections.

Windows Vista introduced slim reader/writer locks and proper condition variables that have various advantages over critical sections. They are quite slim (8 bytes instead of 40), can be more efficient (uses keyed events, not full-fledged event objects), don't require setup/teardown calls and can in fact be zero-initialized at constant init time.

That last point is particularly interesting because there are various places in Panda where we use static mutexes that we have to jump through hoops to initialize properly, especially because we can't use magic statics (#548). This change would allow us to fix those problems more neatly.

Unlike critical sections, SRWLocks are non-recursive, but I think this is a good thing. The recursive nature of the current MutexWin32Impl on Windows can hide bugs that would otherwise occur on another platform. We will still use critical sections for ReMutex.

The big catch is that we can't use them on Windows XP. To remedy this, I've hand-rolled a mutex implementation for Windows XP that satisfies the same constraints. I'm pretty sure that my implementation is fairly similar to Windows XP's implementation of critical sections, except being zero-initialized, using only 16 bytes and without support for recursion.

At static init time, Panda will initialize function pointers to the right implementation. When we can drop Windows XP (#548) we can just trivially change this to directly wire it to the SRW functions.

As for condition variables, we currently have two implementations on Windows; one that is slower but has full broadcast semantics (ConditionVarFull), and one that is faster but doesn't have notify_all. I would propose we get rid of the limited version; now that we can use the Vista primitives, the only case where this distinction is still relevant is in the Windows XP compatibility emulation, and I would prefer to sacrifice a bit of performance in this tiny corner case so that we don't have to keep the awkwardness of two separate implementations with subtly different semantics.

This uses SRWLock on Vista and above, and uses a hand-rolled implementation on Windows XP that uses Events (and a spinlock, if this is a multi-core system).

Since SRWLocks aren't recursive, ReMutexWin32Impl has been added to implement recursive mutices, using old-fashioned critical sections.

MutexImpl now has a constexpr constructor on all implementations.
See #550.  Now that we use the Vista API for condition variables, the only place where the distinction is still relevant is Windows XP, and it's just not worth it for that one corner case.
This is possible now that all MutexImpl have a constexpr constructor.
MutexImpl guarantees nowadays to be initialized at constant init time, so this is safer on Windows, where we can't rely on magic statics.
@rdb rdb merged commit 11b5f09 into master Feb 12, 2019
@rdb rdb deleted the win32-new-mutex-impl branch February 15, 2019 21:52
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.

1 participant