[pypy-commit] stmgc default: Next test: link again all tx_descriptors in a chained list (duh, and I

arigo noreply at buildbot.pypy.org
Mon Jun 17 17:42:00 CEST 2013


Author: Armin Rigo <arigo at tunes.org>
Branch: 
Changeset: r175:1a57a7dfd909
Date: 2013-06-17 17:41 +0200
http://bitbucket.org/pypy/stmgc/changeset/1a57a7dfd909/

Log:	Next test: link again all tx_descriptors in a chained list (duh, and
	I still cannot get chained list manipulations bug-free the first
	time)

diff --git a/c4/et.c b/c4/et.c
--- a/c4/et.c
+++ b/c4/et.c
@@ -1049,7 +1049,7 @@
         }
       else
         {
-          stm_free(B, stmcb_size(B));
+          stmgcpage_free(B);
           fprintf(stderr, "commit: free backup at %p\n", B);
         }
     };
@@ -1096,7 +1096,7 @@
                  ((char *)B) + offsetof(struct stm_object_s, h_revision),
                  size - offsetof(struct stm_object_s, h_revision));
           assert(!(P->h_tid & GCFLAG_BACKUP_COPY));
-          stm_free(B, size);
+          stmgcpage_free(B);
           fprintf(stderr, "abort: free backup at %p\n", B);
         }
     };
@@ -1342,6 +1342,7 @@
 
 /************************************************************/
 
+struct tx_descriptor *stm_tx_head = NULL;
 struct tx_public_descriptor *stm_descriptor_array[MAX_THREADS] = {0};
 static revision_t descriptor_array_free_list = 0;
 
@@ -1352,17 +1353,20 @@
   assert(thread_descriptor == NULL);
   memset(stm_descriptor_array, 0, sizeof(stm_descriptor_array));
   descriptor_array_free_list = 0;
-  stmgcpage_count(2);
+  stm_tx_head = NULL;
+  stmgcpage_count(2);  /* reset */
 }
 
-struct tx_public_descriptor *stm_remove_next_public_descriptor(void)
+struct tx_public_descriptor *stm_get_free_public_descriptor(revision_t *pindex)
 {
-  revision_t i = descriptor_array_free_list;
-  struct tx_public_descriptor *pd = stm_descriptor_array[i];
+  if (*pindex < 0)
+    *pindex = descriptor_array_free_list;
+
+  struct tx_public_descriptor *pd = stm_descriptor_array[*pindex];
   if (pd != NULL)
     {
-      descriptor_array_free_list = pd->free_list_next;
-      assert(descriptor_array_free_list >= 0);
+      *pindex = pd->free_list_next;
+      assert(*pindex >= 0);
     }
   return pd;
 }
@@ -1390,6 +1394,8 @@
           /* we are reusing 'pd' */
           descriptor_array_free_list = pd->free_list_next;
           assert(descriptor_array_free_list >= 0);
+          assert(pd->collection_lock == 0 || pd->collection_lock == -1);
+          pd->collection_lock = 0;
       }
       else {
           /* no item in the free list */
@@ -1413,6 +1419,10 @@
       stm_private_rev_num = -d->my_lock;
       d->private_revision_ref = &stm_private_rev_num;
       d->max_aborts = -1;
+      d->tx_prev = NULL;
+      d->tx_next = stm_tx_head;
+      if (d->tx_next != NULL) d->tx_next->tx_prev = d;
+      stm_tx_head = d;
       thread_descriptor = d;
 
       fprintf(stderr, "[%lx] pthread %lx starting\n",
@@ -1442,6 +1452,9 @@
     assert(stm_descriptor_array[i] == d->public_descriptor);
     d->public_descriptor->free_list_next = descriptor_array_free_list;
     descriptor_array_free_list = i;
+    if (d->tx_prev != NULL) d->tx_prev->tx_next = d->tx_next;
+    if (d->tx_next != NULL) d->tx_next->tx_prev = d->tx_prev;
+    if (d == stm_tx_head) stm_tx_head = d->tx_next;
     stmgcpage_release_global_lock();
 
     thread_descriptor = NULL;
diff --git a/c4/et.h b/c4/et.h
--- a/c4/et.h
+++ b/c4/et.h
@@ -153,11 +153,13 @@
   long long longest_abort_info_time;
   revision_t *private_revision_ref;
   struct FXCache recent_reads_cache;
+  struct tx_descriptor *tx_prev, *tx_next;
 };
 
 extern __thread struct tx_descriptor *thread_descriptor;
 extern __thread revision_t stm_private_rev_num;
 extern struct tx_public_descriptor *stm_descriptor_array[];
+extern struct tx_descriptor *stm_tx_head;
 
 /************************************************************/
 
@@ -182,8 +184,8 @@
 void stm_clear_read_cache(void);  /* debugging */
 void _stm_test_forget_previous_state(void);  /* debugging */
 
+struct tx_public_descriptor *stm_get_free_public_descriptor(revision_t *);
 int DescriptorInit(void);
 void DescriptorDone(void);
-struct tx_public_descriptor *stm_remove_next_public_descriptor(void);
 
 #endif  /* _ET_H */
diff --git a/c4/gcpage.c b/c4/gcpage.c
--- a/c4/gcpage.c
+++ b/c4/gcpage.c
@@ -66,7 +66,7 @@
         init_global_data();
 
     /* Take back ownership of the pages currently assigned to
-       LOCAL_GCPAGES that come from a previous thread. */
+       LOCAL_GCPAGES that might come from a previous thread. */
 }
 
 void stmgcpage_done_tls(void)
