Author: Remi Meier
Branch: c7
Changeset: r705:d7f5d26b082d
Date: 2014-02-05 14:52 +0100
http://bitbucket.org/pypy/stmgc/changeset/d7f5d26b082d/

Log:    implement requesting of safe-points and older-transaction-succeeds
        in write-write conflicts

diff --git a/c7/core.c b/c7/core.c
--- a/c7/core.c
+++ b/c7/core.c
@@ -21,6 +21,7 @@
 static int num_threads_started;
 uint8_t write_locks[READMARKER_END - READMARKER_START];
 volatile uint8_t inevitable_lock __attribute__((aligned(64))); /* cache-line 
alignment */
+long global_age = 0;
 
 struct _thread_local1_s* _stm_dbg_get_tl(int thread)
 {
@@ -134,18 +135,16 @@
         if ((!prev_owner) || (prev_owner == lock_num))
             break;
 
-        if (_STM_TL->active == 2) {
+        struct _thread_local1_s* other_tl = _stm_dbg_get_tl(prev_owner - 1);
+        if ((_STM_TL->age < other_tl->age) || (_STM_TL->active == 2)) {
             /* we must succeed! */
-            _stm_dbg_get_tl(prev_owner - 1)->need_abort = 1;
+            other_tl->need_abort = 1;
             _stm_start_safe_point(0);
             /* XXX: not good, maybe should be signalled by other thread */
             usleep(1);
             _stm_stop_safe_point(0);
             goto retry;
-        }
-
-
-        if (retries < 1) {
+        } else if (retries < 1) {
             _stm_start_safe_point(0);
             usleep(1);
             _stm_stop_safe_point(0);
@@ -176,8 +175,8 @@
     _stm_restore_local_state(thread_num);
 
     _STM_TL->nursery_current = (localchar_t*)(FIRST_NURSERY_PAGE * 4096);
-    memset((void*)real_address((object_t*)_STM_TL->nursery_current), 0x0,
-           (FIRST_AFTER_NURSERY_PAGE - FIRST_NURSERY_PAGE) * 4096); /* clear 
nursery */
+    
memset((void*)real_address((object_t*)CLEAR_SYNC_REQUEST(_STM_TL->nursery_current)),
+           0x0, (FIRST_AFTER_NURSERY_PAGE - FIRST_NURSERY_PAGE) * 4096); /* 
clear nursery */
     
     _STM_TL->shadow_stack = NULL;
     _STM_TL->shadow_stack_base = NULL;
@@ -386,6 +385,8 @@
     _STM_TL->jmpbufptr = jmpbufptr;
     _STM_TL->active = 1;
     _STM_TL->need_abort = 0;
+    /* global_age is approximate -> no synchronization required */
+    _STM_TL->age = global_age++;
     
     fprintf(stderr, "%c", 'S'+_STM_TL->thread_num*32);
 }
diff --git a/c7/core.h b/c7/core.h
--- a/c7/core.h
+++ b/c7/core.h
@@ -94,6 +94,10 @@
     jmpbufptr_t *jmpbufptr;
     uint8_t transaction_read_version;
 
+    /* unsynchronized/inaccurate start age of transaction
+       XXX: may be replaced with size_of(read/write-set) */
+    long age;
+
     /* static threads, not pthreads */
     int thread_num;
     char *thread_base;
@@ -105,7 +109,10 @@
     object_t **shadow_stack;
     object_t **shadow_stack_base;
 
-    localchar_t *nursery_current;
+    union {
+        localchar_t *nursery_current;
+        uint32_t nursery_current_halfwords[2];
+    };
     
     struct stm_list_s *modified_objects;
     
diff --git a/c7/nursery.c b/c7/nursery.c
--- a/c7/nursery.c
+++ b/c7/nursery.c
@@ -166,7 +166,7 @@
     /* clear nursery */
     localchar_t *nursery_base = (localchar_t*)(FIRST_NURSERY_PAGE * 4096);
     memset((void*)real_address((object_t*)nursery_base), 0x0,
-           _STM_TL->nursery_current - nursery_base);
+           CLEAR_SYNC_REQUEST(_STM_TL->nursery_current) - nursery_base);
     _STM_TL->nursery_current = nursery_base;
 }
 
