From 7acd25a42205412aea65b28806e72c48bd58bb77 Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Sat, 6 Jun 2015 23:00:33 +0100 Subject: [PATCH] sh: Ooh look it works on 6809 Remove remaining rcheat Add some comments Make a gratuitious cross file call to fix the gcc miscompile (eww...) Add a pile of debug (leaving in for the moment until I'm sure) Fix brk handling in the original code (I guess there is some magic V7 PDP11 quirk we don't have) --- Applications/V7/cmd/sh/blok.c | 75 +++++++++++++++++++++++++++++------ Applications/V7/cmd/sh/main.c | 4 ++ Applications/V7/cmd/sh/mode.h | 1 - 3 files changed, 66 insertions(+), 14 deletions(-) diff --git a/Applications/V7/cmd/sh/blok.c b/Applications/V7/cmd/sh/blok.c index 742e1147..9f276add 100644 --- a/Applications/V7/cmd/sh/blok.c +++ b/Applications/V7/cmd/sh/blok.c @@ -12,13 +12,15 @@ #include "defs.h" +extern int printf(const char *, ...); + /* * storage allocator * (circular first fit strategy) */ #define BUSY 01 -#define busy(x) (Rcheat((x)->word)&BUSY) +#define busy(x) (((intptr_t)(x)->word) & BUSY) POS brkincr = BRKINCR; BLKPTR blokp; /* current search pointer */ @@ -29,56 +31,97 @@ void blokinit(void) { end = setbrk(0); /* Find where space starts */ if (((uint8_t)end) & 1) - end = setbrk(1); /* Align */ + end = 1 + (uint8_t *)setbrk(1); /* Align */ bloktop = BLK(end); +/* printf("Begin: blokop %p end %p\n", (void *)bloktop, end); */ } ADDRESS alloc(POS nbytes) { register POS rbytes = round(nbytes + BYTESPERWORD, BYTESPERWORD); +/* printf("allocating %d [", rbytes); */ for (;;) { int c = 0; register BLKPTR p = blokp; register BLKPTR q; do { + /* Only interested in holes */ if (!busy(p)) { + /* Merge adjacent holes */ while (!busy(q = p->word)) p->word = q->word; +/* printf("H%d ", ADR(q) - ADR(p)); */ + gratuitous_call(); + /* Big enough hole */ if (ADR(q) - ADR(p) >= rbytes) { + /* blokp is the first byte after + the hole */ blokp = BLK(ADR(p) + rbytes); - if (q > blokp) + /* Splitting ? */ + if (q > blokp) { +/* printf("S");*/ + gratuitous_call(); blokp->word = p->word; - p->word = BLK(Rcheat(blokp) | BUSY); - return (ADR(p + 1)); + } + /* Update our block */ + p->word = BLK( + ((intptr_t)(blokp)) | BUSY); + /* Usable space beyond header */ +/* printf("] %p\n", (void *)p); */ + return ADR(p + 1); }; } + /* Remember the last pointer */ q = p; - p = BLK(Rcheat(p->word) & ~BUSY); + /* Move on one block */ + p = BLK(((intptr_t)(p->word)) & ~BUSY); + + if (p == q) { + write(2, "membad\n", 7); + exit(1); + } +/* printf("."); */ } while (p > q || (c++) == 0); + /* No room at the inn - add more space */ +/* printf("+%d+", rbytes); */ addblok(rbytes); } } +static void blkfit(BLKPTR p) +{ + uint8_t *pt = (uint8_t *)&p->word; + if (pt < (uint8_t *)brkend) + return; + setbrk(pt - (uint8_t *)brkend + sizeof(*p)); +} + void addblok(POS reqd) { + /* Expanding with a local stack in the way ? */ if (stakbas != staktop) { register STKPTR rndstak; register BLKPTR blokstak; + /* Add the stack to the memory pool */ pushstak(0); rndstak = (STKPTR) round(staktop, BYTESPERWORD); blokstak = BLK(stakbas) - 1; blokstak->word = stakbsy; stakbsy = blokstak; - bloktop->word = BLK(Rcheat(rndstak) | BUSY); + bloktop->word = BLK(((intptr_t)rndstak) | BUSY); bloktop = BLK(rndstak); } + /* Round up to a chunk boundary */ reqd += brkincr; reqd &= ~(brkincr - 1); + /* Adjust */ blokp = bloktop; - bloktop = bloktop->word = BLK(Rcheat(bloktop) + reqd); + blkfit(bloktop); + bloktop = bloktop->word = BLK(((intptr_t)(bloktop)) + reqd); + blkfit(bloktop); bloktop->word = BLK(ADR(end) + 1); { register STKPTR stakadr = STK(bloktop + 2); @@ -89,14 +132,20 @@ void addblok(POS reqd) void sh_free(void *ap) { - BLKPTR p; + BLKPTR p = ap; - if ((p = ap) && p < bloktop) - Lcheat((--p)->word) &= ~BUSY; + if (p && p < bloktop) { + /* Step back from data to header */ + p--; + /* Clear the busy bit */ + p->word = (BLKPTR)(((intptr_t)p->word) & ~BUSY); + if (p->word == p) + write(2, "freebad\n", 8); + } } #ifdef DEBUG -chkbptr(BLKPTR ptr) +void chkbptr(BLKPTR ptr) { int exf = 0; register BLKPTR p = end; @@ -104,7 +153,7 @@ chkbptr(BLKPTR ptr) int us = 0, un = 0; for (;;) { - q = Rcheat(p->word) & ~BUSY; + q = ((intptr_t)(p->word)) & ~BUSY; if (p == ptr) { exf++; } diff --git a/Applications/V7/cmd/sh/main.c b/Applications/V7/cmd/sh/main.c index 5fc039e0..6735fb90 100644 --- a/Applications/V7/cmd/sh/main.c +++ b/Applications/V7/cmd/sh/main.c @@ -192,3 +192,7 @@ void Ldup(register int fa, register int fb) close(fa); fcntl(fb, F_SETFD, FD_CLOEXEC); } + +void gratuitous_call(void) +{ +} diff --git a/Applications/V7/cmd/sh/mode.h b/Applications/V7/cmd/sh/mode.h index 2a459b5b..9a975cf0 100644 --- a/Applications/V7/cmd/sh/mode.h +++ b/Applications/V7/cmd/sh/mode.h @@ -49,7 +49,6 @@ typedef struct namnod *NAMPTR; * are necessary, one for each context. */ #define Lcheat(a) (*(int *)&(a)) -#define Rcheat(a) ((int)(a)) /* address puns for storage allocation */ -- 2.34.1