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