1
0
Files
irix-657m-src/eoe/cmd/sh/blok.c
2022-09-29 17:59:04 +03:00

228 lines
4.0 KiB
C

/* Copyright (c) 1990, 1991 UNIX System Laboratories, Inc. */
/* Copyright (c) 1984, 1986, 1987, 1988, 1989, 1990 AT&T */
/* All Rights Reserved */
/* THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF */
/* UNIX System Laboratories, Inc. */
/* The copyright notice above does not evidence any */
/* actual or intended publication of such source code. */
#ident "@(#)sh:blok.c 1.9.6.1"
/*
* UNIX shell
*/
#include <memory.h>
#include "defs.h"
/*
* storage allocator
* (circular first fit strategy)
*/
#define BUSY 01
#define busy(x) (Rcheat((x)->ag.word) & BUSY)
unsigned brkincr = BRKINCR;
static struct blk *blokp; /*current search pointer*/
static struct blk *bloktop; /* top of arena (last blok) */
static unsigned char *brkbegin, *aligned_brkbegin;
unsigned char *setbrk();
void addblok();
#ifdef __STDC__
void *
#else
char *
#endif
alloc(nbytes)
size_t nbytes;
{
register unsigned rbytes = round(nbytes+ALIGN, ALIGN);
for (;;)
{
int c = 0;
register struct blk *p = blokp;
register struct blk *q;
do
{
if (!busy(p))
{
while (!busy(q = p->ag.word))
p->ag.word = q->ag.word;
if ((char *)q - (char *)p >= rbytes)
{
blokp = (struct blk *)((char *)p + rbytes);
if (q > blokp)
blokp->ag.word = p->ag.word;
p->ag.word = (struct blk *)(Rcheat(blokp) | BUSY);
return((char *)(p + 1));
}
}
q = p;
p = (struct blk *)(Rcheat(p->ag.word) & ~BUSY);
} while (p > q || (c++) == 0);
addblok(rbytes);
}
}
void
addblok(reqd)
unsigned reqd;
{
if (stakbot == 0)
{
brkbegin = setbrk(3 * BRKINCR);
aligned_brkbegin = (unsigned char *) round(brkbegin, ALIGN);
bloktop = (struct blk *) aligned_brkbegin;
}
if (stakbas != staktop)
{
register unsigned char *rndstak;
register struct blk *blokstak;
/*
* Round up at least one byte so
* staktop doesn't get clobbered.
*/
rndstak = (unsigned char *)round(staktop+1, ALIGN);
blokstak = (struct blk *)(stakbas) - 1;
blokstak->ag.word = stakbsy;
stakbsy = blokstak;
bloktop->ag.word = (struct blk *)(Rcheat(rndstak) | BUSY);
bloktop = (struct blk *)(rndstak);
}
reqd += brkincr;
reqd &= ~(brkincr - 1);
blokp = bloktop;
bloktop = bloktop->ag.word = (struct blk *)(Rcheat(bloktop) + reqd);
bloktop->ag.word = (struct blk *) ((long) aligned_brkbegin | BUSY);
{
register unsigned char *stakadr = (unsigned char *)(bloktop + 2);
int length = staktop - stakbot;
if(length)
(void)memcpy(stakadr, stakbot, length);
stakbas = stakbot = stakadr;
staktop = stakbot + length;
}
}
void
free(ap)
void *ap;
{
register struct blk *p;
p = (struct blk *)ap;
if (p && p < bloktop && p > (struct blk *)aligned_brkbegin)
{
#ifdef DEBUG
chkbptr(p);
#endif
--p;
p->ag.word = (struct blk *)(Rcheat(p->ag.word) & ~BUSY);
}
}
/*
* realloc() is needed by __gtxt(). Normally not used.
*/
void *
realloc(oldp, nbytes)
void *oldp;
size_t nbytes;
{
void *newp;
newp = alloc((int)nbytes);
if(newp){
(void)memcpy(newp, oldp, nbytes);
free(oldp);
}
return(newp);
}
#ifdef DEBUG
chkbptr(ptr)
struct blk *ptr;
{
int exf = 0;
register struct blk *p = (struct blk *)aligned_brkbegin;
register struct blk *q;
int us = 0, un = 0;
for (;;)
{
q = (struct blk *)(Rcheat(p->ag.word) & ~BUSY);
if (p+1 == ptr)
exf++;
if (q < (struct blk *)aligned_brkbegin || q > bloktop)
abort(/* 3 */);
if (p == bloktop)
break;
if (busy(p))
us += q - p;
else
un += q - p;
if (p >= q)
abort(/* 4 */);
p = q;
}
if (exf == 0)
abort(/* 1 */);
}
chkmem()
{
register struct blk *p = (struct blk *)aligned_brkbegin;
register struct blk *q;
int us = 0, un = 0;
for (;;)
{
q = (struct blk *)(Rcheat(p->ag.word) & ~BUSY);
if (q < (struct blk *)aligned_brkbegin || q > bloktop)
abort(/* 3 */);
if (p == bloktop)
break;
if (busy(p))
us += q - p;
else
un += q - p;
if (p >= q)
abort(/* 4 */);
p = q;
}
prs("un/used/avail ");
prn(un);
blank();
prn(us);
blank();
prn((char *)bloktop - aligned_brkbegin - (un + us));
newline();
}
#endif /* DEBUG */