xref: /csrg-svn/local/toolchest/ksh/sh/blok.c (revision 35127)
1*35127Smarc /*
2*35127Smarc 
3*35127Smarc  *      Copyright (c) 1984, 1985, 1986 AT&T
4*35127Smarc  *      All Rights Reserved
5*35127Smarc 
6*35127Smarc  *      THIS IS UNPUBLISHED PROPRIETARY SOURCE
7*35127Smarc  *      CODE OF AT&T.
8*35127Smarc  *      The copyright notice above does not
9*35127Smarc  *      evidence any actual or intended
10*35127Smarc  *      publication of such source code.
11*35127Smarc 
12*35127Smarc  */
13*35127Smarc /* @(#)blok.c	1.1 */
14*35127Smarc /*
15*35127Smarc  *	UNIX shell
16*35127Smarc  *
17*35127Smarc  *	S. R. Bourne
18*35127Smarc  *	Rewritten by David Korn
19*35127Smarc  *	AT&T Bell Laboratories
20*35127Smarc  *
21*35127Smarc  */
22*35127Smarc 
23*35127Smarc #include	"defs.h"
24*35127Smarc #include	"stak.h"
25*35127Smarc #include	"brkincr.h"
26*35127Smarc 
27*35127Smarc 
28*35127Smarc /*
29*35127Smarc  *	storage allocator
30*35127Smarc  *	(circular first fit strategy)
31*35127Smarc  */
32*35127Smarc 
33*35127Smarc #define BUSY 01
34*35127Smarc #define busy(x)	(Rcheat((x)->word)&BUSY)
35*35127Smarc 
36*35127Smarc void	addblok();
37*35127Smarc void	free();
38*35127Smarc char	*malloc();
39*35127Smarc void	setbrk();
40*35127Smarc #ifdef DBUG
41*35127Smarc void	chkmem();
42*35127Smarc extern	void	p_str();
43*35127Smarc extern	void	p_num();
44*35127Smarc extern	void	p_flush();
45*35127Smarc #endif	/* DBUG */
46*35127Smarc 
47*35127Smarc 
48*35127Smarc /*
49*35127Smarc  * equivalent to malloc(3) except that a data area stack is
50*35127Smarc  * maintained on top of the heap
51*35127Smarc  */
52*35127Smarc 
malloc(nbytes)53*35127Smarc char	*malloc(nbytes)
54*35127Smarc unsigned 	nbytes;
55*35127Smarc {
56*35127Smarc 	register unsigned  rbytes = round(nbytes+BYTESPERWORD,BYTESPERWORD);
57*35127Smarc 	while(1)
58*35127Smarc 	{
59*35127Smarc 		register BLKPTR p = blokp;
60*35127Smarc 		register BLKPTR q;
61*35127Smarc 		register int c=0;
62*35127Smarc 		do
63*35127Smarc 		{
64*35127Smarc 			 if(!busy(p))
65*35127Smarc 			{
66*35127Smarc 				while(!busy(q = p->word))
67*35127Smarc 					p->word = q->word;
68*35127Smarc 				if(ADR(q)-ADR(p) >= rbytes)
69*35127Smarc 				{
70*35127Smarc 					blokp = BLK(ADR(p)+rbytes);
71*35127Smarc 					if(q > blokp)
72*35127Smarc 						blokp->word = p->word;
73*35127Smarc 					p->word=BLK(Rcheat(blokp)|BUSY);
74*35127Smarc 					return(ADR(p+1));
75*35127Smarc 				}
76*35127Smarc 			}
77*35127Smarc 			q = p; p = BLK(Rcheat(p->word)&~BUSY);
78*35127Smarc 		}
79*35127Smarc 		while(p>q || (c++)==0);
80*35127Smarc 		addblok(rbytes);
81*35127Smarc 	}
82*35127Smarc }
83*35127Smarc 
84*35127Smarc /*
85*35127Smarc  * add more space to the heap and move the stack to the top of the heap
86*35127Smarc  */
87*35127Smarc 
addblok(reqd)88*35127Smarc void	addblok(reqd)
89*35127Smarc register unsigned int reqd;
90*35127Smarc {
91*35127Smarc 	if(stakbot == 0)
92*35127Smarc 	{
93*35127Smarc 		setbrk(3*BRKINCR);
94*35127Smarc 		bloktop = BLK(brkbegin);
95*35127Smarc 	}
96*35127Smarc 	if(stakbas!=staktop)
97*35127Smarc 	{
98*35127Smarc 		register STKPTR	rndstak;
99*35127Smarc 		register BLKPTR	blokstak;
100*35127Smarc 		pushstak(0);
101*35127Smarc 		rndstak=(STKPTR) round(staktop,BYTESPERWORD);
102*35127Smarc 		blokstak=BLK(stakbas)-1;
103*35127Smarc 		blokstak->word=stakbsy; stakbsy=blokstak;
104*35127Smarc 		bloktop->word=BLK(Rcheat(rndstak)|BUSY);
105*35127Smarc 		bloktop=BLK(rndstak);
106*35127Smarc 	}
107*35127Smarc 	reqd += BRKINCR;
108*35127Smarc 	reqd &= ~(BRKINCR-1);
109*35127Smarc 	blokp=bloktop;
110*35127Smarc 	bloktop=bloktop->word=BLK(Rcheat(bloktop)+reqd);
111*35127Smarc 	reqd = 0;
112*35127Smarc 	while((char*)bloktop+BRKINCR > brkend+reqd)
113*35127Smarc 		reqd += BRKINCR;
114*35127Smarc 	if(reqd)
115*35127Smarc 		setbrk((int)reqd);
116*35127Smarc 	bloktop->word=BLK(Rcheat(brkbegin)|BUSY);
117*35127Smarc 	{
118*35127Smarc 		register STKPTR stakadr=STK(bloktop+2);
119*35127Smarc 		register STKPTR sp = stakadr;
120*35127Smarc 		if(reqd = (staktop-stakbot))
121*35127Smarc 		{
122*35127Smarc 			while(reqd-- > 0)
123*35127Smarc 				*sp++ = *stakbot++;
124*35127Smarc 			sp--;
125*35127Smarc 		}
126*35127Smarc 		staktop = sp;
127*35127Smarc 		stakbas=stakbot=stakadr;
128*35127Smarc 	}
129*35127Smarc }
130*35127Smarc 
131*35127Smarc /*
132*35127Smarc  * mark the block free if address is in the heap
133*35127Smarc  */
134*35127Smarc 
free(ap)135*35127Smarc void	free(ap)
136*35127Smarc register char	*ap;
137*35127Smarc {
138*35127Smarc 	register BLKPTR p;
139*35127Smarc 	if(ap>brkbegin && ap<(char*)bloktop)
140*35127Smarc 	{
141*35127Smarc 		p = (BLKPTR)(ap-sizeof(p->word));
142*35127Smarc 		p->word = (BLKPTR)(Rcheat(p->word)&~BUSY);
143*35127Smarc 	}
144*35127Smarc }
145*35127Smarc 
146*35127Smarc 
setbrk(incr)147*35127Smarc void setbrk(incr)
148*35127Smarc {
149*35127Smarc 	register char *a=(char *)(sbrk(incr));
150*35127Smarc 	if((int)a == -1)
151*35127Smarc 		error(nospace);
152*35127Smarc 	a = (char*)round(a,BYTESPERWORD);
153*35127Smarc 	if(brkbegin==0)
154*35127Smarc 		brkbegin = a;
155*35127Smarc 	brkend=a+incr-8;
156*35127Smarc #ifndef INT16
157*35127Smarc 	if(brkend > brkbegin + BRKMAX)
158*35127Smarc 	{
159*35127Smarc 		error(nospace);
160*35127Smarc 	}
161*35127Smarc #endif	/* INT16 */
162*35127Smarc }
163*35127Smarc 
164*35127Smarc #ifdef DBUG
chkmem()165*35127Smarc void chkmem()
166*35127Smarc {
167*35127Smarc 	register BLKPTR	p = (BLKPTR)brkbegin;
168*35127Smarc 	register BLKPTR	q;
169*35127Smarc 	register int 	us=0, un=0;
170*35127Smarc 
171*35127Smarc 	while(1)
172*35127Smarc 	{
173*35127Smarc 		q = (BLKPTR) (Rcheat(p->word)&~BUSY);
174*35127Smarc 
175*35127Smarc 		if(q<BLK(brkbegin) || q>bloktop)
176*35127Smarc 		abort(3);
177*35127Smarc 		if(p==bloktop)
178*35127Smarc 			break;
179*35127Smarc 		if(busy(p))
180*35127Smarc 			us += q-p;
181*35127Smarc 		else
182*35127Smarc 		  	 un += q-p;
183*35127Smarc 		if(p>=q)
184*35127Smarc 		{
185*35127Smarc 			p_flush();
186*35127Smarc 			abort(4);
187*35127Smarc 		}
188*35127Smarc 		 p=q;
189*35127Smarc 	}
190*35127Smarc 	un *= sizeof(*q);
191*35127Smarc 	us *= sizeof(*q);
192*35127Smarc 	p_str("free/used/missing",':');
193*35127Smarc 	p_num(un,' ');
194*35127Smarc 	p_num(us,' ');
195*35127Smarc 	p_num((char*)bloktop - (char*)brkbegin - (un+us),NL);
196*35127Smarc }
197*35127Smarc 
198*35127Smarc /*
199*35127Smarc  * returns 1 if <ap> is on heap and is free
200*35127Smarc  * returns 2 if <ap> is on heap and not beginning of a block
201*35127Smarc  * otherwise returns 0
202*35127Smarc  */
203*35127Smarc 
chkfree(ap)204*35127Smarc int	chkfree(ap)
205*35127Smarc register char	*ap;
206*35127Smarc {
207*35127Smarc 	register BLKPTR p;
208*35127Smarc 	if(ap>brkbegin && ap<(char*)bloktop)
209*35127Smarc 	{
210*35127Smarc 		p = (BLKPTR)(ap-sizeof(p->word));
211*35127Smarc 		if(p->word<BLK(brkbegin) || p->word>bloktop)
212*35127Smarc 			return(2);
213*35127Smarc 		return(!busy(p));
214*35127Smarc 	}
215*35127Smarc 	return(0);
216*35127Smarc }
217*35127Smarc #endif	/* DBUG */
218