Author: Armin Rigo <[email protected]>
Branch: 
Changeset: r952:37981d65bc52
Date: 2014-03-04 19:43 +0100
http://bitbucket.org/pypy/stmgc/changeset/37981d65bc52/

Log:    A final clean-up round of bug fixes. Now demo_random seems to pass
        again.

diff --git a/c7/stm/contention.c b/c7/stm/contention.c
--- a/c7/stm/contention.c
+++ b/c7/stm/contention.c
@@ -215,8 +215,8 @@
                We don't have to wake it up right now, but we know it will
                abort as soon as it wakes up.  We can safely force it to
                reset its state now. */
-            dprintf(("reset other modified\n"));
-            reset_modified_from_other_segments(other_segment_num);
+            dprintf(("killing data structures\n"));
+            abort_data_structures_from_segment_num(other_segment_num);
         }
         dprintf(("killed other thread\n"));
     }
diff --git a/c7/stm/core.c b/c7/stm/core.c
--- a/c7/stm/core.c
+++ b/c7/stm/core.c
@@ -448,6 +448,29 @@
     list_clear(pseg->modified_old_objects);
 }
 
+static void abort_data_structures_from_segment_num(int segment_num)
+{
+    /* This function clears the content of the given segment undergoing
+       an abort.  It is called from abort_with_mutex(), but also sometimes
+       from other threads that figure out that this segment should abort.
+       In the latter case, make sure that this segment is currently at
+       a safe point (not SP_RUNNING).
+    */
+    struct stm_priv_segment_info_s *pseg = get_priv_segment(segment_num);
+
+    /* throw away the content of the nursery */
+    throw_away_nursery(pseg);
+
+    /* reset all the modified objects (incl. re-adding GCFLAG_WRITE_BARRIER) */
+    reset_modified_from_other_segments(segment_num);
+
+    /* reset the tl->shadowstack and thread_local_obj to their original
+       value before the transaction start */
+    stm_thread_local_t *tl = pseg->pub.running_thread;
+    tl->shadowstack = pseg->shadowstack_at_start_of_transaction;
+    tl->thread_local_obj = pseg->threadlocal_at_start_of_transaction;
+}
+
 static void abort_with_mutex(void)
 {
     dprintf(("~~~ ABORT\n"));
@@ -463,16 +486,9 @@
     }
     assert(STM_PSEGMENT->running_pthread == pthread_self());
 
-    /* throw away the content of the nursery */
-    throw_away_nursery();
-
-    /* reset all the modified objects (incl. re-adding GCFLAG_WRITE_BARRIER) */
-    reset_modified_from_other_segments(STM_SEGMENT->segment_num);
+    abort_data_structures_from_segment_num(STM_SEGMENT->segment_num);
 
     stm_jmpbuf_t *jmpbuf_ptr = STM_SEGMENT->jmpbuf_ptr;
-    stm_thread_local_t *tl = STM_SEGMENT->running_thread;
-    tl->shadowstack = STM_PSEGMENT->shadowstack_at_start_of_transaction;
-    tl->thread_local_obj = STM_PSEGMENT->threadlocal_at_start_of_transaction;
 
     if (STM_SEGMENT->nursery_end == NSE_SIGABORT)
         STM_SEGMENT->nursery_end = NURSERY_END;   /* done aborting */
diff --git a/c7/stm/core.h b/c7/stm/core.h
--- a/c7/stm/core.h
+++ b/c7/stm/core.h
@@ -183,6 +183,7 @@
 
 static void teardown_core(void);
 static void abort_with_mutex(void) __attribute__((noreturn));
+static void abort_data_structures_from_segment_num(int segment_num);
 
 static inline bool was_read_remote(char *base, object_t *obj,
                                    uint8_t other_transaction_read_version)
diff --git a/c7/stm/nursery.c b/c7/stm/nursery.c
--- a/c7/stm/nursery.c
+++ b/c7/stm/nursery.c
@@ -196,29 +196,29 @@
                    _collect_now(item));
 }
 
-static void throw_away_nursery(void)
+static void throw_away_nursery(struct stm_priv_segment_info_s *pseg)
 {
     /* reset the nursery by zeroing it */
     size_t size;
     char *realnursery;
 
-    realnursery = REAL_ADDRESS(STM_SEGMENT->segment_base, _stm_nursery_start);
-    size = STM_SEGMENT->nursery_current - (stm_char *)_stm_nursery_start;
+    realnursery = REAL_ADDRESS(pseg->pub.segment_base, _stm_nursery_start);
+    size = pseg->pub.nursery_current - (stm_char *)_stm_nursery_start;
     memset(realnursery, 0, size);
 
-    STM_SEGMENT->nursery_current = (stm_char *)_stm_nursery_start;
+    pseg->pub.nursery_current = (stm_char *)_stm_nursery_start;
 
     /* free any object left from 'young_outside_nursery' */
-    if (!tree_is_cleared(STM_PSEGMENT->young_outside_nursery)) {
+    if (!tree_is_cleared(pseg->young_outside_nursery)) {
         bool locked = false;
         wlog_t *item;
-        TREE_LOOP_FORWARD(*STM_PSEGMENT->young_outside_nursery, item) {
+        TREE_LOOP_FORWARD(*pseg->young_outside_nursery, item) {
             assert(!_is_in_nursery((object_t *)item->addr));
             if (!locked) {
                 mutex_pages_lock();
                 locked = true;
             }
-            char *realobj = REAL_ADDRESS(STM_SEGMENT->segment_base,item->addr);
+            char *realobj = REAL_ADDRESS(pseg->pub.segment_base, item->addr);
             ssize_t size = stmcb_size_rounded_up((struct object_s *)realobj);
             increment_total_allocated(-(size + LARGE_MALLOC_OVERHEAD));
             _stm_large_free(stm_object_pages + item->addr);
@@ -227,7 +227,7 @@
         if (locked)
             mutex_pages_unlock();
 
-        tree_clear(STM_PSEGMENT->young_outside_nursery);
+        tree_clear(pseg->young_outside_nursery);
     }
 }
 
@@ -277,7 +277,7 @@
 
     collect_oldrefs_to_nursery();
 
-    throw_away_nursery();
+    throw_away_nursery(get_priv_segment(STM_SEGMENT->segment_num));
 
     assert(MINOR_NOTHING_TO_DO(STM_PSEGMENT));
     assert(list_is_empty(STM_PSEGMENT->objects_pointing_to_nursery));
@@ -405,6 +405,10 @@
             _do_minor_collection(/*commit=*/ false);
             assert(MINOR_NOTHING_TO_DO(pseg));
         }
+        else {
+            dprintf(("abort data structures\n"));
+            abort_data_structures_from_segment_num(i);
+        }
     }
 
     set_gs_register(get_segment_base(original_num));
diff --git a/c7/stm/nursery.h b/c7/stm/nursery.h
--- a/c7/stm/nursery.h
+++ b/c7/stm/nursery.h
@@ -11,7 +11,7 @@
 
 static void minor_collection(bool commit);
 static void check_nursery_at_transaction_start(void);
-static void throw_away_nursery(void);
+static void throw_away_nursery(struct stm_priv_segment_info_s *pseg);
 static void major_do_minor_collections(void);
 
 static inline bool must_abort(void) {
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to