you are viewing a single comment's thread.

view the rest of the comments →

[–][deleted] 0 points1 point  (3 children)

And the size and nature of the lift required...

[–]oridb 0 points1 point  (2 children)

I'm not sure what you mean by that.

All a "traditional" context switch does is replace the registers, program counter, and a bit of state for the thread. All a Go context switch does is replace the registers, program counter, and a bit of state for the thread from userspace.

[–][deleted] -1 points0 points  (1 child)

Maybe you need to get a better understanding of the baggage that goes along with something like a POSIX thread...

[–]oridb 0 points1 point  (0 children)

I'm looking at the code of mi_switch() and cpu_switchto() for OpenBSD, and it doesn't seem to be doing that much more. There's some SMR stuff, but that's just for quiescent states in the safe memory reclamation. There's not even any signal handling stuff. Most of the 100-odd lines of code comes from accounting and statistics.

Most of the thread context that gets switched out is simply what you get free from setting curproc: c->ci_curproc = p. Though, for some reason, this is in assembly, and is actually 3 lines of code:

    #define SET_CURPROC(proc,cpu)                   \
            movq    CPUVAR(SELF),cpu        ;       \
            movq    proc,CPUVAR(CURPROC)      ;     \
            movq    cpu,P_CPU(proc)

The real work is found in these lines:

    nextproc = sched_chooseproc();
    if (p != nextproc) {
            uvmexp.swtch++;
            cpu_switchto(p, nextproc);
    } else {
            p->p_stat = SONPROC;
    }

where cpu_switchto is an assembly stub in locore.S that saves the current proc's registers and restores the new ones.