xref: /original-bsd/old/sh/blok.c (revision 6b7db209)
1 /*	blok.c	4.1	82/05/07	*/
2 
3 #
4 /*
5  *	UNIX shell
6  *
7  *	S. R. Bourne
8  *	Bell Telephone Laboratories
9  *
10  */
11 
12 #include	"defs.h"
13 
14 
15 /*
16  *	storage allocator
17  *	(circular first fit strategy)
18  */
19 
20 #define BUSY 01
21 #define busy(x)	(Rcheat((x)->word)&BUSY)
22 
23 POS		brkincr=BRKINCR;
24 BLKPTR		blokp;			/*current search pointer*/
25 BLKPTR		bloktop=BLK(end);	/*top of arena (last blok)*/
26 
27 
28 
29 ADDRESS	alloc(nbytes)
30 	POS		nbytes;
31 {
32 	REG POS		rbytes = round(nbytes+BYTESPERWORD,BYTESPERWORD);
33 
34 	LOOP	INT		c=0;
35 		REG BLKPTR	p = blokp;
36 		REG BLKPTR	q;
37 		REP	IF !busy(p)
38 			THEN	WHILE !busy(q = p->word) DO p->word = q->word OD
39 				IF ADR(q)-ADR(p) >= rbytes
40 				THEN	blokp = BLK(ADR(p)+rbytes);
41 					IF q > blokp
42 					THEN	blokp->word = p->word;
43 					FI
44 					p->word=BLK(Rcheat(blokp)|BUSY);
45 					return(ADR(p+1));
46 				FI
47 			FI
48 			q = p; p = BLK(Rcheat(p->word)&~BUSY);
49 		PER	p>q ORF (c++)==0 DONE
50 		addblok(rbytes);
51 	POOL
52 }
53 
54 VOID	addblok(reqd)
55 	POS		reqd;
56 {
57 	IF stakbas!=staktop
58 	THEN	REG STKPTR	rndstak;
59 		REG BLKPTR	blokstak;
60 
61 		pushstak(0);
62 		rndstak=round(staktop,BYTESPERWORD);
63 		blokstak=BLK(stakbas)-1;
64 		blokstak->word=stakbsy; stakbsy=blokstak;
65 		bloktop->word=BLK(Rcheat(rndstak)|BUSY);
66 		bloktop=BLK(rndstak);
67 	FI
68 	reqd += brkincr; reqd &= ~(brkincr-1);
69 	blokp=bloktop;
70 	bloktop=bloktop->word=BLK(Rcheat(bloktop)+reqd);
71 	bloktop->word=BLK(ADR(end)+1);
72 	BEGIN
73 	   REG STKPTR stakadr=STK(bloktop+2);
74 	   staktop=movstr(stakbot,stakadr);
75 	   stakbas=stakbot=stakadr;
76 	END
77 }
78 
79 VOID	free(ap)
80 	BLKPTR		ap;
81 {
82 	REG BLKPTR	p;
83 
84 	IF (p=ap) ANDF p<bloktop
85 	THEN	Lcheat((--p)->word) &= ~BUSY;
86 	FI
87 }
88 
89 #ifdef DEBUG
90 chkbptr(ptr)
91 	BLKPTR	ptr;
92 {
93 	INT		exf=0;
94 	REG BLKPTR	p = end;
95 	REG BLKPTR	q;
96 	INT		us=0, un=0;
97 
98 	LOOP
99 	   q = Rcheat(p->word)&~BUSY;
100 	   IF p==ptr THEN exf++ FI
101 	   IF q<end ORF q>bloktop THEN abort(3) FI
102 	   IF p==bloktop THEN break FI
103 	   IF busy(p)
104 	   THEN us += q-p;
105 	   ELSE un += q-p;
106 	   FI
107 	   IF p>=q THEN abort(4) FI
108 	   p=q;
109 	POOL
110 	IF exf==0 THEN abort(1) FI
111 	prn(un); prc(SP); prn(us); prc(NL);
112 }
113 #endif
114