Skip to content

Insert yield checks at appropriate places #524

Description

@eholk
No description provided.

Activity

  1. ghost assigned on Jun 20, 2011
  2. brson commented on Sep 14, 2011

    @brson
    Contributor

    There's the issue of never yielding, and the issue of fairness. For 0.1 let's just try to make sure we don't tie up a scheduler forever in an iloop.

  3. brson commented on Sep 16, 2011

    @brson
    Contributor

    I added a yield after send, which I thinks makes it less likely that one might create an iloop that never yields. Do we want to try to make back edges yield for 0.1? I say no.

  4. ghost assigned on Sep 27, 2011
  5. ghost assigned on Mar 15, 2012
  6. bblum commented on Aug 16, 2012

    @bblum
    Contributor

    I will note that when this happens, we will probably need to change rust_task_yield_fail() in rust_task.cpp to not always fail if a task yields in an atomic section. instead, it should check if the yield was explicit or compiler-inserted, and fail if the first or silently ignore if the second.

  7. graydon commented on Apr 18, 2013

    @graydon
    Contributor

    discussed at workweek, this is going to be accomplished "natively" by work stealing + keeping at least one spare thread whenever there are more tasks than threads.

  8. bblum commented on Jun 7, 2013

    @bblum
    Contributor

    Maybe I don't understand what that means, but won't that just result in "extra threads" being allocated until there are as many threads as tasks?

  9. bblum commented on Jun 26, 2013

    @bblum
    Contributor

    I'm pretty sure this is still an issue, so reopening. With the new runtime written in rust, we could have a #[no_yield_checks] attribute for crate-level or file-level that we'd put in the scheduler.

  10. reopened this on Jun 26, 2013
  11. thestinger commented on Jun 26, 2013

    @thestinger
    Contributor

    The only overhead of a thread compared to a Rust task is the context switching at arbitrary points. Inserting yield checks would be much slower than just using 1:1 threading, at least on Linux, so I don't think it makes sense to do this. You're better off with context switches than yield checks in critical loops.

  12. bblum commented on Jun 26, 2013

    @bblum
    Contributor

    If I remember right, the plan was to insert checks on back-edges in the CFG (presumably including tailcalls), and to have them only actually yield 1 in BIGNUM times. It would be worth profiling but I think that would still save significantly over kernel-mode context switches..

  13. graydon commented on Jun 26, 2013

    @graydon
    Contributor

    @bblum So long as the stealing and thread spawning behavior is rate limited (i.e. after the spare thread sees one of the schedulers hasn't seen a yield in K ms), the scenario you're describing would occur only when a user is exclusively making non-yielding (i.e., no i/o, no sleeping, fully cpu bound) tasks. And that's the case where multiplying threads to equal tasks is probably appropriate behavior: to saturate all the available cores with computation, as best the os kernel can.

    It is possible someone will not want this behavior in some case. If they make so many cpu-spinning tasks the os literally can't handle the overhead, or perhaps they want a fixed number of rust threads even though they want to overload them. There are other mechanisms users can employ to achieve these ends in these cases. We decided on the strategy we did because it seemed like the more appropriate default, and avoids the worst problems (systemic taxes, artificial blocking or starvation). Most of the time, tasks do i/o or enter a potential yield point (say, malloc) regularly.

  14. thestinger commented on Jun 26, 2013

    @thestinger
    Contributor

    Somewhat off-topic: I don't think malloc is really a potential yield point, because with jemalloc it's lock-free for allocations under 4K and only hits kernel synchronization when it actually has to make a system call (allocations over 4K, and occasionally to increase the pool size for small ones). It's never really blocking.

  15. 12 remaining items

  16. added a commit that references this issue on Jun 3, 2025
  17. added 2 commits that reference this issue on Aug 21, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-concurrencyArea: ConcurrencyA-runtimeArea: std's runtime and "pre-main" init for handling backtraces, unwinds, stack overflowsE-hardCall for participation: Hard difficulty. Experience needed to fix: A lot.P-mediumMedium priority

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions