void cinv22(COMPLEX *a,COMPLEX *b){ double tmp = 1/(a->re*(a+3)->im - (a+1)->im*(a+2)->re); COMPLEX res1,res2,res3,res4,one; cmult((a),(a+3),&res1); cmult((a+1),(a+2),&res2); res2.re *= -1; res2.im *= -1; cadd(&res1,&res2,&res3); one.re = 1; one.im = 0; cdev(&one,&res3,&res4); cmult(&res4,a+3,b); cmult(&res4,a+1,b+1); (b+1)->re *= -1; (b+1)->im *= -1; cmult(&res4,a+2,b+2); (b+2)->re *= -1; (b+2)->im *= -1; cmult(&res4,a,b+3); }
void cwrite(Chan* c, uchar *buf, int len, vlong off) { int o, eo; Mntcache *m; ulong eblock, ee; Extent *p, *f, *e, *tail; ulong offset; if(off > maxcache || len == 0) return; m = c->mcp; if(m == 0) return; qlock(m); if(cdev(m, c) == 0) { qunlock(m); return; } offset = off; m->qid.vers++; c->qid.vers++; p = 0; for(f = m->list; f; f = f->next) { if(f->start >= offset) break; p = f; } if(p != 0) { ee = p->start+p->len; eo = offset - p->start; /* pack in predecessor if there is space */ if(offset <= ee && eo < BY2PG) { o = len; if(o > BY2PG - eo) o = BY2PG - eo; if(cpgmove(p, buf, eo, o)) { if(eo+o > p->len) p->len = eo+o; buf += o; len -= o; offset += o; } } } /* free the overlap -- it's a rare case */ eblock = offset+len; while(f && f->start < eblock) { e = f->next; extentfree(f); f = e; } /* link the block (if any) into the middle */ e = cchain(buf, offset, len, &tail); if(e != 0) { tail->next = f; f = e; } if(p == 0) m->list = f; else p->next = f; qunlock(m); }
void cupdate(Chan *c, uchar *buf, int len, vlong off) { Mntcache *m; Extent *tail; Extent *e, *f, *p; int o, ee, eblock; ulong offset; if(off > maxcache || len == 0) return; m = c->mcp; if(m == 0) return; qlock(m); if(cdev(m, c) == 0) { qunlock(m); return; } /* * Find the insertion point */ offset = off; p = 0; for(f = m->list; f; f = f->next) { if(f->start > offset) break; p = f; } /* trim if there is a successor */ eblock = offset+len; if(f != 0 && eblock > f->start) { len -= (eblock - f->start); if(len <= 0) { qunlock(m); return; } } if(p == 0) { /* at the head */ e = cchain(buf, offset, len, &tail); if(e != 0) { m->list = e; tail->next = f; } qunlock(m); return; } /* trim to the predecessor */ ee = p->start+p->len; if(offset < ee) { o = ee - offset; len -= o; if(len <= 0) { qunlock(m); return; } buf += o; offset += o; } /* try and pack data into the predecessor */ if(offset == ee && p->len < BY2PG) { o = len; if(o > BY2PG - p->len) o = BY2PG - p->len; if(cpgmove(p, buf, p->len, o)) { p->len += o; buf += o; len -= o; offset += o; if(len <= 0) { if(f && p->start + p->len > f->start) print("CACHE: p->start=%uld p->len=%d f->start=%uld\n", p->start, p->len, f->start); qunlock(m); return; } } } e = cchain(buf, offset, len, &tail); if(e != 0) { p->next = e; tail->next = f; } qunlock(m); }
int cread(Chan *c, uchar *buf, int len, vlong off) { KMap *k; Page *p; Mntcache *m; Extent *e, **t; int o, l, total; ulong offset; if(off+len > maxcache) return 0; m = c->mcp; if(m == 0) return 0; qlock(m); if(cdev(m, c) == 0) { qunlock(m); return 0; } offset = off; t = &m->list; for(e = *t; e; e = e->next) { if(offset >= e->start && offset < e->start+e->len) break; t = &e->next; } if(e == 0) { qunlock(m); return 0; } total = 0; while(len) { p = cpage(e); if(p == 0) { *t = e->next; extentfree(e); qunlock(m); return total; } o = offset - e->start; l = len; if(l > e->len-o) l = e->len-o; k = kmap(p); if(waserror()) { kunmap(k); putpage(p); qunlock(m); nexterror(); } memmove(buf, (uchar*)VA(k) + o, l); poperror(); kunmap(k); putpage(p); buf += l; len -= l; offset += l; total += l; t = &e->next; e = e->next; if(e == 0 || e->start != offset) break; } qunlock(m); return total; }