Skip to content

Incompatibility of Rust's stdlib with Coroutines #33368

Closed
@lhecker

Description

@lhecker

The issue

thread_local! is used in the stdlib, which does not work well with Coroutines. Repeated access to a TLS variable inside a method might be cached and optimized by LLVM. If a coroutine is transferred from one thread to another this can lead to problems, due to a coroutine still using the cached reference to the TLS storage from the previous thread.

What is not the issue

TLS being incompatible with coroutines for the most part (e.g. here) is well known and not an issue per se. You want to use rand::thread_rng() with coroutines? Just use rand::StdRng::new() instead! Most of the time it's just quite easy to circumvent the TLS by simply using something different. This is not true for the stdlib though. One way or the other you're using it somewhere probably.

Possible solutions

  • Add a option akin to RFC 1513 to replace the stdlib with one with a builtin "libgreen". This might actually be much more practicable than it sounds at first, since the overhead of implementating this is not much larger than of the other options.
  • Add a option akin to RFC 1513 to control inlining of TLS access at compile time.
  • Make it possible to hook into thread_local!. I think that this could be hard to achieve in a performant way though.
  • Reduce the usage of TLS inside the stdlib and instead let crates use it as they please. Panic and unwind semantics could for instance be changed to match C++. This would obviate PANIC_COUNT and it's wonky implementation and still make entirely sure that a stack is unwound twice. Other uses of TLS inside the stdlib could be wrapped inside inline(never) without causing large overheads.
  • Possibly some other way? I read that TLS variables are rendered as globals inside LLVM. If we mark the suspension function as "can write to any memory location", we could make LLVM stop caching the TLS access...

I hope we can find a solution for this as this is really a huge problem for using stackful coroutines with Rust and who doesn't want "Go" but with Rust's syntax, eh? 😉

Metadata

Metadata

Assignees

No one assigned

    Labels

    C-bugCategory: This is a bug.T-libs-apiRelevant to the library API team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions