Author: Remi Meier
Branch: c7
Changeset: r682:3e167ba69711
Date: 2014-01-28 13:09 +0100
http://bitbucket.org/pypy/stmgc/changeset/3e167ba69711/

Log:    test and fix for writing to old objects which are already writeable
        for us

diff --git a/c7/core.c b/c7/core.c
--- a/c7/core.c
+++ b/c7/core.c
@@ -72,7 +72,7 @@
 
             /* clear the write-lock */
             uintptr_t lock_idx = (((uintptr_t)item) >> 4) - READMARKER_START;
-            assert(write_locks[lock_idx]);
+            assert(write_locks[lock_idx] == _STM_TL->thread_num + 1);
             write_locks[lock_idx] = 0;
 
             _stm_move_object(item,
@@ -103,7 +103,7 @@
         obj->stm_flags &= ~GCFLAG_WRITE_BARRIER;
         return;
     }
-
+    
     /* privatize if SHARED_PAGE */
     uintptr_t pagenum2, pages;
     if (obj->stm_flags & GCFLAG_SMALL) {
@@ -115,28 +115,38 @@
         assert(pagenum == pagenum2);
         assert(pages == (stmcb_size(real_address(obj)) +4095) / 4096);
     }
+    
     for (pagenum2 += pages - 1; pagenum2 >= pagenum; pagenum2--)
         stm_pages_privatize(pagenum2);
 
+    
     /* claim the write-lock for this object */
     uintptr_t lock_idx = (((uintptr_t)obj) >> 4) - READMARKER_START;
-    uint8_t previous;
-    while ((previous = __sync_lock_test_and_set(&write_locks[lock_idx], 1))) {
+    uint8_t lock_num = _STM_TL->thread_num + 1;
+    uint8_t prev_owner;
+    do {
+        prev_owner = __sync_val_compare_and_swap(&write_locks[lock_idx],
+                                               0, lock_num);
+        
+        /* if there was no lock-holder or we already have the lock */
+        if ((!prev_owner) || (prev_owner == lock_num))
+            break;
+        
         /* XXXXXX */
         //_stm_start_semi_safe_point();
-        usleep(1);
+        //usleep(1);
         //_stm_stop_semi_safe_point();
-        //if (!(previous = __sync_lock_test_and_set(&write_locks[lock_idx], 
1))) 
-        //    break;
+        // try again.... XXX
         stm_abort_transaction();
         /* XXX: only abort if we are younger */
         spin_loop();
+    } while (1);
+    
+    obj->stm_flags &= ~GCFLAG_WRITE_BARRIER;
+    if (prev_owner == 0) {
+        stm_read(obj);
+        LIST_APPEND(_STM_TL->modified_objects, obj);
     }
-
-    obj->stm_flags &= ~GCFLAG_WRITE_BARRIER;
-    stm_read(obj);
-
-    LIST_APPEND(_STM_TL->modified_objects, obj);
 }
 
 
@@ -380,11 +390,13 @@
             /* note: same as push_modified_to... but src/dst swapped
                TODO: unify both... */
             
-            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);
-
+             /* check at least the first page (required by move_obj() */
+            assert(stm_get_page_flag((uintptr_t)item / 4096) == PRIVATE_PAGE);
+            
+            _stm_move_object(item,
+                             REAL_ADDRESS(remote_base, item),
+                             REAL_ADDRESS(local_base, item));
+            
             /* copying from the other thread re-added the
                WRITE_BARRIER flag */
             assert(item->stm_flags & GCFLAG_WRITE_BARRIER);
diff --git a/c7/largemalloc.c b/c7/largemalloc.c
--- a/c7/largemalloc.c
+++ b/c7/largemalloc.c
@@ -124,7 +124,7 @@
        memcpy over multiple PRIVATE pages. */
     char *end = src + _stm_data_size((struct 
object_s*)REAL_ADDRESS(get_thread_base(0), obj));
     uintptr_t pagenum, num;
-    struct object_s *t0_obj = (struct 
object_s*)REAL_ADDRESS(get_thread_base(0), _stm_tl_address(src));
+    struct object_s *t0_obj = (struct 
object_s*)REAL_ADDRESS(get_thread_base(0), obj);
 
     if (obj->stm_flags & GCFLAG_SMALL) {
         pagenum = (uintptr_t)obj / 4096UL;
diff --git a/c7/test/test_basic.py b/c7/test/test_basic.py
--- a/c7/test/test_basic.py
+++ b/c7/test/test_basic.py
@@ -456,6 +456,23 @@
         newer = stm_pop_root()
         assert new == newer
 
+    def test_write_to_old_after_minor(self):
+        stm_start_transaction()
+        new = stm_allocate(16)
+        stm_push_root(new)
+        stm_minor_collect()
+        old = stm_pop_root()
+        stm_stop_transaction()
+
+        stm_start_transaction()
+        stm_write(old) # old objs to trace
+        stm_set_char(old, 'x')
+        stm_minor_collect()
+        stm_write(old) # old objs to trace
+        stm_set_char(old, 'y')
+        stm_stop_transaction()
+        
+
         
     # def test_resolve_write_write_no_conflict(self):
     #     stm_start_transaction()
diff --git a/duhton/demo/sort.duh b/duhton/demo/sort.duh
--- a/duhton/demo/sort.duh
+++ b/duhton/demo/sort.duh
@@ -126,24 +126,7 @@
 (defun print_list (xs)
   (print (quote len:) (len xs) (quote ->) xs)
   )
-;; (defun rotate (tree)
-;;   (if (pair? tree)
-;;       (progn
-;;         (setq left (car tree))
-;;         (print left)
-;;         (print (cdr tree))
-;;         )
-;;     (print 111111)
-;;     )
-;;   )
 
-;; (defun create-tree (n)
-;;   (if (== n 0) 
-;;       (progn
-;;         (set c (+ (get c) 1))
-;;         (get c))
-;;     (cons (create-tree (- n 1)) (create-tree (- n 1))))
-;;   )
 
 
 
@@ -153,7 +136,7 @@
 (print bs)
 (print (split_list as))
 
-(setq cs (random_list 200))
+(setq cs (random_list 1000))
 (print_list cs)
 (print_list (merge_sort (copy_list cs)))
 
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to