OS thread these are two-fold:
Must tasks “cooperatively” yield control back to the scheduling subsystem, or can they be “preemptively” stopped at some point while they’re running, without the task being aware of it?
The second axis of choice is between a stackful and a stackless coroutine
One issue that is often brought up with async/await (in Rust and other languages) is the “function coloring problem” - a complaint that in order to get the result of an async function, you need to use a different operation (such as awaiting it) rather than call it normally. Both green threads and stackful coroutine mechanisms can avoid this outcome, because it’s that special syntax that is used to indicate that something special is happening to manage the stackless state of the coroutine (what specifically depends on the language).
A big issue for any green threading system - Rust’s or Go’s or any other language’s - is what to do about the program stack for these threads
green thread libraries tend to try to adopt a mechanism to spawn threads with smaller stacks, and grow them only as needed.
Go uses stack copying, and benefits from the fact that in Go pointers into a stack can only exist in the same stack, so it just needs to scan that stack to rewrite pointers.