@@ -254,30 +254,55 @@
     gcp->free_loc_for_size[size_class] = freelist;
 }
 
+static void free_unused_local_pages(struct tx_public_descriptor *gcp)
+{
+    int i;
+    page_header_t *lpage;
 
-/***** Major collections: main *****/
+    for (i = 1; i < GC_SMALL_REQUESTS; i++) {
+        lpage = gcp->pages_for_size[i];
+        gcp->pages_for_size[i] = NULL;
+        gcp->free_loc_for_size[i] = NULL;
+        sweep_pages(gcp, i, lpage);
+    }
+}
+
+static void free_all_unused_local_pages(void)
+{
+    struct tx_descriptor *d;
+    for (d = stm_tx_head; d; d = d->tx_next) {
+        free_unused_local_pages(d->public_descriptor);
+    }
+}
 
 static void free_closed_thread_descriptors(void)
 {
     int i;
     page_header_t *gpage;
     struct tx_public_descriptor *gcp;
+    revision_t index = -1;
 
-    while ((gcp = stm_remove_next_public_descriptor()) != NULL) {
+    while ((gcp = stm_get_free_public_descriptor(&index)) != NULL) {
+        if (gcp->collection_lock == -1)
+            continue;
+
         for (i = 1; i < GC_SMALL_REQUESTS; i++) {
             gpage = gcp->pages_for_size[i];
             sweep_pages(gcp, i, gpage);
         }
         assert(gcp->collection_lock == 0);
+        gcp->collection_lock = -1;
         /* XXX ...stub_blocks... */
         assert(gcp->stolen_objects.size == 0);
         assert(gcp->stolen_young_stubs.size == 0);
         gcptrlist_delete(&gcp->stolen_objects);
         gcptrlist_delete(&gcp->stolen_young_stubs);
-        stm_free(gcp, sizeof(struct tx_public_descriptor));
     }
 }
 
+
+/***** Major collections: main *****/
+
 void stm_major_collect(void)
 {
     stmgcpage_acquire_global_lock();
@@ -295,8 +320,8 @@
 #endif
 
     mc_total_in_use = mc_total_reserved = 0;
+    free_all_unused_local_pages();
 #if 0
-    free_all_unused_local_pages();
     free_unused_global_pages();
 #endif
     free_closed_thread_descriptors();
diff --git a/c4/nursery.c b/c4/nursery.c
--- a/c4/nursery.c
+++ b/c4/nursery.c
@@ -77,7 +77,7 @@
 gcptr stmgc_duplicate_old(gcptr P)
 {
     size_t size = stmcb_size(P);
-    gcptr L = (gcptr)stm_malloc(size);
+    gcptr L = (gcptr)stmgcpage_malloc(size);
     memcpy(L, P, size);
     L->h_tid |= GCFLAG_OLD;
     return L;
diff --git a/c4/steal.c b/c4/steal.c
--- a/c4/steal.c
+++ b/c4/steal.c
@@ -19,6 +19,7 @@
     if (p == NULL) {
         assert(sizeof(struct stub_block_s) == STUB_BLOCK_SIZE);
 
+        /* XXX free! */
         char *page = stm_malloc(STUB_PAGE);
         char *page_end = page + STUB_PAGE;
         page += (-(revision_t)page) & (STUB_BLOCK_SIZE-1);  /* round up */
diff --git a/c4/test/test_gcpage.py b/c4/test/test_gcpage.py
--- a/c4/test/test_gcpage.py
+++ b/c4/test/test_gcpage.py
@@ -99,3 +99,9 @@
         major_collect()
         assert count_global_pages() == 0
     run_parallel(f1, f2)
+
+def test_free_unused_local_pages():
+    p1 = oalloc(HDR)
+    assert count_pages() == 1
+    major_collect()
+    assert count_pages() == 0


More information about the pypy-commit mailing list