[comp.os.xinu] sun3, version 6 bug and fix

sdo@PURDUE.EDU (02/10/88)

There is a problem with the way the version of Xinu 6 for the Sun
3 manages the heap and stack space.  The original version used the
routines roundew() and truncew() to insure that all requests for heap
space were rounded up to a multiple of the size of the mblock
structure that was used to keep track of the free blocks.  This
insures that when the blocks are returned to the heap, there is at
least enough room in them to overlay the mblock structure onto them
and chain the block into the free list.  It also insured that there
could be no unusable blocks on the list, since you could never remove
part of a block, and have a piece left that was smaller than the
mblock structure.

Unfortunately, the macros which served this purpose had the size of
the structure compiled in:

>   ORIGINAL mem.h include file...
>
> /* mem.h - freestk, roundew, truncew */
> 
> /*----------------------------------------------------------------------
>  * roundew, truncew - round or truncate address to next even word
>  *----------------------------------------------------------------------
>  */
> #define	roundew(x)	(int *)( (3 + (int)(x)) & (~3) )
> #define	truncew(x)	(int *)( ((int)(x)) & (~3) )
> 
>  ...
>  
> struct	mblock	{
> 	struct	mblock	*mnext;
> 	unsigned int	mlen;
> 	};
> 
>  ...
On the LSI, the mblock structure took 4 bytes, on the Sun 3 (and most
other "large" machines), it takes 8.

The suggested fix is to:
1) rewrite these routines so that they use the larger structure size.
2) change the names so that it is more obvious what they do
3) change the routines that use them.

Of course, you can argue that the macros should use "sizeof(struct mblock)"
rather that the constant 8 for the size.  The problem with this, for
me, is one of inefficiency.  There are some machines, so I am told,
that use 4 byte pointers, and 2 byte integers.  On such a machine, the
math needed to round up to 6 bytes seems like too much overhead.
Using a size of 8 rather than 6 would still work, however.

The change to mem.h is as follows:
> ADD THE FOLLOWING TO mem.h
>
> /*----------------------------------------------------------------------
>  * roundmb, truncmb -- round or truncate address up to size of mblock
>  *----------------------------------------------------------------------
>  */
> #define	roundmb(x)	(WORD *)( (7 + (WORD)(x)) & ~07 )
> #define	truncmb(x)	(WORD *)( ((WORD)(x)) & ~07 )

Each of the following files contains a single reference to roundew()
that needs to be changed to roundmb():
    create.c:	    ssize = (int) roundmb(ssize);
    freemem.c:	    size = (unsigned)roundmb(size);
    getmem.c:	    nbytes = (unsigned int) roundmb(nbytes);
    getstk.c:	    nbytes = (unsigned int) roundmb(nbytes);
    initialize.c:	  (struct mblock *) roundmb(&end);


The following file contains a single reference to truncew()
that needs to be changed to truncmb():
    initialize.c:	mptr->mlen = (int) truncmb((unsigned)maxaddr

To: info-xinu
cc: sdo
Subject: sun3, version 6 bug and fix
--------


There is a problem with the way the version of Xinu 6 for the Sun
3 manages the heap and stack space.  The original version used the
routines roundew() and truncew() to insure that all requests for heap
space were rounded up to a multiple of the size of the mblock
structure that was used to keep track of the free blocks.  This
insures that when the blocks are returned to the heap, there is at
least enough room in them to overlay the mblock structure onto them
and chain the block into the free list.  It also insured that there
could be no unusable blocks on the list, since you could never remove
part of a block, and have a piece left that was smaller than the
mblock structure.

Unfortunately, the macros which served this purpose had the size of
the structure compiled in:

>   ORIGINAL mem.h include file...
>
> /* mem.h - freestk, roundew, truncew */
> 
> /*----------------------------------------------------------------------
>  * roundew, truncew - round or truncate address to next even word
>  *----------------------------------------------------------------------
>  */
> #define	roundew(x)	(int *)( (3 + (int)(x)) & (~3) )
> #define	truncew(x)	(int *)( ((int)(x)) & (~3) )
> 
>  ...
>  
> struct	mblock	{
> 	struct	mblock	*mnext;
> 	unsigned int	mlen;
> 	};
> 
>  ...
On the LSI, the mblock structure took 4 bytes, on the Sun 3 (and most
other "large" machines), it takes 8.

The suggested fix is to:
1) rewrite these routines so that they use the larger structure size.
2) change the names so that it is more obvious what they do
3) change the routines that use them.

Of course, you can argue that the macros should use "sizeof(struct mblock)"
rather that the constant 8 for the size.  The problem with this, for
me, is one of inefficiency.  There are some machines, so I am told,
that use 4 byte pointers, and 2 byte integers.  On such a machine, the
math needed to round up to 6 bytes seems like too much overhead.
Using a size of 8 rather than 6 would still work, however.

The change to mem.h is as follows:
> ADD THE FOLLOWING TO mem.h
>
> /*----------------------------------------------------------------------
>  * roundmb, truncmb -- round or truncate address up to size of mblock
>  *----------------------------------------------------------------------
>  */
> #define	roundmb(x)	(WORD *)( (7 + (WORD)(x)) & ~07 )
> #define	truncmb(x)	(WORD *)( ((WORD)(x)) & ~07 )

Each of the following files contains a single reference to roundew()
that needs to be changed to roundmb():
    create.c:	    ssize = (int) roundmb(ssize);
    freemem.c:	    size = (unsigned)roundmb(size);
    getmem.c:	    nbytes = (unsigned int) roundmb(nbytes);
    getstk.c:	    nbytes = (unsigned int) roundmb(nbytes);
    initialize.c:	  (struct mblock *) roundmb(&end);


The following file contains a single reference to truncew()
that needs to be changed to truncmb():
    initialize.c:	mptr->mlen = (int) truncmb((unsigned)maxaddr


Thanks to David Schulz at Bell Labs for running his "turture tests" on
the Sun 3 Xinu code and finding this bug for me.  


Shawn

-----------------------------------------------------------------------------
Shawn Ostermann        ARPA:  sdo@gwen.cs.purdue.edu
                       UUCP:  ...!purdue!sdo
-----------------------------------------------------------------------------