Mail Archives: djgpp-workers/2002/02/11/17:54:26
Charles Sandmann wrote:
>> Since malloc rounds the size to a multiple of 8 bytes, the rest should be
>> fine as long as we get contiguous memory. Whenever we get noncontiguous
>> chunk, we can again align its beginning and continue.
>
> Agreed. (This is all in one place - probably 2-3 lines of code).
Here is a patch that seemed to work (though I've only given it a cursory
test). Please take a look at it and see whether I have made a mistake:
*** src/libc/ansi/stdlib/malloc.old Fri Aug 20 18:46:58 1999
--- src/libc/ansi/stdlib/malloc.c Mon Feb 11 16:05:02 2002
***************
*** 20,25 ****
--- 20,26 ----
#define NUMSMALL 0
#define ALIGN 8
+ #define ALIGN1 (ALIGN-1)
#define SMALL (NUMSMALL*ALIGN)
static BLOCK *slop = 0;
***************
*** 192,203 ****
}
chunk_size = size+16; /* two ends plus two placeholders */
! rv = (BLOCK *)sbrk(chunk_size);
if (rv == (BLOCK *)(-1))
return 0;
#if DEBUG
printf("sbrk(%d) -> %08x, expected %08x\n", chunk_size, rv,
expected_sbrk);
#endif
if (rv == expected_sbrk)
{
expected_sbrk = (BLOCK *)((char *)rv + chunk_size);
--- 193,208 ----
}
chunk_size = size+16; /* two ends plus two placeholders */
!
! /* Ask sbrk() for ALIGN1 extra bytes, to allow for possible alignment. */
!
! rv = (BLOCK *)sbrk(chunk_size+ALIGN1);
if (rv == (BLOCK *)(-1))
return 0;
#if DEBUG
printf("sbrk(%d) -> %08x, expected %08x\n", chunk_size, rv,
expected_sbrk);
#endif
+ rv = (BLOCK *) (((int)rv + ALIGN1) & ~ALIGN1); /* Align the pointer. */
if (rv == expected_sbrk)
{
expected_sbrk = (BLOCK *)((char *)rv + chunk_size);
> Another idea:
>
> We could add a sbrk(0) call before calling sbrk() with the expected size -
> and if it's aligned the sbrk() value should be also. If sbrk(0) not
> aligned, we sbrk() the small number of bytes to align - which will always
> work (unless there's a equality bug right at the boundary in sbrk...)
It seemed to me that simply keeping sbrk() at least 7 bytes ahead of the
expected end of the region was simpler and safer. I don't know whether there
are people doing multi-threaded stuff out there, but if they are, I fear that
sbrk() could get called with some bad (size % 8 != 0) value between the two
times it is called in the above scheme. Or is malloc() inherently
non-re-entrant?
> By the way, I think the reason we are off by 4 is stubinfo is 0x54 bytes
> and it's the very first thing we sbrk() :-P
Aha! However, I think that forcing malloc() to work with non-aligned sbrk()
values is a better solution than requiring alignment from stubinfo, since it
makes the code less intertwined.
-Eric
- Raw text -