Radience on the HP 9000 / 700 fix

Radience on the HP 9000 / 700 fix

Post by knive.. » Wed, 25 Mar 1992 01:38:13



Hi All,

Just thought I'd pass this info on, thanks Eric and Greg

From g...@hobbes.lbl.gov Mon Mar 23 16:21:20 1992
Return-Path: <g...@hobbes.lbl.gov>
Received: from pobox.mot.com ([129.188.137.100]) by zeus.swindon.rtsg.mot.com (4.0/SMI-4.0)
        id AA22894; Mon, 23 Mar 92 16:21:16 GMT
Received: from motgate.mot.com ([129.188.136.100]) by pobox.mot.com (4.1/SMI-4.0)
        id AA19145; Mon, 23 Mar 92 10:16:18 CST
Received: from lbl.gov by motgate.mot.com (4.0/SMI-4.0)
        id AA25514; Mon, 23 Mar 92 10:16:14 CST
Received: from hobbes.lbl.gov by lbl.gov (4.1/1.39)
        id AA24457; Mon, 23 Mar 92 08:17:17 PST
Received: by hobbes.lbl.gov (3.2/SMI-3.2)
        id AA26475; Mon, 23 Mar 92 08:17:26 PST
Date: Mon, 23 Mar 92 08:17:26 PST
From: g...@hobbes.lbl.gov (Gregory J. Ward)
Message-Id: <9203231617.AA26475@hobbes.lbl.gov>
To: knive...@zeus.swindon.rtsg.mot.com
Subject: new malloc
Status: RO

Hi Andy,

Here is the new version of malloc.c.  The problem with the old version was
that the system call sbrk() doesn't return a word-aligned pointer on some
of the HP workstations!

-Greg

---------------
/* Copyright (c) 1992 Regents of the University of California */

#ifndef lint
static char SCCSid[] = "@(#)malloc.c 2.4 2/8/92 LBL";
#endif

/*
 * Fast malloc for memory hogs and VM environments.
 * Performs a minimum of searching through free lists.
 * malloc(), realloc() and free() use buckets
 *      containing blocks in powers of two, similar to CIT routines.
 * bfree() puts memory from any source into malloc free lists.
 * bmalloc() doesn't keep track of free lists -- it's usually
 *      just a buffered call to sbrk(2).  However, bmalloc will
 *      call mscrounge() if sbrk fails.
 * mscrounge() returns whatever free memory it can find to satisfy the
 *      request along with the number of bytes (modified).
 * mcompact() takes the same arguments as mscrounge() (and is in fact
 *      called by mscrounge() under dire circumstances), but it uses
 *      memory compaction to return a larger block.  (MCOMP)
 *
 *      Greg Ward       Lawrence Berkeley Laboratory
 */

#include  <errno.h>

#ifdef MSTATS
#include  <stdio.h>
static unsigned b_nsbrked = 0;
static unsigned b_nalloced = 0;
static unsigned b_nfreed = 0;
static unsigned b_nscrounged = 0;
static unsigned b_ncompacted = 0;
static unsigned m_nalloced = 0;
static unsigned m_nfreed = 0;
static unsigned m_nwasted = 0;
#else
#define  NULL           0
#endif

#ifndef ALIGN
#define  ALIGN          int                     /* align type */
#endif
#define  BYTES_WORD     sizeof(ALIGN)

#ifndef  MAXINCR
#define  MAXINCR        (1<<16)                   /* largest sbrk(2) increment */
#endif
                                        /* malloc free lists */
typedef union m_head {
        union m_head    *next;
        struct {
                short           magic;
                short           bucket;
        }       a;
        ALIGN           dummy;

} M_HEAD;

#define MAGIC           0x1a2           /* magic number for allocated memory */

#define FIRSTBUCKET     3
#define NBUCKETS        30

static M_HEAD   *free_list[NBUCKETS];

static ALIGN    dummy_mem;

#define DUMMYLOC        ((char *)&dummy_mem)

#ifdef  MCOMP                   /* memory compaction routines */
static char     seedtab[1024];          /* seed for compaction table */

static struct mblk {
        char            *ptr;   /* pointer to memory block */
        unsigned        siz;    /* size of memory block */

}       cptab = {seedtab, sizeof(seedtab)};

#define mtab(mb)        ((struct mblk *)(mb)->ptr)
#define mtablen(mb)     ((mb)->siz/sizeof(struct mblk))

static int
mbcmp(m1, m2)           /* compare memory block locations */
register struct mblk    *m1, *m2;
{
                                /* put empty blocks at end */
        if (m1->siz == 0)
                return(m2->siz == 0 ? 0 : 1);
        if (m2->siz == 0)
                return(-1);
                                /* otherwise, ascending order */
        return(m1->ptr - m2->ptr);

}

