type coro … // newcoro creates a new coro containing a // goroutine blocked waiting to run f // and returns that coro. func newcoro(f func(*coro)) *coro { … } // corostart is the entry func for a new coroutine. // It runs the coroutine user function f passed to corostart // and then calls coroexit to remove the extra concurrency. func corostart() { … } // coroexit is like coroswitch but closes the coro // and exits the current goroutine func coroexit(c *coro) { … } // coroswitch switches to the goroutine blocked on c // and then blocks the current goroutine on c. func coroswitch(c *coro) { … } // coroswitch_m is the implementation of coroswitch // that runs on the m stack. // // Note: Coroutine switches are expected to happen at // an order of magnitude (or more) higher frequency // than regular goroutine switches, so this path is heavily // optimized to remove unnecessary work. // The fast path here is three CAS: the one at the top on gp.atomicstatus, // the one in the middle to choose the next g, // and the one at the bottom on gnext.atomicstatus. // It is important not to add more atomic operations or other // expensive operations to the fast path. func coroswitch_m(gp *g) { … }