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

[WIP] Windows and Darwin support #1

Open
wants to merge 2 commits into
base: master
Choose a base branch
from

Conversation

eugeneia
Copy link

@eugeneia eugeneia commented Jun 9, 2017

Sketch for Windows and Darwin support. I haven’t actually tested this since I do not own a Mac or Windows license. This is basically Clozure/ccl#46 translated to this library.

See: https://www.python.org/dev/peps/pep-0418/#monotonic-clocks
For Windows: https://msdn.microsoft.com/en-us/library/windows/desktop/ms724411%28v=vs.85%29.aspx
For Darwin: https://developer.apple.com/library/content/qa/qa1398/_index.html

This adds a new optional parameter, INCLUDE-SUSPEND-P that reflects how
the different platform specific clocks handle system suspension.

See: https://www.python.org/dev/peps/pep-0418/#monotonic-clocks
For Windows: https://msdn.microsoft.com/en-us/library/windows/desktop/ms724411%28v=vs.85%29.aspx
For Darwin: https://developer.apple.com/library/content/qa/qa1398/_index.html

This adds a new optional parameter, INCLUDE-SUSPEND-P that reflects how
the different platform specific clocks handle system suspension.
@death
Copy link
Owner

death commented Jun 9, 2017

Hey, thanks for the pull request! Here are some comments:

  1. I don't like include-suspend-p, especially given that it signals
    an error for certain values on certain platforms. I would prefer to
    have a sentence in the documentation that makes it clear that
    platforms may diverge in behavior in that case.

  2. On platforms where monotonic-time-units-per-second is nontrivial,
    there's no need to inline it. There is also no need to use
    load-time-value for it; I prefer to let the user decide about
    caching.

  3. The docstrings should be the same for all platforms, since the
    interface is meant to be portable. So it would make sense to have a
    file, doc.lisp, where they can be set. It's OK to use the readme
    file or comments for providing auxiliary information, such as
    platform-specific notes.

  4. In the defsystem form's :defsystem-depends-on entry, the feature
    expression should be (or linux darwin windows).

  5. I am not convinced by the PEP's arguments regarding
    QueryPerformanceCounter. I think it should be used in the Windows
    implementation.

  6. I would like to have things tested before merging. Maybe #lisp
    could help here. After the merge, I will submit it to Quicklisp.

@eugeneia
Copy link
Author

eugeneia commented Jun 9, 2017

On platforms where monotonic-time-units-per-second is nontrivial,
there's no need to inline it. There is also no need to use
load-time-value for it; I prefer to let the user decide about
caching.

The usage is pretty much copied from examples from the official documentation of the respective OS. In all cases they are values that do not change during system run time. I think it makes sense to compute the value only once, at load time.

I don't like include-suspend-p, especially given that it signals
an error for certain values on certain platforms. I would prefer to
have a sentence in the documentation that makes it clear that
platforms may diverge in behavior in that case.

I would argue that the API is portable, with the default value of include-suspend-p as an exception. My reasoning for this divergence is that the API is equally non-portable, whether the non-portable parts are merely documented or codified.

The upside of formalizing the platform realities is that someone could write

(get-monotonic-now :raw :include-suspend)

if they care about the specific behavior, and have it fail on platforms where the implementation does not meet the requirements. I think that’s a feature.

I would like to have things tested before merging. Maybe #lisp
could help here. After the merge, I will submit it to Quicklisp.

Absolutely! I merely meant to share the work.

@eugeneia
Copy link
Author

May I ask why you prefer QueryPerformanceCounter?

@death
Copy link
Owner

death commented Jun 13, 2017

QueryPerformanceCounter is simply the good old traditional API to use for such purposes. Windows programmers know it well. It provides a way to acquire high-resolution timing information, usually almost directly from the hardware (uses the Time-Stamp Counter), unlike GetTickCount64. Microsoft claims that it's "typically the best method to use to time-stamp events and measure small time intervals that occur on the same system or virtual machine.".

The article says that for "some hardware systems" running Windows 2000/XP it may give different results on different cores - I am not worried about those systems.

The PEP (from 2012) also lists VirtualBox bugs, at least some of which are fixed. I don't know what they mean when they speak about frequency that varies with workload - they don't give any further information, and this contradicts Microsoft's documentation. There is also the Chromium comment that says it's "unreliable" on "Ahtlon X2 CPUs (model 15)" - I guess it's a joke to bring it up in a PEP because otherwise it's sad.

The biggest gotcha when using this API is described in this paragraph from Microsoft's documentation:

When you compare performance counter results that are acquired from different threads, consider values that differ by ± 1 tick to have an ambiguous ordering. If the time stamps are taken from the same thread, this ± 1 tick uncertainty doesn't apply. In this context, the term tick refers to a period of time equal to 1 ÷ (the frequency of the performance counter obtained from QueryPerformanceFrequency).

We could mention this in the README.

P.S. A cynical me notes in passing that this PEP also demonstrates Google's corporate influence on Python. Politics are not out of the question either, as the arguments presented straddle the borders of FUD.

@eugeneia
Copy link
Author

I don’t have any horse in this race, and just for the record, didn’t notice any bias in the PEP (honestly, I didn’t notice QPC until after you told me). I welcome an alternative implementation, but it won’t be me to supply it as I know too little about Windows APIs.

If we could verify that QPC does not include time suspended that would also simplify the API. The PEP is unsure about it, and I couldn’t really find anything about it on the net.

@phoe
Copy link

phoe commented Dec 5, 2019

Just bumping the PR since I am interested in its outcome.

@death
Copy link
Owner

death commented Dec 6, 2019

Hey phoe, would you be interested in working on this?

@phoe
Copy link

phoe commented Dec 6, 2019

I could, though I'd need a while to set up my Windows/Darwin environment. What needs to be done?

@death
Copy link
Owner

death commented Dec 7, 2019

Basically what I wrote in the first comment in this issue.

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.

3 participants