/* take the action prescribed by 'ev', update the clock, and generate any subsequent events */ static int doevent(struct event *ev) { double nxttime; int i, p, proc; global_time = ev->time; proc = ev->proc; switch (ev->type) { case TRYCRIT: if (critfree == TRUE) addevent(ENTERCRIT, proc, global_time); else addwaiting(proc); break; case ENTERCRIT: critfree = FALSE; nxttime = global_time + dtcrit(); addevent(LEAVECRIT, proc, nxttime); break; case LEAVECRIT: critfree = TRUE; addevent(ATBARRIER, proc, global_time); if ((p = getwaiting()) != 0) { nxttime = global_time; addevent(ENTERCRIT, p, nxttime); } break; case ATBARRIER: barcnt++; if (barcnt == nproc) { nxttime = global_time; for (i = 1; i <= nproc; i++) { nxttime += dtspinoff(); addevent(ENTERWORK, i, nxttime); } barcnt = 0; ncycle++; } break; case ENTERWORK: nxttime = global_time + dtwork(); if (ncycle < ncycmax) addevent(LEAVEWORK, proc, nxttime); break; case LEAVEWORK: addevent(TRYCRIT, proc, global_time); break; default: tst_brkm(TBROK, NULL, "Illegal event"); break; } return (0); }
static long srvwrite(Chan *c, void *va, long count, vlong offset) { long l; Heap * volatile h; SrvFile *sp; Channel *wc; Channel *wr; Pending wait; Sys_Rwrite * volatile w; Sys_FileIO_write req; if(c->qid.type & QTDIR) error(Eperm); acquire(); if(waserror()){ release(); nexterror(); } sp = c->aux; wr = sp->write; if(wr == H) error(Ehungup); wc = cnewc(dev.Rwrite, movtmp, 1); ptradd(D2H(wc)); if(waserror()){ ptrdel(D2H(wc)); destroy(wc); nexterror(); } req.t0 = offset; req.t1 = mem2array(va, count); req.t2 = c->fid; req.t3 = wc; ptradd(D2H(req.t1)); if(waserror()){ ptrdel(D2H(req.t1)); destroy(req.t1); nexterror(); } csend(wr, &req); poperror(); ptrdel(D2H(req.t1)); destroy(req.t1); h = heap(dev.Rwrite); w = H2D(Sys_Rwrite *, h); ptradd(h); if(waserror()){ ptrdel(h); destroy(w); nexterror(); } wait.fid = c->fid; wait.rc = nil; wait.wc = wc; addwaiting(sp, &wait); if(waserror()){ delwaiting(&wait); nexterror(); } crecv(wc, w); poperror(); delwaiting(&wait); if(w->t1 != H) error(string2c(w->t1)); poperror(); ptrdel(h); l = w->t0; destroy(w); poperror(); ptrdel(D2H(wc)); destroy(wc); poperror(); release(); if(l < 0) l = 0; return l; }
static long srvread(Chan *c, void *va, long count, vlong offset) { int l; Heap * volatile h; Array *a; SrvFile *sp; Channel *rc; Channel *rd; Pending wait; Sys_Rread * volatile r; Sys_FileIO_read req; if(c->qid.type & QTDIR){ qlock(&dev.l); if(waserror()){ qunlock(&dev.l); nexterror(); } l = devdirread(c, va, count, 0, 0, srvgen); poperror(); qunlock(&dev.l); return l; } sp = c->aux; acquire(); if(waserror()){ release(); nexterror(); } rd = sp->read; if(rd == H) error(Ehungup); rc = cnewc(dev.Rread, movtmp, 1); ptradd(D2H(rc)); if(waserror()){ ptrdel(D2H(rc)); destroy(rc); nexterror(); } req.t0 = offset; req.t1 = count; req.t2 = c->fid; req.t3 = rc; csend(rd, &req); h = heap(dev.Rread); r = H2D(Sys_Rread *, h); ptradd(h); if(waserror()){ ptrdel(h); destroy(r); nexterror(); } wait.fid = c->fid; wait.rc = rc; wait.wc = nil; addwaiting(sp, &wait); if(waserror()){ delwaiting(&wait); nexterror(); } crecv(rc, r); poperror(); delwaiting(&wait); if(r->t1 != H) error(string2c(r->t1)); a = r->t0; l = 0; if(a != H){ l = a->len; if(l > count) l = count; memmove(va, a->data, l); } poperror(); ptrdel(h); destroy(r); poperror(); ptrdel(D2H(rc)); destroy(rc); poperror(); release(); return l; }