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

Iteration policy API for eager polling loops #1961

Closed
wants to merge 44 commits into from

Commits on Nov 23, 2019

  1. Macro poll_loop

    Starting work on adding busy loop guards to stream combinators.
    mzabaluev committed Nov 23, 2019
    Configuration menu
    Copy the full SHA
    7e76c90 View commit details
    Browse the repository at this point in the history
  2. Require a token for breaking out of poll_loop!

    An unlabeled break expression inside the loop body given to poll_loop!
    breaks out of the loop in the expansion with the effect of yielding
    to the task. Make the users conscious of this by requiring the break
    expression to carry a token value of type $crate::task::ToYield.
    mzabaluev committed Nov 23, 2019
    Configuration menu
    Copy the full SHA
    455fbf6 View commit details
    Browse the repository at this point in the history
  3. Configuration menu
    Copy the full SHA
    b24c62b View commit details
    Browse the repository at this point in the history
  4. Configuration menu
    Copy the full SHA
    df4d079 View commit details
    Browse the repository at this point in the history
  5. futures-util: Ground work for poll loop guards

    Import the poll_loop! macro from futures-core.
    
    Define a constant with some uneducated guess value on a
    good default for yielding after this number of iterations, which
    should keep the overhead low in good cases, but not block
    the outer poll for too many iterations.
    mzabaluev committed Nov 23, 2019
    Configuration menu
    Copy the full SHA
    ae5303f View commit details
    Browse the repository at this point in the history
  6. Configuration menu
    Copy the full SHA
    3c0ee91 View commit details
    Browse the repository at this point in the history
  7. Configuration menu
    Copy the full SHA
    c7a6ddd View commit details
    Browse the repository at this point in the history
  8. Busy loop guard for stream::Flatten

    Not normally expected to occur, but a busy stream of empty streams
    can theoretically saturate this loop.
    mzabaluev committed Nov 23, 2019
    Configuration menu
    Copy the full SHA
    60c80a5 View commit details
    Browse the repository at this point in the history
  9. Configuration menu
    Copy the full SHA
    b14a1f5 View commit details
    Browse the repository at this point in the history
  10. Configuration menu
    Copy the full SHA
    7dd521e View commit details
    Browse the repository at this point in the history
  11. Configuration menu
    Copy the full SHA
    a01ef0e View commit details
    Browse the repository at this point in the history
  12. Configuration menu
    Copy the full SHA
    3aea69c View commit details
    Browse the repository at this point in the history
  13. Configuration menu
    Copy the full SHA
    78ed967 View commit details
    Browse the repository at this point in the history
  14. Configuration menu
    Copy the full SHA
    46ff20b View commit details
    Browse the repository at this point in the history
  15. Configuration menu
    Copy the full SHA
    58c0791 View commit details
    Browse the repository at this point in the history
  16. Configuration menu
    Copy the full SHA
    ac0ee30 View commit details
    Browse the repository at this point in the history
  17. Configuration menu
    Copy the full SHA
    ff1b4b7 View commit details
    Browse the repository at this point in the history
  18. Busy loop guards for stream::{Filter, FilterMap}

    These can busy loop if the filter future consistenly filters out items.
    mzabaluev committed Nov 23, 2019
    Configuration menu
    Copy the full SHA
    81de5f5 View commit details
    Browse the repository at this point in the history
  19. Configuration menu
    Copy the full SHA
    ae22dc0 View commit details
    Browse the repository at this point in the history
  20. Configuration menu
    Copy the full SHA
    36382a9 View commit details
    Browse the repository at this point in the history
  21. Configuration menu
    Copy the full SHA
    60660e1 View commit details
    Browse the repository at this point in the history
  22. Configuration menu
    Copy the full SHA
    69868ed View commit details
    Browse the repository at this point in the history
  23. Configuration menu
    Copy the full SHA
    e6f3d6c View commit details
    Browse the repository at this point in the history
  24. Configuration menu
    Copy the full SHA
    808ef7a View commit details
    Browse the repository at this point in the history
  25. Configuration menu
    Copy the full SHA
    3107730 View commit details
    Browse the repository at this point in the history
  26. Optimize poll_loop! using NonNullU32

    Use NonNullU32 for the limits on the number of iterations to give
    the optimizer information that the first iteration will always be taken,
    allowing to unroll it or move the loop exit check to the end.
    
    To make poll_loop! macro work with a NonNullU32 argument,
    apply an Into<u32> conversion to it. The iteration range is now
    strictly in u32, while previously the integer type was inferred from
    the macro's argument.
    mzabaluev committed Nov 23, 2019
    Configuration menu
    Copy the full SHA
    1f1c55b View commit details
    Browse the repository at this point in the history
  27. Configuration menu
    Copy the full SHA
    7432b5c View commit details
    Browse the repository at this point in the history
  28. Configuration menu
    Copy the full SHA
    c07e93e View commit details
    Browse the repository at this point in the history
  29. Method yield_after_every to tune iteration guards

    Add combinator method .yield_after_every(n) to stream and future
    combinator types that have been provided with iteration guards.
    
    This gives the user means to fine tune the yielding behavior.
    mzabaluev committed Nov 23, 2019
    Configuration menu
    Copy the full SHA
    4c7da04 View commit details
    Browse the repository at this point in the history
  30. iteration::Policy trait for poll_loop!

    Future-proofing the poll_loop! macro by defining a Policy
    trait that is provided by poll guard implementations:
    Limit with the maximum count, and Unlimited that does not do any checks.
    mzabaluev committed Nov 23, 2019
    Configuration menu
    Copy the full SHA
    65262fd View commit details
    Browse the repository at this point in the history
  31. Rotate the check in poll_loop!, remove ToYield

    Perform the yield check at the end of an iteration. Document
    the check-skipping effect of `continue` and the new semantics of
    `break`: this can now be used to return arbitrary values from
    the poll_loop! expression. This is less semantically weird than
    `break ToYield`, and `continue` gets back its usual meaning of
    continuing iteration unconditionally.
    mzabaluev committed Nov 23, 2019
    Configuration menu
    Copy the full SHA
    fefd6e5 View commit details
    Browse the repository at this point in the history
  32. Rework the loop guard protocol

    iteration::Policy gets methods to observe how the loop has ended.
    LoopGuard, a RAII helper, is used by poll_loop! to catch early returns.
    The uses of poll_loop! in futures-util needed to be changed to split
    borrows out of Pin<&mut Self>, allowing the guard to borrow the
    iteration checker while other state objects are used and modified
    by the loop body.
    Notably, this makes the code of the loops more readable.
    mzabaluev committed Nov 23, 2019
    Configuration menu
    Copy the full SHA
    4271013 View commit details
    Browse the repository at this point in the history
  33. Configuration menu
    Copy the full SHA
    3da7d7d View commit details
    Browse the repository at this point in the history
  34. Improve yield_after macros

    Add optional customization of a possibly nested path to the
    iteration policy checker field.
    mzabaluev committed Nov 23, 2019
    Configuration menu
    Copy the full SHA
    e6f3a06 View commit details
    Browse the repository at this point in the history
  35. Configuration menu
    Copy the full SHA
    f6d6670 View commit details
    Browse the repository at this point in the history
  36. Configuration menu
    Copy the full SHA
    967de9b View commit details
    Browse the repository at this point in the history
  37. Configuration menu
    Copy the full SHA
    d7a4339 View commit details
    Browse the repository at this point in the history
  38. Change default iteration limit to a power of two

    The default limit is nearly arbitrary, aiming to keep the yielding
    overhead in low single digit percentages while not starving other
    pollables for too many iterations.
    Making it a power of two does not make much difference,
    except that it may produce more efficient allocation patterns
    in hypothetical cases e.g. when a future accumulates a collection from
    polled items, then yields, which causes draining of the collection
    by some other pollable.
    mzabaluev committed Nov 23, 2019
    Configuration menu
    Copy the full SHA
    1fc8a23 View commit details
    Browse the repository at this point in the history
  39. Configuration menu
    Copy the full SHA
    ea8ecb0 View commit details
    Browse the repository at this point in the history
  40. Simplify iteration::Policy and erase LoopGuard

    It's not a good idea to let impls run arbitrary code in the RAII
    destructor which may be invoked in an unwind.
    Also, separation between yield_check and when_yielded is not
    really necessary. Erase when_* methods on Policy and allow the
    yield_check method to modify the receiver so that adaptive and
    instrumentation impls are still supported.
    
    With this, LoopGuard is not needed in poll_loop! and is gone.
    mzabaluev committed Nov 23, 2019
    Configuration menu
    Copy the full SHA
    3ffb24a View commit details
    Browse the repository at this point in the history
  41. Improve naming in iteration API

    Renamed:
    Policy -> LoopPolicy, for more instant legibility in docs
    Policy::begin -> LoopPolicy::enter, clearer meaning
    mzabaluev committed Nov 23, 2019
    Configuration menu
    Copy the full SHA
    d129010 View commit details
    Browse the repository at this point in the history
  42. Configuration menu
    Copy the full SHA
    9749923 View commit details
    Browse the repository at this point in the history
  43. Configuration menu
    Copy the full SHA
    db4b867 View commit details
    Browse the repository at this point in the history
  44. futures-util: More descriptive yield_after macros

    Make the meta parameter names describe what each doc string refers to.
    mzabaluev committed Nov 23, 2019
    Configuration menu
    Copy the full SHA
    7f24550 View commit details
    Browse the repository at this point in the history