xref: /inferno-os/appl/acme/disk.b (revision 37da2899f40661e3e9631e497da8dc59b971cbd0)
1*37da2899SCharles.Forsythimplement Diskm;
2*37da2899SCharles.Forsyth
3*37da2899SCharles.Forsythinclude "common.m";
4*37da2899SCharles.Forsyth
5*37da2899SCharles.Forsythsys : Sys;
6*37da2899SCharles.Forsythacme : Acme;
7*37da2899SCharles.Forsythutils : Utils;
8*37da2899SCharles.Forsyth
9*37da2899SCharles.ForsythSZSHORT, Block, Blockincr, Astring : import Dat;
10*37da2899SCharles.Forsytherror : import utils;
11*37da2899SCharles.Forsyth
12*37da2899SCharles.Forsythinit(mods : ref Dat->Mods)
13*37da2899SCharles.Forsyth{
14*37da2899SCharles.Forsyth	sys = mods.sys;
15*37da2899SCharles.Forsyth	acme = mods.acme;
16*37da2899SCharles.Forsyth	utils = mods.utils;
17*37da2899SCharles.Forsyth}
18*37da2899SCharles.Forsyth
19*37da2899SCharles.Forsythblist : ref Block;
20*37da2899SCharles.Forsyth
21*37da2899SCharles.Forsythtempfile() : ref Sys->FD
22*37da2899SCharles.Forsyth{
23*37da2899SCharles.Forsyth	buf := sys->sprint("/tmp/X%d.%.4sacme", sys->pctl(0, nil), utils->getuser());
24*37da2899SCharles.Forsyth	for(i:='A'; i<='Z'; i++){
25*37da2899SCharles.Forsyth		buf[5] = i;
26*37da2899SCharles.Forsyth		(ok, nil) := sys->stat(buf);
27*37da2899SCharles.Forsyth		if(ok == 0)
28*37da2899SCharles.Forsyth			continue;
29*37da2899SCharles.Forsyth		fd := sys->create(buf, Sys->ORDWR|Sys->ORCLOSE, 8r600);
30*37da2899SCharles.Forsyth		if(fd != nil)
31*37da2899SCharles.Forsyth			return fd;
32*37da2899SCharles.Forsyth	}
33*37da2899SCharles.Forsyth	return nil;
34*37da2899SCharles.Forsyth}
35*37da2899SCharles.Forsyth
36*37da2899SCharles.ForsythDisk.init() : ref Disk
37*37da2899SCharles.Forsyth{
38*37da2899SCharles.Forsyth	d : ref Disk;
39*37da2899SCharles.Forsyth
40*37da2899SCharles.Forsyth	d = ref Disk;
41*37da2899SCharles.Forsyth	d.free = array[Dat->Maxblock/Dat->Blockincr+1] of ref Block;
42*37da2899SCharles.Forsyth	d.addr = 0;
43*37da2899SCharles.Forsyth	d.fd = tempfile();
44*37da2899SCharles.Forsyth	if(d.fd == nil){
45*37da2899SCharles.Forsyth		error(sys->sprint("can't create temp file %r"));
46*37da2899SCharles.Forsyth		acme->acmeexit("temp create");
47*37da2899SCharles.Forsyth	}
48*37da2899SCharles.Forsyth	return d;
49*37da2899SCharles.Forsyth}
50*37da2899SCharles.Forsyth
51*37da2899SCharles.Forsythntosize(n : int) : (int, int)
52*37da2899SCharles.Forsyth{
53*37da2899SCharles.Forsyth	size : int;
54*37da2899SCharles.Forsyth
55*37da2899SCharles.Forsyth	if (n > Dat->Maxblock)
56*37da2899SCharles.Forsyth		error("bad assert in ntosize");
57*37da2899SCharles.Forsyth	size = n;
58*37da2899SCharles.Forsyth	if(size & (Blockincr-1))
59*37da2899SCharles.Forsyth		size += Blockincr - (size & (Blockincr-1));
60*37da2899SCharles.Forsyth	# last bucket holds blocks of exactly Maxblock
61*37da2899SCharles.Forsyth	return (size * SZSHORT, size/Blockincr);
62*37da2899SCharles.Forsyth}
63*37da2899SCharles.Forsyth
64*37da2899SCharles.ForsythDisk.new(d : self ref Disk, n : int) : ref Block
65*37da2899SCharles.Forsyth{
66*37da2899SCharles.Forsyth	i, j, size : int;
67*37da2899SCharles.Forsyth	b, bl : ref Block;
68*37da2899SCharles.Forsyth
69*37da2899SCharles.Forsyth	(size, i) = ntosize(n);
70*37da2899SCharles.Forsyth	b = d.free[i];
71*37da2899SCharles.Forsyth	if(b != nil)
72*37da2899SCharles.Forsyth		d.free[i] = b.next;
73*37da2899SCharles.Forsyth	else{
74*37da2899SCharles.Forsyth		# allocate in chunks to reduce malloc overhead
75*37da2899SCharles.Forsyth		if(blist == nil){
76*37da2899SCharles.Forsyth			blist = ref Block;
77*37da2899SCharles.Forsyth			bl = blist;
78*37da2899SCharles.Forsyth			for(j=0; j<100-1; j++) {
79*37da2899SCharles.Forsyth				bl.next = ref Block;
80*37da2899SCharles.Forsyth				bl = bl.next;
81*37da2899SCharles.Forsyth			}
82*37da2899SCharles.Forsyth		}
83*37da2899SCharles.Forsyth		b = blist;
84*37da2899SCharles.Forsyth		blist = b.next;
85*37da2899SCharles.Forsyth		b.addr = d.addr;
86*37da2899SCharles.Forsyth		d.addr += size;
87*37da2899SCharles.Forsyth	}
88*37da2899SCharles.Forsyth	b.n = n;
89*37da2899SCharles.Forsyth	return b;
90*37da2899SCharles.Forsyth}
91*37da2899SCharles.Forsyth
92*37da2899SCharles.ForsythDisk.release(d : self ref Disk, b : ref Block)
93*37da2899SCharles.Forsyth{
94*37da2899SCharles.Forsyth	(nil, i) := ntosize(b.n);
95*37da2899SCharles.Forsyth	b.next = d.free[i];
96*37da2899SCharles.Forsyth	d.free[i] = b;
97*37da2899SCharles.Forsyth}
98*37da2899SCharles.Forsyth
99*37da2899SCharles.ForsythDisk.write(d : self ref Disk, bp : ref Block, r : string, n : int) : ref Block
100*37da2899SCharles.Forsyth{
101*37da2899SCharles.Forsyth	size, nsize, i : int;
102*37da2899SCharles.Forsyth	b : ref Block;
103*37da2899SCharles.Forsyth	ab : array of byte;
104*37da2899SCharles.Forsyth
105*37da2899SCharles.Forsyth	b = bp;
106*37da2899SCharles.Forsyth	(size, i) = ntosize(b.n);
107*37da2899SCharles.Forsyth	(nsize, i) = ntosize(n);
108*37da2899SCharles.Forsyth	if(size != nsize){
109*37da2899SCharles.Forsyth		d.release(b);
110*37da2899SCharles.Forsyth		b = d.new(n);
111*37da2899SCharles.Forsyth	}
112*37da2899SCharles.Forsyth	if(sys->seek(d.fd, big b.addr, 0) < big 0)
113*37da2899SCharles.Forsyth		error("seek error in temp file");
114*37da2899SCharles.Forsyth	ab = utils->stob(r, n);
115*37da2899SCharles.Forsyth	if(sys->write(d.fd, ab, len ab) != len ab)
116*37da2899SCharles.Forsyth		error("write error to temp file");
117*37da2899SCharles.Forsyth	ab = nil;
118*37da2899SCharles.Forsyth	b.n = n;
119*37da2899SCharles.Forsyth	return b;
120*37da2899SCharles.Forsyth}
121*37da2899SCharles.Forsyth
122*37da2899SCharles.ForsythDisk.read(d : self ref Disk, b : ref Block, r : ref Astring, n : int)
123*37da2899SCharles.Forsyth{
124*37da2899SCharles.Forsyth	ab : array of byte;
125*37da2899SCharles.Forsyth
126*37da2899SCharles.Forsyth	if (n > b.n)
127*37da2899SCharles.Forsyth		error("bad assert in Disk.read");
128*37da2899SCharles.Forsyth	(nil, nil) := ntosize(b.n);
129*37da2899SCharles.Forsyth	if(sys->seek(d.fd, big b.addr, 0) < big 0)
130*37da2899SCharles.Forsyth		error("seek error in temp file");
131*37da2899SCharles.Forsyth	ab = array[n*SZSHORT] of byte;
132*37da2899SCharles.Forsyth	if(sys->read(d.fd, ab, len ab) != len ab)
133*37da2899SCharles.Forsyth		error("read error from temp file");
134*37da2899SCharles.Forsyth	utils->btos(ab, r);
135*37da2899SCharles.Forsyth	ab = nil;
136*37da2899SCharles.Forsyth}
137