Author: Remi Meier <[email protected]>
Branch: c7
Changeset: r618:e4ab154d61af
Date: 2014-01-17 11:01 +0100
http://bitbucket.org/pypy/stmgc/changeset/e4ab154d61af/

Log:    push modified objs to other threads

diff --git a/c7/core.c b/c7/core.c
--- a/c7/core.c
+++ b/c7/core.c
@@ -191,6 +191,14 @@
         stm_abort_transaction();
 }
 
+bool _stm_was_read_remote(char *base, object_t *obj)
+{
+    struct read_marker_s *marker = (struct read_marker_s *)
+        (base + (((uintptr_t)obj) >> 4));
+    struct _thread_local1_s *other_TL1 = (struct _thread_local1_s*)
+        (base + (uintptr_t)_STM_TL1);
+    return (marker->rm == other_TL1->transaction_read_version);
+}
 
 
 bool _stm_was_read(object_t *obj)
@@ -318,54 +326,37 @@
 
 
 
-enum detect_conflicts_e { CANNOT_CONFLICT, CAN_CONFLICT, CHECK_CONFLICT };
-
-static void update_to_current_version(enum detect_conflicts_e check_conflict)
+static void push_modified_to_other_threads()
 {
-    /* Loop over objects in 'pending_updates': if they have been
-       read by the current transaction, the current transaction must
-       abort; then copy them out of the other thread's object space,
-       which is not modified so far (the other thread just committed
-       and will wait until we are done here before it starts the
-       next transaction).
-    */
-    bool conflict_found_or_dont_check = (check_conflict == CANNOT_CONFLICT);
+    struct stm_list_s *modified = _STM_TL2->modified_objects;
     char *local_base = _STM_TL2->thread_base;
     char *remote_base = get_thread_base(1 - _STM_TL2->thread_num);
-    struct stm_list_s *pu = pending_updates;
+    bool conflicted = 0;
+    char *t0_base = get_thread_base(0);
+    
+    STM_LIST_FOREACH(modified, ({
+                if (!conflicted)
+                    conflicted = _stm_was_read_remote(remote_base, item);
 
-    assert(pu != _STM_TL2->modified_objects);
-
-    STM_LIST_FOREACH(pu, ({
-
-        if (!conflict_found_or_dont_check)
-            conflict_found_or_dont_check = _stm_was_read(item);
-
-        char *dst = REAL_ADDRESS(local_base, item);
-        char *src = REAL_ADDRESS(remote_base, item);
-        size_t size = stmcb_size((struct object_s*)src);
-
-        memcpy(dst, src, size);
-    }));
-
-    write_fence();
-    pending_updates = NULL;
-
-    if (conflict_found_or_dont_check) {
-        if (check_conflict == CAN_CONFLICT) {
-            stm_abort_transaction();
-        } else {                  /* CHECK_CONFLICT */
-            _STM_TL2->need_abort = 1;
-        }
+                /* clear the write-lock */
+                struct object_s *t0_obj = (struct object_s*)
+                    REAL_ADDRESS(t0_base, item);
+                assert(t0_obj->stm_write_lock);
+                t0_obj->stm_write_lock = 0;
+                
+                char *src = REAL_ADDRESS(local_base, item);
+                char *dst = REAL_ADDRESS(remote_base, item);
+                size_t size = stmcb_size((struct object_s*)src);
+                memcpy(dst, src, size);
+            }));
+    
+    if (conflicted) {
+        struct _thread_local2_s *remote_TL2 = (struct _thread_local2_s *)
+            REAL_ADDRESS(remote_base, _STM_TL2);
+        remote_TL2->need_abort = 1;
     }
 }
 
-static void maybe_update(enum detect_conflicts_e check_conflict)
-{
-    if (pending_updates != NULL) {
-        update_to_current_version(check_conflict);
-    }
-}
 
 static void wait_until_updated(void)
 {
@@ -788,15 +779,10 @@
     }
 
     wait_until_updated();
-    stm_list_clear(_STM_TL2->modified_objects);
+    assert(stm_list_is_empty(_STM_TL2->modified_objects));
     assert(stm_list_is_empty(_STM_TL2->old_objects_to_trace));
     stm_list_clear(_STM_TL2->uncommitted_pages);
 
-    /* check that there is no stm_abort() in the following maybe_update() */
-    _STM_TL1->jmpbufptr = NULL;
-
-    maybe_update(CANNOT_CONFLICT);    /* no read object: cannot conflict */
-
     _STM_TL1->jmpbufptr = jmpbufptr;
     _STM_TL2->running_transaction = 1;
     _STM_TL2->need_abort = 0;
@@ -831,12 +817,8 @@
     minor_collect();
     
     /* copy modified object versions to other threads */
-    pending_updates = _STM_TL2->modified_objects;
-    int my_thread_num = _STM_TL2->thread_num;
-    int other_thread_num = 1 - my_thread_num;
-    _stm_restore_local_state(other_thread_num);
-    update_to_current_version(CHECK_CONFLICT); /* sets need_abort */
-    _stm_restore_local_state(my_thread_num);
+    push_modified_to_other_threads();
+    stm_list_clear(_STM_TL2->modified_objects);
 
     /* uncommitted_pages */
     long j;
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to