www.delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp-workers/2003/11/26/09:14:04

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 <peuha AT cc DOT helsinki DOT fi>
Sender: peuha AT sirppi DOT helsinki DOT fi
To: djgpp-workers AT delorie DOT com
Subject: New nmalloc patch
Message-ID: <Pine.OSF.4.58.0311261044070.24147@sirppi.helsinki.fi>
MIME-Version: 1.0
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/

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019