void _sched(void) { Proc *p; Thread *t; Resched: p = _threadgetproc(); if((t = p->thread) != nil){ needstack(128); _threaddebug(DBGSCHED, "pausing, state=%s", psstate(t->state)); if(setjmp(t->sched)==0) longjmp(p->sched, 1); return; }else{ t = runthread(p); if(t == nil){ _threaddebug(DBGSCHED, "all threads gone; exiting"); _schedexit(p); } _threaddebug(DBGSCHED, "running %d.%d", t->proc->pid, t->id); p->thread = t; if(t->moribund){ _threaddebug(DBGSCHED, "%d.%d marked to die"); goto Resched; } t->state = Running; t->nextstate = Ready; longjmp(t->sched, 1); } }
int chanalt(Alt *a) { int i, j, ncan, n, canblock; Channel *c; Task *t; needstack(512); for(i=0; a[i].op != CHANEND && a[i].op != CHANNOBLK; i++) ; n = i; canblock = a[i].op == CHANEND; t = taskrunning; //所有alt指向正在运行的task for(i=0; i<n; i++){ a[i].task = t; a[i].xalt = a; } ncan = 0; for(i=0; i<n; i++){ if(altcanexec(&a[i])){ ncan++; } } if(ncan){ j = rand()%ncan; for(i=0; i<n; i++){ if(altcanexec(&a[i])){ if(j-- == 0){ altexec(&a[i]); return i; } } } } if(!canblock) return -1; for(i=0; i<n; i++){ if(a[i].op != CHANNOP) altqueue(&a[i]); } taskswitch(); /* * the guy who ran the op took care of dequeueing us * and then set a[0].alt to the one that was executed. */ return a[0].xalt - a; }
static void dotextbin(Hio *io, Graph *g) { int i, nbin; Statbin *b, bin[2000]; /* 32 kB, but whack is worse */ needstack(8192); /* double check that bin didn't kill us */ nbin = 100; binstats(g->fn, g->arg, g->t0, g->t1, bin, nbin); hprint(io, "stats\n\n"); for(i=0; i<nbin; i++){ b = &bin[i]; hprint(io, "%d: nsamp=%d min=%d max=%d avg=%d\n", i, b->nsamp, b->min, b->max, b->avg); } }
int chanalt(Alt *a) { int i, j, ncan, n, canblock; Channel *c; Task *t; needstack(512); for(i=0; a[i].op != CHANEND && a[i].op != CHANNOBLK; i++) ; n = i; canblock = a[i].op == CHANEND; t = taskrunning; for(i=0; i<n; i++){ a[i].task = t; a[i].xalt = a; } if(dbgalt) print("alt "); ncan = 0; for(i=0; i<n; i++){ c = a[i].c; if(dbgalt) print(" %c:", "esrnb"[a[i].op]); if(dbgalt) { if(c->name) print("%s", c->name); else print("%p", c); } if(altcanexec(&a[i])){ if(dbgalt) print("*"); ncan++; } } if(ncan){ j = rand()%ncan; for(i=0; i<n; i++){ if(altcanexec(&a[i])){ if(j-- == 0){ if(dbgalt){ c = a[i].c; print(" => %c:", "esrnb"[a[i].op]); if(c->name) print("%s", c->name); else print("%p", c); print("\n"); } altexec(&a[i]); return i; } } } } if(dbgalt)print("\n"); if(!canblock) return -1; for(i=0; i<n; i++){ if(a[i].op != CHANNOP) altqueue(&a[i]); } taskswitch(); /* * the guy who ran the op took care of dequeueing us * and then set a[0].alt to the one that was executed. */ return a[0].xalt - a; }
static KeySym __xtoplan9kbd(XEvent *e) { KeySym k; if(e->xany.type != KeyPress) return -1; needstack(64*1024); /* X has some *huge* buffers in openobject */ /* and they're even bigger on SuSE */ XLookupString((XKeyEvent*)e,NULL,0,&k,NULL); if(k == NoSymbol) return -1; if(k&0xFF00){ switch(k){ case XK_BackSpace: case XK_Tab: case XK_Escape: case XK_Delete: case XK_KP_0: case XK_KP_1: case XK_KP_2: case XK_KP_3: case XK_KP_4: case XK_KP_5: case XK_KP_6: case XK_KP_7: case XK_KP_8: case XK_KP_9: case XK_KP_Divide: case XK_KP_Multiply: case XK_KP_Subtract: case XK_KP_Add: case XK_KP_Decimal: k &= 0x7F; break; case XK_Linefeed: k = '\r'; break; case XK_KP_Space: k = ' '; break; case XK_Home: case XK_KP_Home: k = Khome; break; case XK_Left: case XK_KP_Left: k = Kleft; break; case XK_Up: case XK_KP_Up: k = Kup; break; case XK_Down: case XK_KP_Down: k = Kdown; break; case XK_Right: case XK_KP_Right: k = Kright; break; case XK_Page_Down: case XK_KP_Page_Down: k = Kpgdown; break; case XK_End: case XK_KP_End: k = Kend; break; case XK_Page_Up: case XK_KP_Page_Up: k = Kpgup; break; case XK_Insert: case XK_KP_Insert: k = Kins; break; case XK_KP_Enter: case XK_Return: k = '\n'; break; case XK_Alt_L: case XK_Meta_L: /* Shift Alt on PCs */ case XK_Alt_R: case XK_Meta_R: /* Shift Alt on PCs */ case XK_Multi_key: return -1; default: /* not ISO-1 or tty control */ if(k>0xff) { k = _p9keysym2ucs(k); if(k==-1) return -1; } } } /* Compensate for servers that call a minus a hyphen */ if(k == XK_hyphen) k = XK_minus; /* Do control mapping ourselves if translator doesn't */ if(e->xkey.state&ControlMask) k &= 0x9f; if(k == NoSymbol) { return -1; } return k+0; }
// 协程切换 void taskswitch(void) { needstack(0); contextswitch(&taskrunning->context, &taskschedcontext); }
Memimage* statgraph(Graph *g) { int i, nbin, x, lo, hi, min, max, first; Memimage *m; Rectangle r; Statbin *b, bin[2000]; /* 32 kB, but whack is worse */ needstack(8192); /* double check that bin didn't kill us */ if(g->wid <= MinWidth) g->wid = DefaultWidth; if(g->ht <= MinHeight) g->ht = DefaultHeight; if(g->wid > nelem(bin)) g->wid = nelem(bin); if(g->fill < 0) g->fill = ((uint)(uintptr)g->arg>>8)%nelem(lofill); if(g->fill > nelem(lofill)) g->fill %= nelem(lofill); nbin = g->wid - (Left+Right); binstats(g->fn, g->arg, g->t0, g->t1, bin, nbin); /* * compute bounds */ min = g->min; max = g->max; if(min < 0 || max <= min){ min = max = 0; first = 1; for(i=0; i<nbin; i++){ b = &bin[i]; if(b->nsamp == 0) continue; if(first || b->min < min) min = b->min; if(first || b->max > max) max = b->max; first = 0; } } qlock(&memdrawlock); ginit(); if(smallfont==nil || black==nil || blue==nil || red==nil || hifill[0]==nil || lofill[0]==nil){ werrstr("graphics initialization failed: %r"); qunlock(&memdrawlock); return nil; } /* fresh image */ m = allocmemimage(Rect(0,0,g->wid,g->ht), ABGR32); if(m == nil){ qunlock(&memdrawlock); return nil; } r = Rect(Left, Top, g->wid-Right, g->ht-Bottom); memfillcolor(m, DTransparent); /* x axis */ memimagedraw(m, Rect(r.min.x, r.max.y, r.max.x, r.max.y+1), black, ZP, memopaque, ZP, S); /* y labels */ drawlabel(m, r.min, max); if(min != 0) drawlabel(m, Pt(r.min.x, r.max.y-smallfont->height), min); /* actual data */ for(i=0; i<nbin; i++){ b = &bin[i]; if(b->nsamp == 0) continue; lo = scalept(b->min, min, max, r.max.y, r.min.y); hi = scalept(b->max, min, max, r.max.y, r.min.y); x = r.min.x+i; hi-=2; memimagedraw(m, Rect(x, hi, x+1,lo), hifill[g->fill%nelem(hifill)], ZP, memopaque, ZP, S); memimagedraw(m, Rect(x, lo, x+1, r.max.y), lofill[g->fill%nelem(lofill)], ZP, memopaque, ZP, S); } if(bin[nbin-1].nsamp) drawlabel(m, Pt(r.max.x, r.min.y+(Dy(r)-smallfont->height)/2), bin[nbin-1].avg); qunlock(&memdrawlock); return m; }
void taskswitch(void) {//主动进行协程切换,其实就是切换到main协程,到那里去进行实际的切换 needstack(0);//检测堆栈溢出 contextswitch(&taskrunning->context, &taskschedcontext); }