date and time created 88/07/21 17:32:57 by marc
authorMarc Teitelbaum <marc@ucbvax.Berkeley.EDU>
Fri, 22 Jul 1988 08:32:57 +0000 (00:32 -0800)
committerMarc Teitelbaum <marc@ucbvax.Berkeley.EDU>
Fri, 22 Jul 1988 08:32:57 +0000 (00:32 -0800)
SCCS-vsn: local/toolchest/ksh/sh/blok.c 1.1

usr/src/local/toolchest/ksh/sh/blok.c [new file with mode: 0644]

diff --git a/usr/src/local/toolchest/ksh/sh/blok.c b/usr/src/local/toolchest/ksh/sh/blok.c
new file mode 100644 (file)
index 0000000..bfbdffc
--- /dev/null
@@ -0,0 +1,217 @@
+/*
+
+ *      Copyright (c) 1984, 1985, 1986 AT&T
+ *      All Rights Reserved
+
+ *      THIS IS UNPUBLISHED PROPRIETARY SOURCE 
+ *      CODE OF AT&T.
+ *      The copyright notice above does not 
+ *      evidence any actual or intended
+ *      publication of such source code.
+
+ */
+/* @(#)blok.c  1.1 */
+/*
+ *     UNIX shell
+ *
+ *     S. R. Bourne
+ *     Rewritten by David Korn
+ *     AT&T Bell Laboratories
+ *
+ */
+
+#include       "defs.h"
+#include       "stak.h"
+#include       "brkincr.h"
+
+
+/*
+ *     storage allocator
+ *     (circular first fit strategy)
+ */
+
+#define BUSY 01
+#define busy(x)        (Rcheat((x)->word)&BUSY)
+
+void   addblok();
+void   free();
+char   *malloc();
+void   setbrk();
+#ifdef DBUG
+void   chkmem();
+extern void    p_str();
+extern void    p_num();
+extern void    p_flush();
+#endif /* DBUG */
+
+
+/*
+ * equivalent to malloc(3) except that a data area stack is
+ * maintained on top of the heap
+ */
+
+char   *malloc(nbytes)
+unsigned       nbytes;
+{
+       register unsigned  rbytes = round(nbytes+BYTESPERWORD,BYTESPERWORD);
+       while(1)
+       {
+               register BLKPTR p = blokp;
+               register BLKPTR q;
+               register int c=0;
+               do
+               {
+                        if(!busy(p))
+                       {
+                               while(!busy(q = p->word))
+                                       p->word = q->word;
+                               if(ADR(q)-ADR(p) >= rbytes)
+                               {
+                                       blokp = BLK(ADR(p)+rbytes);
+                                       if(q > blokp)
+                                               blokp->word = p->word;
+                                       p->word=BLK(Rcheat(blokp)|BUSY);
+                                       return(ADR(p+1));
+                               }
+                       }
+                       q = p; p = BLK(Rcheat(p->word)&~BUSY);
+               }
+               while(p>q || (c++)==0);
+               addblok(rbytes);
+       }
+}
+
+/*
+ * add more space to the heap and move the stack to the top of the heap
+ */
+
+void   addblok(reqd)
+register unsigned int reqd;
+{
+       if(stakbot == 0)
+       {
+               setbrk(3*BRKINCR);
+               bloktop = BLK(brkbegin);
+       }
+       if(stakbas!=staktop)
+       {
+               register STKPTR rndstak;
+               register BLKPTR blokstak;
+               pushstak(0);
+               rndstak=(STKPTR) round(staktop,BYTESPERWORD);
+               blokstak=BLK(stakbas)-1;
+               blokstak->word=stakbsy; stakbsy=blokstak;
+               bloktop->word=BLK(Rcheat(rndstak)|BUSY);
+               bloktop=BLK(rndstak);
+       }
+       reqd += BRKINCR;
+       reqd &= ~(BRKINCR-1);
+       blokp=bloktop;
+       bloktop=bloktop->word=BLK(Rcheat(bloktop)+reqd);
+       reqd = 0;
+       while((char*)bloktop+BRKINCR > brkend+reqd)
+               reqd += BRKINCR;
+       if(reqd)
+               setbrk((int)reqd);
+       bloktop->word=BLK(Rcheat(brkbegin)|BUSY);
+       {
+               register STKPTR stakadr=STK(bloktop+2);
+               register STKPTR sp = stakadr;
+               if(reqd = (staktop-stakbot))
+               {
+                       while(reqd-- > 0)
+                               *sp++ = *stakbot++;
+                       sp--;
+               }
+               staktop = sp;
+               stakbas=stakbot=stakadr;
+       }
+}
+
+/*
+ * mark the block free if address is in the heap
+ */
+
+void   free(ap)
+register char  *ap;
+{
+       register BLKPTR p;
+       if(ap>brkbegin && ap<(char*)bloktop)
+       {
+               p = (BLKPTR)(ap-sizeof(p->word));
+               p->word = (BLKPTR)(Rcheat(p->word)&~BUSY);
+       }
+}
+
+
+void setbrk(incr)
+{
+       register char *a=(char *)(sbrk(incr));
+       if((int)a == -1)
+               error(nospace);
+       a = (char*)round(a,BYTESPERWORD);
+       if(brkbegin==0)
+               brkbegin = a;
+       brkend=a+incr-8;
+#ifndef INT16
+       if(brkend > brkbegin + BRKMAX)
+       {
+               error(nospace);
+       }
+#endif /* INT16 */
+}
+
+#ifdef DBUG
+void chkmem()
+{
+       register BLKPTR p = (BLKPTR)brkbegin;
+       register BLKPTR q;
+       register int    us=0, un=0;
+
+       while(1)
+       {
+               q = (BLKPTR) (Rcheat(p->word)&~BUSY);
+
+               if(q<BLK(brkbegin) || q>bloktop)
+               abort(3);
+               if(p==bloktop)
+                       break;
+               if(busy(p))
+                       us += q-p;
+               else
+                        un += q-p;
+               if(p>=q)
+               {
+                       p_flush();
+                       abort(4);
+               }
+                p=q;
+       }
+       un *= sizeof(*q);
+       us *= sizeof(*q);
+       p_str("free/used/missing",':');
+       p_num(un,' ');
+       p_num(us,' ');
+       p_num((char*)bloktop - (char*)brkbegin - (un+us),NL);
+}
+
+/*
+ * returns 1 if <ap> is on heap and is free
+ * returns 2 if <ap> is on heap and not beginning of a block
+ * otherwise returns 0
+ */
+
+int    chkfree(ap)
+register char  *ap;
+{
+       register BLKPTR p;
+       if(ap>brkbegin && ap<(char*)bloktop)
+       {
+               p = (BLKPTR)(ap-sizeof(p->word));
+               if(p->word<BLK(brkbegin) || p->word>bloktop)
+                       return(2);
+               return(!busy(p));
+       }
+       return(0);
+}
+#endif /* DBUG */