17dd7cddfSDavid du Colombier #include <u.h>
27dd7cddfSDavid du Colombier #include <libc.h>
37dd7cddfSDavid du Colombier #include <draw.h>
47dd7cddfSDavid du Colombier #include <thread.h>
59a747e4fSDavid du Colombier #include <cursor.h>
67dd7cddfSDavid du Colombier #include <mouse.h>
77dd7cddfSDavid du Colombier #include <keyboard.h>
87dd7cddfSDavid du Colombier #include <frame.h>
97dd7cddfSDavid du Colombier #include <fcall.h>
107dd7cddfSDavid du Colombier #include <plumb.h>
117dd7cddfSDavid du Colombier #include "dat.h"
127dd7cddfSDavid du Colombier #include "fns.h"
137dd7cddfSDavid du Colombier
147dd7cddfSDavid du Colombier static Block *blist;
157dd7cddfSDavid du Colombier
167dd7cddfSDavid du Colombier int
tempfile(void)177dd7cddfSDavid du Colombier tempfile(void)
187dd7cddfSDavid du Colombier {
197dd7cddfSDavid du Colombier char buf[128];
207dd7cddfSDavid du Colombier int i, fd;
217dd7cddfSDavid du Colombier
2259cc4ca5SDavid du Colombier snprint(buf, sizeof buf, "/tmp/X%d.%.4sacme", getpid(), getuser());
237dd7cddfSDavid du Colombier for(i='A'; i<='Z'; i++){
247dd7cddfSDavid du Colombier buf[5] = i;
259a747e4fSDavid du Colombier if(access(buf, AEXIST) == 0)
267dd7cddfSDavid du Colombier continue;
277dd7cddfSDavid du Colombier fd = create(buf, ORDWR|ORCLOSE|OCEXEC, 0600);
287dd7cddfSDavid du Colombier if(fd >= 0)
297dd7cddfSDavid du Colombier return fd;
307dd7cddfSDavid du Colombier }
317dd7cddfSDavid du Colombier return -1;
327dd7cddfSDavid du Colombier }
337dd7cddfSDavid du Colombier
347dd7cddfSDavid du Colombier Disk*
diskinit()359a747e4fSDavid du Colombier diskinit()
367dd7cddfSDavid du Colombier {
377dd7cddfSDavid du Colombier Disk *d;
387dd7cddfSDavid du Colombier
397dd7cddfSDavid du Colombier d = emalloc(sizeof(Disk));
407dd7cddfSDavid du Colombier d->fd = tempfile();
417dd7cddfSDavid du Colombier if(d->fd < 0){
427dd7cddfSDavid du Colombier fprint(2, "acme: can't create temp file: %r\n");
439a747e4fSDavid du Colombier threadexitsall("diskinit");
447dd7cddfSDavid du Colombier }
457dd7cddfSDavid du Colombier return d;
467dd7cddfSDavid du Colombier }
477dd7cddfSDavid du Colombier
487dd7cddfSDavid du Colombier static
497dd7cddfSDavid du Colombier uint
ntosize(uint n,uint * ip)507dd7cddfSDavid du Colombier ntosize(uint n, uint *ip)
517dd7cddfSDavid du Colombier {
527dd7cddfSDavid du Colombier uint size;
537dd7cddfSDavid du Colombier
547dd7cddfSDavid du Colombier if(n > Maxblock)
557dd7cddfSDavid du Colombier error("internal error: ntosize");
567dd7cddfSDavid du Colombier size = n;
577dd7cddfSDavid du Colombier if(size & (Blockincr-1))
587dd7cddfSDavid du Colombier size += Blockincr - (size & (Blockincr-1));
597dd7cddfSDavid du Colombier /* last bucket holds blocks of exactly Maxblock */
607dd7cddfSDavid du Colombier if(ip)
617dd7cddfSDavid du Colombier *ip = size/Blockincr;
627dd7cddfSDavid du Colombier return size * sizeof(Rune);
637dd7cddfSDavid du Colombier }
647dd7cddfSDavid du Colombier
657dd7cddfSDavid du Colombier Block*
disknewblock(Disk * d,uint n)667dd7cddfSDavid du Colombier disknewblock(Disk *d, uint n)
677dd7cddfSDavid du Colombier {
687dd7cddfSDavid du Colombier uint i, j, size;
697dd7cddfSDavid du Colombier Block *b;
707dd7cddfSDavid du Colombier
717dd7cddfSDavid du Colombier size = ntosize(n, &i);
727dd7cddfSDavid du Colombier b = d->free[i];
737dd7cddfSDavid du Colombier if(b)
747dd7cddfSDavid du Colombier d->free[i] = b->next;
757dd7cddfSDavid du Colombier else{
767dd7cddfSDavid du Colombier /* allocate in chunks to reduce malloc overhead */
777dd7cddfSDavid du Colombier if(blist == nil){
787dd7cddfSDavid du Colombier blist = emalloc(100*sizeof(Block));
797dd7cddfSDavid du Colombier for(j=0; j<100-1; j++)
807dd7cddfSDavid du Colombier blist[j].next = &blist[j+1];
817dd7cddfSDavid du Colombier }
827dd7cddfSDavid du Colombier b = blist;
837dd7cddfSDavid du Colombier blist = b->next;
847dd7cddfSDavid du Colombier b->addr = d->addr;
857dd7cddfSDavid du Colombier d->addr += size;
867dd7cddfSDavid du Colombier }
877dd7cddfSDavid du Colombier b->n = n;
887dd7cddfSDavid du Colombier return b;
897dd7cddfSDavid du Colombier }
907dd7cddfSDavid du Colombier
917dd7cddfSDavid du Colombier void
diskrelease(Disk * d,Block * b)927dd7cddfSDavid du Colombier diskrelease(Disk *d, Block *b)
937dd7cddfSDavid du Colombier {
947dd7cddfSDavid du Colombier uint i;
957dd7cddfSDavid du Colombier
967dd7cddfSDavid du Colombier ntosize(b->n, &i);
977dd7cddfSDavid du Colombier b->next = d->free[i];
987dd7cddfSDavid du Colombier d->free[i] = b;
997dd7cddfSDavid du Colombier }
1007dd7cddfSDavid du Colombier
1017dd7cddfSDavid du Colombier void
diskwrite(Disk * d,Block ** bp,Rune * r,uint n)1027dd7cddfSDavid du Colombier diskwrite(Disk *d, Block **bp, Rune *r, uint n)
1037dd7cddfSDavid du Colombier {
1047dd7cddfSDavid du Colombier int size, nsize;
1057dd7cddfSDavid du Colombier Block *b;
1067dd7cddfSDavid du Colombier
1077dd7cddfSDavid du Colombier b = *bp;
1087dd7cddfSDavid du Colombier size = ntosize(b->n, nil);
1097dd7cddfSDavid du Colombier nsize = ntosize(n, nil);
1107dd7cddfSDavid du Colombier if(size != nsize){
1117dd7cddfSDavid du Colombier diskrelease(d, b);
1127dd7cddfSDavid du Colombier b = disknewblock(d, n);
1137dd7cddfSDavid du Colombier *bp = b;
1147dd7cddfSDavid du Colombier }
1159a747e4fSDavid du Colombier if(pwrite(d->fd, r, n*sizeof(Rune), b->addr) != n*sizeof(Rune))
1167dd7cddfSDavid du Colombier error("write error to temp file");
1177dd7cddfSDavid du Colombier b->n = n;
1187dd7cddfSDavid du Colombier }
1197dd7cddfSDavid du Colombier
1207dd7cddfSDavid du Colombier void
diskread(Disk * d,Block * b,Rune * r,uint n)1217dd7cddfSDavid du Colombier diskread(Disk *d, Block *b, Rune *r, uint n)
1227dd7cddfSDavid du Colombier {
123*aaee2222SDavid du Colombier int tot, nr;
124*aaee2222SDavid du Colombier char *p;
125*aaee2222SDavid du Colombier
1267dd7cddfSDavid du Colombier if(n > b->n)
1277dd7cddfSDavid du Colombier error("internal error: diskread");
1287dd7cddfSDavid du Colombier
1297dd7cddfSDavid du Colombier ntosize(b->n, nil);
130*aaee2222SDavid du Colombier n *= sizeof(Rune);
131*aaee2222SDavid du Colombier p = (char*)r;
132*aaee2222SDavid du Colombier for(tot = 0; tot < n; tot += nr){
133*aaee2222SDavid du Colombier nr = pread(d->fd, p+tot, n-tot, b->addr+tot);
134*aaee2222SDavid du Colombier if(nr <= 0)
135*aaee2222SDavid du Colombier break; /* tot < n, so error */
136*aaee2222SDavid du Colombier }
137*aaee2222SDavid du Colombier if(tot != n)
1387dd7cddfSDavid du Colombier error("read error from temp file");
1397dd7cddfSDavid du Colombier }
140