int
compactfree()           /* compact free lists (moving to table) */
{
        register struct mblk    *tp;
        register int    bucket;
        unsigned        n, bsiz, ncomp;
                                /* fill table from free lists */
        tp = mtab(&cptab); n = mtablen(&cptab);
        bucket = NBUCKETS-1; bsiz = 1<<(NBUCKETS-1);
        ncomp = 0;
        for ( ; ; ) {
                while (tp->siz) {    /* find empty slot */
                        if (--n == 0)
                                goto loopexit;
                        tp++;
                }
                while (free_list[bucket] == NULL) {     /* find block */
                        if (--bucket < FIRSTBUCKET)
                                goto loopexit;
                        bsiz >>= 1;
                }
                tp->ptr = (char *)free_list[bucket];
                ncomp += (tp->siz = bsiz + sizeof(M_HEAD));
                free_list[bucket] = free_list[bucket]->next;
        }
loopexit:
        if (ncomp == 0)
                return(0);              /* nothing new to compact */
#ifdef MSTATS
        b_ncompacted += ncomp;
#endif
        tp = mtab(&cptab); n = mtablen(&cptab);         /* sort table */
        qsort((char *)tp, n, sizeof(struct mblk), mbcmp);
        ncomp = 0;                                      /* collect blocks */
        while (--n && tp[1].siz) {
                if (tp[0].ptr + tp[0].siz == tp[1].ptr) {
                        tp[1].ptr = tp[0].ptr;
                        tp[1].siz += tp[0].siz;
                        ncomp += tp[0].siz;
                        tp[0].siz = 0;
                }
                tp++;
        }
        return(ncomp);

}

char *
mcompact(np)            /* compact free lists to satisfy request */
unsigned        *np;
{
        struct mblk     *tab;
        unsigned        tablen;
        register struct mblk    *bp, *big;

        for ( ; ; ) {
                                        /* compact free lists */
                compactfree();
                                        /* find largest block */
                tab = mtab(&cptab); tablen = mtablen(&cptab);
                big = tab;
                bp = tab + tablen;
                while (--bp > tab)
                        if (bp->siz > big->siz)
                                big = bp;
                if (big->siz >= *np) {            /* big enough? */
                        *np = big->siz;
                        big->siz = 0;                /* remove from table */
                        return(big->ptr);    /* return it */
                }
                if (mtablen(big) < tablen+1) {
                        *np = 0;                /* cannot grow table */
                        return(NULL);           /* report failure */
                }
                                /* enlarge table, free old one */
                mtab(big)[0].ptr = cptab.ptr;
                mtab(big)[0].siz = cptab.siz;
                cptab.ptr = big->ptr;
                cptab.siz = big->siz;
                big->siz = 0;                        /* clear and copy */
#ifdef BSD
                bcopy((char *)tab, (char *)(mtab(&cptab)+1),
                                tablen*sizeof(struct mblk));
                bzero((char *)(mtab(&cptab)+tablen+1),
                        (mtablen(&cptab)-tablen-1)*sizeof(struct mblk));
#else
                (void)memcpy((char *)(mtab(&cptab)+1), (char *)tab,
                                tablen*sizeof(struct mblk));
                memset((char *)(mtab(&cptab)+tablen+1), 0,
                        (mtablen(&cptab)-tablen-1)*sizeof(struct mblk));
#endif
        }                       /* next round */

}

#endif          /* MCOMP */

char *
mscrounge(np)           /* search free lists to satisfy request */
register unsigned       *np;
{
        char    *p;
        register int    bucket;
        register unsigned       bsiz;

        for (bucket = FIRSTBUCKET, bsiz = 1<<FIRSTBUCKET;
                        bucket < NBUCKETS; bucket++, bsiz <<= 1)
                if (free_list[bucket] != NULL && bsiz+sizeof(M_HEAD) >= *np) {
                        *np = bsiz+sizeof(M_HEAD);
                        p = (char *)free_list[bucket];
                        free_list[bucket] = free_list[bucket]->next;
#ifdef MSTATS
                        b_nscrounged += *np;
#endif
                        return(p);
                }
#ifdef MCOMP
        return(mcompact(np));           /* try compaction */
#else
        *np = 0;
        return(NULL);
#endif

}

