BSD 3 development
[unix-history] / usr / src / cmd / sh / blok.c
#
/*
* UNIX shell
*
* S. R. Bourne
* Bell Telephone Laboratories
*
*/
#include "defs.h"
/*
* storage allocator
* (circular first fit strategy)
*/
#define BUSY 01
#define busy(x) (Rcheat((x)->word)&BUSY)
POS brkincr=BRKINCR;
BLKPTR blokp; /*current search pointer*/
BLKPTR bloktop=BLK(end); /*top of arena (last blok)*/
ADDRESS alloc(nbytes)
POS nbytes;
{
REG POS rbytes = round(nbytes+BYTESPERWORD,BYTESPERWORD);
LOOP INT c=0;
REG BLKPTR p = blokp;
REG BLKPTR q;
REP IF !busy(p)
THEN WHILE !busy(q = p->word) DO p->word = q->word OD
IF ADR(q)-ADR(p) >= rbytes
THEN blokp = BLK(ADR(p)+rbytes);
IF q > blokp
THEN blokp->word = p->word;
FI
p->word=BLK(Rcheat(blokp)|BUSY);
return(ADR(p+1));
FI
FI
q = p; p = BLK(Rcheat(p->word)&~BUSY);
PER p>q ORF (c++)==0 DONE
addblok(rbytes);
POOL
}
VOID addblok(reqd)
POS reqd;
{
IF stakbas!=staktop
THEN REG STKPTR rndstak;
REG BLKPTR blokstak;
pushstak(0);
rndstak=round(staktop,BYTESPERWORD);
blokstak=BLK(stakbas)-1;
blokstak->word=stakbsy; stakbsy=blokstak;
bloktop->word=BLK(Rcheat(rndstak)|BUSY);
bloktop=BLK(rndstak);
FI
reqd += brkincr; reqd &= ~(brkincr-1);
blokp=bloktop;
bloktop=bloktop->word=BLK(Rcheat(bloktop)+reqd);
bloktop->word=BLK(ADR(end)+1);
BEGIN
REG STKPTR stakadr=STK(bloktop+2);
staktop=movstr(stakbot,stakadr);
stakbas=stakbot=stakadr;
END
}
VOID free(ap)
BLKPTR ap;
{
REG BLKPTR p;
IF (p=ap) ANDF p<bloktop
THEN Lcheat((--p)->word) &= ~BUSY;
FI
}
#ifdef DEBUG
chkbptr(ptr)
BLKPTR ptr;
{
INT exf=0;
REG BLKPTR p = end;
REG BLKPTR q;
INT us=0, un=0;
LOOP
q = Rcheat(p->word)&~BUSY;
IF p==ptr THEN exf++ FI
IF q<end ORF q>bloktop THEN abort(3) FI
IF p==bloktop THEN break FI
IF busy(p)
THEN us += q-p;
ELSE un += q-p;
FI
IF p>=q THEN abort(4) FI
p=q;
POOL
IF exf==0 THEN abort(1) FI
prn(un); prc(SP); prn(us); prc(NL);
}
#endif