Go

Язык программирования

часть 2 - планировщик

Планировщик

http://supertech.csail.mit.edu/papers/steal.pdf

Горутина (Goroutine)

struct  G {
    uintptr stackguard;  // segmented stacks
    uintptr stackbase;
    int64   goid;        // id for stack dumps
    int16   status;      // running, runnable, blocked
    Gobuf   sched;       // saved registers
    G*      alllink;     // links all goroutines
    G*      schedlink;   // links G's in schuedler
    // panic, defer, etc, etc
};

Процессор

struct P {
    Lock;
    int32   id;
    uint32  status;         // one of Pidle/Prunning/...
    uint32  schedtick;      // incremented on every scheduler call
    uint32  syscalltick;    // incremented on every system call

    MCache* mcache;

    // Queue of runnable goroutines.
    G**     runq;
    int32   runqhead;
    int32   runqtail;
    int32   runqsize;

    // Available G's (status == Gdead)
    G*      gfree;
    int32   gfreecnt;
};

Поток

struct  M {
    int32   id;
    G*      g0;             // goroutine with scheduling stack
    G*      gsignal;        // signal-handling G
    G*      curg;           // current running goroutine
    G*      lockedg;        // locked goroutine
    P*      p;              // attached P for executing Go code
    M*      alllink;        // links all M's
    M*      schedlink;      // links M's in scheduler
    void*   stackcache[];   // stack segment cache
    // lots of other stuff
};

Планировщик

struct Sched {
    Lock;
    uint64  goidgen;
    M*      midle;  // idle m's waiting for work
    P*      pidle;  // idle P's

    // Global runnable queue.
    G*      runqhead;
    G*      runqtail;
    int32   runqsize;

    // Global cache of dead G's.
    Lock    gflock;
    G*      gfree;

    uint32  gcwaiting;      // gc is waiting to run
    ...
};