char *
bmalloc(n)              /* allocate a block of n bytes, sans header */
register unsigned  n;
{
        extern char  *sbrk();
        static unsigned  pagesz = 0;
        static unsigned  amnt;
        static char  *bpos;
        static unsigned  nrem;
        unsigned  thisamnt;
        register char   *p;

        if (pagesz == 0) {                              /* initialize */
                pagesz = amnt = getpagesize();
                nrem = (int)sbrk(0);                    /* page align break */
                nrem = pagesz - (nrem&(pagesz-1));
                bpos = sbrk(nrem);
                if ((int)bpos == -1)
                        return(NULL);
#ifdef MSTATS
                b_nsbrked += nrem;
#endif
                bpos += nrem & (BYTES_WORD-1);              /* align pointer */
                nrem &= ~(BYTES_WORD-1);
        }

        n = (n+(BYTES_WORD-1))&~(BYTES_WORD-1);             /* word align rqst. */

        if (n > nrem) {                                      /* need more core */
                if (n > amnt) {                              /* big chunk */
                        thisamnt = (n+(pagesz-1))&~(pagesz-1);
                        if (thisamnt <= MAXINCR)     /* increase amnt */
                                amnt = thisamnt;
                } else
                        thisamnt = amnt;
                p = sbrk(thisamnt);
                if ((int)p == -1) {                     /* uh-oh, ENOMEM */
                        thisamnt = n;                   /* search free lists */
                        p = mscrounge(&thisamnt);
                        if (p == NULL)                  /* we're really out */
                                return(NULL);
                }
#ifdef MSTATS
                else b_nsbrked += thisamnt;
#endif
                if (p != bpos+nrem) {                   /* not an increment */
                        bfree(bpos, nrem);              /* free what we have */
                        bpos = p;
                        nrem = thisamnt;
                } else                                  /* otherwise tack on */
                        nrem += thisamnt;
        }
        p = bpos;
        bpos += n;                                      /* advance */
        nrem -= n;
#ifdef MSTATS
        b_nalloced += n;
#endif
        return(p);

}

bfree(p, n)                     /* free n bytes of random memory */
register char  *p;
register unsigned  n;
{
        register int    bucket;
        register unsigned       bsiz;

        if (n < 1<<FIRSTBUCKET)
                return;
#ifdef MSTATS
        b_nfreed += n;
#endif
                                        /* align pointer */
        bsiz = BYTES_WORD - ((unsigned)p&(BYTES_WORD-1));
        if (bsiz < BYTES_WORD) {
                p += bsiz;
                n -= bsiz;
        }
                                        /* fill big buckets first */
        for (bucket = NBUCKETS-1, bsiz = 1<<(NBUCKETS-1);
                        bucket >= FIRSTBUCKET; bucket--, bsiz >>= 1)
                if (n >= bsiz+sizeof(M_HEAD)) {
                        ((M_HEAD *)p)->next = free_list[bucket];
                        free_list[bucket] = (M_HEAD *)p;
                        p += bsiz+sizeof(M_HEAD);
                        n -= bsiz+sizeof(M_HEAD);
                }

}

char *
malloc(n)                       /* allocate n bytes of memory */
unsigned        n;
{
        extern int  errno;
        register M_HEAD *mp;
        register int    bucket;
        register unsigned       bsiz;
                                        /* don't return NULL on 0 request */
        if (n == 0)
                return(DUMMYLOC);
                                        /* find first bucket that fits */
        for (bucket = FIRSTBUCKET, bsiz = 1<<FIRSTBUCKET;
                        bucket < NBUCKETS; bucket++, bsiz <<= 1)
                if (bsiz >= n)
                        break;
        if (bucket >= NBUCKETS) {
                errno = EINVAL;
                return(NULL);
        }
        if (free_list[bucket] == NULL) {        /* need more core */
                mp = (M_HEAD *)bmalloc(bsiz+sizeof(M_HEAD));
                if (mp == NULL)
                        return(NULL);
        } else {                                /* got it */
                mp = free_list[bucket];
                free_list[bucket] = mp->next;
        }
#ifdef MSTATS
        m_nalloced += bsiz + sizeof(M_HEAD);
        m_nwasted += bsiz + sizeof(M_HEAD) - n;
#endif
        mp->a.magic = MAGIC;                 /* tag block */
        mp->a.bucket = bucket;
        return((char *)(mp+1));

}

char *
realloc(op, n)                  /* reallocate memory using malloc() */
register char   *op;
unsigned        n;
{
        char    *p;
        register unsigned       on;
                                        /* get old size */
        if (op != NULL && op != DUMMYLOC && ((M_HEAD *)op-1)->a.magic == MAGIC)
                on = 1 << ((M_HEAD *)op-1)->a.bucket;
        else
                on = 0;
        if (n <= on && (n > on>>1 || on == 1<<FIRSTBUCKET))
                return(op);             /* same bucket */
        if ((p = malloc(n)) == NULL)
                return(NULL);
        if (on) {
#ifdef  BSD
                bcopy(op, p, n>on ? on : n);
#else
                (void)memcpy(p, op, n>on ? on : n);
#endif
                free(op);
        }
        return(p);

}

