Esempio n. 1
0
// 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;
}
Esempio n. 2
0
/*
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);
}