X-Authentication-Warning: delorie.com: mail set sender to djgpp-workers-bounces using -f Date: Wed, 26 Nov 2003 10:52:41 +0200 (EET) From: Esa A E Peuha Sender: peuha AT sirppi DOT helsinki DOT fi To: djgpp-workers AT delorie DOT com Subject: New nmalloc patch Message-ID: MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII Reply-To: djgpp-workers AT delorie DOT com Below is a new patch to nmalloc. It makes memalign fully functional (now it searches free blocks for possible matches; it still walks the free chains, which might reslut in poor performance, but that should be easy to change if needed). The patch also fixes some bugs in memalign and one in size2bucket. --- nmalloc.c_o Thu Jun 26 17:19:16 2003 +++ nmalloc.c Tue Nov 25 20:05:14 2003 @@ -379,7 +379,7 @@ { int b; - for (b = 0; sz; sz >>= 1, b++) continue; + for (b = -1; sz; sz >>= 1, b++) continue; return b; } /* size2bucket */ @@ -514,7 +514,6 @@ m->nextfree = NONE; } m->prevfree = NONE; - if (freehdrs[b]) freehdrs[b]->prevfree = m; freehdrs[b] = m; DBGPRT(EOL " Exit mv2freelist"); } @@ -588,7 +587,7 @@ m = *mp; m1 = (memblockp)((char *)m + sz); - if (m->sz < (sz + DATAOFFSET)) { + if ((sz < MINSAVE) || (m->sz < (sz + MINSAVE))) { badcallabort("memblockpsz", 11, m); exit(EXIT_FAILURE); /* prevent user trapping SIGABRT */ } @@ -1029,10 +1028,11 @@ { ulong mb, mlen, mtry; - mb = (ulong)(char *)m; mlen = m->sz; + mb = (ulong)m; mlen = m->sz; + if (mlen < size) return 0; /* too small, exit early */ if (0 == ((mtry = mb + DATAOFFSET) & alignmask)) return mb; /* miracles happen, exact fit */ - mtry = (mtry + MINSAVE + alignmask) & (alignmask+1); + mtry = (mtry + MINSAVE + alignmask) & ~alignmask; mtry = mtry - DATAOFFSET; if ((size + (mtry - mb)) <= mlen) return mtry; else return 0; @@ -1048,7 +1048,7 @@ ulong mtry; m = freehdrs[b]; *m1p = NULL; - while ((m = freehdrs[b]) && (m != NONE)) { + while (m && (m != NONE)) { if ((mtry = suitable(m, size, alignmsk))) { *m1p = m; return mtry; @@ -1103,8 +1103,28 @@ szneed = roundup(size); m = searchblock(szneed, alignmask, &m1); if (m) { - /* parcel out m1. m is block to return */ - /* FAILS for now */ + extractfree(m1); + if (m != m1) { + /* parcel out m1. m is block to return */ + memcpy(m, m1, DATAOFFSET); + m1->sz = (ulong)m - (ulong)m1; + m->sz -= (ulong)m - (ulong)m1; + m1->next = m; + m->prev = m1; + if (m->next) { + if (m->next->prev != m1) { + badcallabort("memblockpnxt", 12, m); + exit(EXIT_FAILURE); /* prevent user trapping SIGABRT */ + } + m->next->prev = m; + } + mv2freelist(m1); + } + if (m->sz >= szneed + MINSAVE) { + m1 = split(&m, szneed); + mv2freelist(m); + m = m1; + } } else { /* we have to use lastsbrk etc. */ @@ -1113,30 +1133,35 @@ block. Then make the assignment from lastsbrk. */ do { - sbrkxtra = ((ulong)lastsbrk + alignmask) - & alignmask; - if (sbrkxtra < DATAOFFSET) + sbrkxtra = alignment - ((ulong)lastsbrk & alignmask); + while (sbrkxtra < DATAOFFSET) sbrkxtra += alignment; + if (sbrkxtra > DATAOFFSET) + while (sbrkxtra < MINSAVE + DATAOFFSET) + sbrkxtra += alignment; m1 = lastsbrk; m = extendsbrk(sbrkxtra + szneed); } while ((m != m1) && m); /* extendsbrk has put any shards in the free list */ /* The loop takes care of unexpected sbrk returns */ if (m) { - /* m + szbrkxtra - DATAOFFSET will now point to + /* m + sbrkxtra - DATAOFFSET will now point to a block sufficient to satisfy memalign. The - returned value will be at m + szbrkxtra. The - block at m, length szbrkxtra, will be put in + returned value will be at m + sbrkxtra. The + block at m, length sbrkxtra, will be put in the free lists. This call will succeed. */ - m1 = split(&lastsbrk, sbrkxtra - DATAOFFSET); + if ((sbrkxtra == DATAOFFSET)) + m1 = NULL; + else + m1 = split(&lastsbrk, sbrkxtra - DATAOFFSET); /* leaving m1 marked non-free, and lastsbrk suitable for the memalign call. We can't - just move m to the freelist, because it + just move m1 to the freelist, because it would immediately recombine with lastsbrk */ m = split(&lastsbrk, szneed); - dofree(m1); /* now the m block is non-free */ + if (m1) dofree(m1); /* now the m block is non-free */ } /* success */ } /* getting from lastsbrk */ } /* alignment > ALIGN */ -- Esa Peuha student of mathematics at the University of Helsinki http://www.helsinki.fi/~peuha/