free(p)                 /* free memory allocated by malloc */
char    *p;
{
        register M_HEAD *mp;
        register int    bucket;

        if (p == NULL | p == DUMMYLOC)
                return(1);
        mp = (M_HEAD *)p - 1;
        if (mp->a.magic != MAGIC)            /* sanity check */
                return(0);
        bucket = mp->a.bucket;
        if (bucket < FIRSTBUCKET | bucket >= NBUCKETS)
                return(0);
        mp->next = free_list[bucket];
        free_list[bucket] = mp;
#ifdef MSTATS
        m_nfreed += (1 << bucket) + sizeof(M_HEAD);
#endif
        return(1);

}

#ifdef MSTATS
printmemstats(fp)               /* print memory statistics to stream */
FILE    *fp;
{
        register int    i;
        int     n;
        register M_HEAD *mp;
        unsigned int    total = 0;

        fprintf(fp, "Memory statistics:\n");
        fprintf(fp, "\tbmalloc: %d bytes from sbrk\n", b_nsbrked);
        fprintf(fp, "\tbmalloc: %d bytes allocated\n", b_nalloced);
        fprintf(fp, "\tbmalloc: %d bytes freed\n", b_nfreed);
        fprintf(fp, "\tbmalloc: %d bytes scrounged\n", b_nscrounged);
        fprintf(fp, "\tbmalloc: %d bytes compacted\n", b_ncompacted);
        fprintf(fp, "\tmalloc: %d bytes allocated\n", m_nalloced);
        fprintf(fp, "\tmalloc: %d bytes wasted (%.1f%%)\n", m_nwasted,
                        100.0*m_nwasted/m_nalloced);
        fprintf(fp, "\tmalloc: %d bytes freed\n", m_nfreed);
        for (i = NBUCKETS-1; i >= FIRSTBUCKET; i--) {
                n = 0;
                for (mp = free_list[i]; mp != NULL; mp = mp->next)
                        n++;
                if (n) {
                        fprintf(fp, "\t%d * %u\n", n, 1<<i);
                        total += n * ((1<<i) + sizeof(M_HEAD));
                }
        }
        fprintf(fp, "\t %u total bytes in free list\n", total);

}

#endif

Andy.
--
  _ _ /|        Andy Kniveton,  Tel No  +44 793 545349
  \'o.O'        Motorola Ltd,   Fax No  +44 793 541228
  =(___)=       16 Euro Way,    E-mail  knive...@zeus.swindon.rtsg.mot.com
     U          Blagrove, Swindon,      uunet!motcid!zeus!kniveton
                England, SN5 8YW.

 
 
 

1. Radience on HP 9000 / 700

Has anyone compiled Radience 2 on the Hp 9000 / 700 range of machines, I'm using
the following in rmake :-

#!/bin/sh
exec make "SPECIAL=tiff" \
        "OPT=" \
        "MACH=-DALIGN=double -DBIGMEM" \
        ARCH=hpux "COMPAT=malloc.o getpagesize.o" \
        INSTDIR=/usr/local/bin \

When I run make daf from the ray/obj/misc directory I got the following :-

/home/ouse/kniveton/compile/ray/obj/misc>>make daf
        oconv daffodil.xf room > daf.oct
        rview -o x11 -vp 50 60 40 -vd 0 -0.707107 -0.707107 -vu 0 1 0 \
        -vh 20 -vv 20 -av .2 .2 .2 daf.oct
sh: 18221 Bus error - core dumped
*** Error code 138

Stop.

Anyone got any ideas ?

Cheers Andy.
--
  _ _ /|        Andy Kniveton,  Tel No  +44 793 545349
  \'o.O'        Motorola Ltd,   Fax No  +44 793 541228

     U          Blagrove, Swindon,      uunet!motcid!zeus!kniveton
                England, SN5 8YW.

2. PCL ( HP LaserJet 3/4 ) to bmp/wmf/gif/tiff (anything!)

3. HP 9000 Screen Dump to HP Laser printer

4. Convert SFF <-> BMP

5. Producing Movies from an HP 9000/730

6. Advice requested

7. Graphics Packages for HP 9000 series

8. Animation Festival web site

9. Graphics animation to video tape for HP 9000

10. xdart.1.0 available for HP 9000/710 (Snake)

11. Versatec C2700 Color Plotter to HP 9000/800

12. Graphics on an HP-9000 with TEK-4115A

13. GLUT on an HP 9000?