@@ -177,23 +177,33 @@
 
 localchar_t *collect_and_reserve(size_t size)
 {
+    localchar_t *new_current = _STM_TL->nursery_current;
+
+    while (((uintptr_t)new_current > FIRST_AFTER_NURSERY_PAGE * 4096)
+           && _STM_TL->nursery_current_halfwords[1]) {
+        
+        _STM_TL->nursery_current_halfwords[1] = 0;
+        _stm_start_safe_point(0);
+        /* no collect, it would mess with nursery_current */
+        _stm_stop_safe_point(0);
+        
+        new_current = _STM_TL->nursery_current;
+    }
+
+    if (!((uintptr_t)new_current > FIRST_AFTER_NURSERY_PAGE * 4096)) {
+        /* after safe-point, new_current is actually fine again */
+        return new_current - size;
+    }
+    
     /* reset nursery_current (left invalid by the caller) */
     _STM_TL->nursery_current -= size;
 
-    /* XXX: check for requested safe-point (by setting nursery_current
-       too high or similar) */
-    
-    
-    _stm_start_safe_point(0);    /* don't release the COLLECT lock,
-                                   that needs to be done afterwards if
-                                   we want a major collection */
     minor_collect();
-    _stm_stop_safe_point(0);
 
     /* XXX: if we_want_major_collect: acquire EXCLUSIVE & COLLECT lock
        and do it */
 
-    localchar_t *current = _STM_TL->nursery_current;
+    localchar_t *current = CLEAR_SYNC_REQUEST(_STM_TL->nursery_current);
     _STM_TL->nursery_current = current + size;
     return current;
 }
@@ -231,7 +241,6 @@
     localchar_t *current = _STM_TL->nursery_current;
     localchar_t *new_current = current + size;
     _STM_TL->nursery_current = new_current;
-    assert((uintptr_t)new_current < (1L << 32));
 
     if ((uintptr_t)new_current > FIRST_AFTER_NURSERY_PAGE * 4096) {
         current = collect_and_reserve(size);
@@ -312,7 +321,7 @@
     /* clear the nursery */
     localchar_t *nursery_base = (localchar_t*)(FIRST_NURSERY_PAGE * 4096);
     memset((void*)real_address((object_t*)nursery_base), 0x0,
-           _STM_TL->nursery_current - nursery_base);
+           CLEAR_SYNC_REQUEST(_STM_TL->nursery_current) - nursery_base);
     _STM_TL->nursery_current = nursery_base;
 
 
diff --git a/c7/stmsync.c b/c7/stmsync.c
--- a/c7/stmsync.c
+++ b/c7/stmsync.c
@@ -108,7 +108,7 @@
     assert(!_STM_TL->active);
     /* assert(!_STM_TL->need_abort); may happen, but will be cleared by
        start_transaction() */ 
-    assert(_STM_TL->nursery_current == (localchar_t*)(FIRST_NURSERY_PAGE * 
4096));
+    assert(CLEAR_SYNC_REQUEST(_STM_TL->nursery_current) == 
(localchar_t*)(FIRST_NURSERY_PAGE * 4096));
 }
 
 void _stm_acquire_tl_segment()
@@ -270,10 +270,12 @@
         _stm_grab_thread_segment();
     }
     
-    if (flags & LOCK_EXCLUSIVE)
+    if (flags & LOCK_EXCLUSIVE) {
+        stm_request_safe_point(1 - _STM_TL->thread_num);
         stm_start_exclusive_lock();
-    else
+    } else {
         stm_start_shared_lock();
+    }
     
     if (flags & LOCK_COLLECT) { /* if we released the collection lock */
         /* acquire read-collection. always succeeds because
@@ -296,3 +298,9 @@
 
 
 
+void stm_request_safe_point(int thread_num)
+{
+    struct _thread_local1_s* other_tl = _stm_dbg_get_tl(thread_num);
+    other_tl->nursery_current_halfwords[1] = 1;    
+}
+
diff --git a/c7/stmsync.h b/c7/stmsync.h
--- a/c7/stmsync.h
+++ b/c7/stmsync.h
@@ -17,3 +17,8 @@
     THREAD_YIELD = (1 << 2),
 };
 
+
+void stm_request_safe_point(int thread_num);
+
+#define CLEAR_SYNC_REQUEST(nursery_current) 
((localchar_t*)(((uintptr_t)(nursery_current)) & 0xffffffff))
+
diff --git a/duhton/demo/synth.duh b/duhton/demo/synth.duh
--- a/duhton/demo/synth.duh
+++ b/duhton/demo/synth.duh
@@ -62,8 +62,10 @@
 
 
 
-(setq N 800)
-(setq RAND_MAX 10)
+(setq N 1000)
+;; CONFL_IF_BELOW / RAND_MAX == ratio of conflicting transactions
+;;                              to non conflicting ones
+(setq RAND_MAX 8)
 (setq CONFL_IF_BELOW 1)
 
 
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to