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 -----------------------------------------------------------------------------