Welcome to Web-News
A Web-based News Reader
Subject I am beginning to lose trust in my ability to code straight.
From downs <default_357-line@yahoo.de>
Date Wed, 25 Jun 2008 19:17:29 +0200
Newsgroups digitalmars.D
Attachment(s) phobos_gc_constant_time_removeRange.patch

Aaaand another one!

This time, it's a race condition.

When two threads try to removeRange at the same time, the position of a Range might change before the lock is engaged.

Fixed by passing the index by reference until inside the sync block.



diff -Nur --exclude aaA.d --exclude math.d dgcc/d/phobos/internal/gc/gc.d gcc-4.2.4/gcc/d/phobos/internal/gc/gc.d
--- dgcc/d/phobos/internal/gc/gc.d        2008-03-07 16:55:56.000000000 +0100
+++ gcc-4.2.4/gcc/d/phobos/internal/gc/gc.d        2008-06-25 19:10:37.000000000 +0200
@@ -56,8 +56,11 @@

void addRoot(void *p)                      { _gc.addRoot(p); }
void removeRoot(void *p)              { _gc.removeRoot(p); }
-void addRange(void *pbot, void *ptop) { _gc.addRange(pbot, ptop); }
+void addRange(void *pbot, void *ptop, size_t* target = null) {
+  _gc.addRange(pbot, ptop, target);
+}
void removeRange(void *pbot)              { _gc.removeRange(pbot); }
+void removeRange(ref size_t index)        { _gc.removeRange(index); }
void fullCollect()                      { _gc.fullCollect(); }
void fullCollectNoStack()              { _gc.fullCollectNoStack(); }
void genCollect()                      { _gc.genCollect(); }
diff -Nur --exclude aaA.d --exclude math.d dgcc/d/phobos/internal/gc/gcx.d gcc-4.2.4/gcc/d/phobos/internal/gc/gcx.d
--- dgcc/d/phobos/internal/gc/gcx.d        2008-06-18 19:36:26.000000000 +0200
+++ gcc-4.2.4/gcc/d/phobos/internal/gc/gcx.d        2008-06-25 19:11:14.000000000 +0200
@@ -966,7 +970,7 @@
     /**
      * add range to scan for roots
      */
-    void addRange(void *pbot, void *ptop)
+    void addRange(void *pbot, void *ptop, size_t* target = null)
     {
         if (!pbot || !ptop)
         {
@@ -976,11 +980,11 @@
        //debug(PRINTF) printf("+GC.addRange(pbot = x%x, ptop = x%x)\n", pbot, ptop);
         if (!thread_needLock())
         {
-            gcx.addRange(pbot, ptop);
+            gcx.addRange(pbot, ptop, target);
         }
         else synchronized (gcLock)
        {
-            gcx.addRange(pbot, ptop);
+            gcx.addRange(pbot, ptop, target);
        }
        //debug(PRINTF) printf("-GC.addRange()\n");
     }
@@ -1006,6 +1010,20 @@
        }
     }

+    /**
+     * remove range with index
+     */
+    void removeRange(ref size_t index)
+    {
+        if (!thread_needLock())
+        {
+            gcx.removeRange(index);
+        }
+        else synchronized (gcLock)
+        {
+            gcx.removeRange(index);
+        }
+    }

     /**
      * do full garbage collection
@@ -1211,6 +1229,7 @@

struct Range
{
+    size_t* target;
     void *pbot;
     void *ptop;
}
@@ -1417,7 +1436,7 @@
     /**
      *
      */
-    void addRange(void *pbot, void *ptop)
+    void addRange(void *pbot, void *ptop, size_t* target = null)
     {
        debug(THREADINVARIANT) { debug(PRINTF) printf("Thread %x ", pthread_self()); }
        debug(PRINTF) printf("%x.Gcx::addRange(%x, %x), nranges = %d\n", this, pbot, ptop, nranges);
@@ -1438,7 +1457,9 @@
        }
        ranges[nranges].pbot = pbot;
        ranges[nranges].ptop = ptop;
-        nranges++;
+        ranges[nranges].target = target;
+        if (target) *target = nranges;
+        nranges ++;
     }


@@ -1453,8 +1474,9 @@
        {
            if (ranges[i].pbot == pbot)
            {
-                nranges--;
-                cstring.memmove(ranges + i, ranges + i + 1, (nranges - i) * ranges[0].sizeof);
+                /*nranges--;
+                cstring.memmove(ranges + i, ranges + i + 1, (nranges - i) * ranges[0].sizeof);*/
+                removeRange(i);
                return;
            }
        }
@@ -1466,6 +1488,18 @@
        //assert(zero);
     }

+    void removeRange(size_t index) {
+        debug(PRINTF) printf("%x.Gcx.removeRange(%d), nranges=%d\n", this, index, nranges);
+        if (index !< nranges)
+            throw new Exception("removeRange: No such index!");
+        if (index < nranges - 1) {
+            ranges[index] = ranges[nranges - 1];
+            if (ranges[index].target)
+                *ranges[index].target = index;
+        }
+        nranges--;
+    }
+

     /**
      * Find Pool that pointer is in.
diff -Nur --exclude aaA.d --exclude math.d dgcc/d/phobos/std/gc.d gcc-4.2.4/gcc/d/phobos/std/gc.d
--- dgcc/d/phobos/std/gc.d        2007-10-16 21:02:09.000000000 +0200
+++ gcc-4.2.4/gcc/d/phobos/std/gc.d        2008-06-25 19:12:01.000000000 +0200
@@ -52,12 +52,13 @@
/**
  * Add range to scan for roots.
  */
-void addRange(void *pbot, void *ptop);        // add range to scan for roots
+void addRange(void *pbot, void *ptop, size_t* target = null);

/**
  * Remove range.
  */
void removeRange(void *pbot);                // remove range
+void removeRange(ref size_t index);                // remove range by index

/**
  * Mark a gc allocated block of memory as possibly containing pointers.


Recent messages in this thread
 
-# Feature Req.+Patch: O(1) removeRange downs 25-Jun-2008 12:10 pm
.-# Fixed patch downs 25-Jun-2008 12:16 pm
..-# Test your patches before posting! :/ downs 25-Jun-2008 01:02 pm
...-# I am beginning to lose trust in my ability to code straight. (Current message) downs 25-Jun-2008 01:17 pm
....|# Re: I am beginning to lose trust in my ability to code straight. Nick Sabalausky 25-Jun-2008 02:44 pm
....|# Re: I am beginning to lose trust in my ability to code straight. Jarrett Billingsley 25-Jun-2008 11:20 pm
....\# downs' removeRange patches (Was: I am beginning to lose trust in my ability to code s... Tom S 28-Jun-2008 12:21 pm