// Only run this on the rust stack MUST_CHECK bool rust_task::yield() { bool killed = false; if (disallow_yield > 0) { call_on_c_stack(this, (void *)rust_task_yield_fail); } // This check is largely superfluous; it's the one after the context swap // that really matters. This one allows us to assert a useful invariant. // NB: This takes lifecycle_lock three times, and I believe that none of // them are actually necessary, as per #3213. Removing the locks here may // cause *harmless* races with a killer... but I didn't observe any // substantial performance improvement from removing them, even with // msgsend-ring-pipes, and also it's my last day, so I'm not about to // remove them. -- bblum if (must_fail_from_being_killed()) { { scoped_lock with(lifecycle_lock); assert(!(state == task_state_blocked)); } killed = true; } // Return to the scheduler. ctx.next->swap(ctx); if (must_fail_from_being_killed()) { killed = true; } return killed; }
/* Called by landing pads during unwinding to figure out which stack segment we are currently running on and record the stack limit (which was not restored when unwinding through __morestack). */ void rust_task::reset_stack_limit() { uintptr_t sp = get_sp(); // Have to do the rest on the C stack because it involves // freeing stack segments, logging, etc. // FIXME: This probably doesn't need to happen on the C // stack now reset_args ra = {this, sp}; call_on_c_stack(&ra, (void*)reset_stack_limit_on_c_stack); }