[pypy-commit] stmgc c7: add spinlock implementation of reader-writer lock

Raemi noreply at buildbot.pypy.org
Sat Jan 18 11:39:54 CET 2014


Author: Remi Meier <remi.meier at gmail.com>
Branch: c7
Changeset: r637:cae45c13aee6
Date: 2014-01-18 11:39 +0100
http://bitbucket.org/pypy/stmgc/changeset/cae45c13aee6/

Log:	add spinlock implementation of reader-writer lock

diff --git a/c7/Makefile b/c7/Makefile
--- a/c7/Makefile
+++ b/c7/Makefile
@@ -14,9 +14,9 @@
 	rm -f $(BUILD_EXE) $(DEBUG_EXE) $(RELEASE_EXE)
 
 
-H_FILES = core.h list.h pagecopy.h
+H_FILES = core.h list.h pagecopy.h reader_writer_lock.h
 
-C_FILES = core.c list.c pagecopy.c
+C_FILES = core.c list.c pagecopy.c reader_writer_lock.c
 
 DEBUG = -g 
 
diff --git a/c7/core.c b/c7/core.c
--- a/c7/core.c
+++ b/c7/core.c
@@ -13,6 +13,7 @@
 #include "core.h"
 #include "list.h"
 #include "pagecopy.h"
+#include "reader_writer_lock.h"
 
 
 #define NB_PAGES            (256*256)    // 256MB
@@ -142,41 +143,40 @@
 
 /************************************************************/
 
+rwticket rw_shared_lock;
+
 /* a multi-reader, single-writer lock: transactions normally take a reader
    lock, so don't conflict with each other; when we need to do a global GC,
    we take a writer lock to "stop the world".  Note the initializer here,
    which should give the correct priority for stm_possible_safe_point(). */
-static pthread_rwlock_t rwlock_shared;
+
 
 struct tx_descriptor *in_single_thread = NULL;
 
 void stm_start_shared_lock(void)
 {
-    int err = pthread_rwlock_rdlock(&rwlock_shared);
-    if (err != 0)
-        abort();
+    rwticket_rdlock(&rw_shared_lock);
 }
 
-void stm_stop_lock(void)
+void stm_stop_shared_lock(void)
 {
-    int err = pthread_rwlock_unlock(&rwlock_shared);
-    if (err != 0)
-        abort();
+    rwticket_rdunlock(&rw_shared_lock);
+}
+
+void stm_stop_exclusive_lock(void)
+{
+    rwticket_wrunlock(&rw_shared_lock);
 }
 
 void stm_start_exclusive_lock(void)
 {
-    int err = pthread_rwlock_wrlock(&rwlock_shared);
-    if (err != 0)
-        abort();
-    if (_STM_TL2->need_abort)
-        stm_abort_transaction();
+    rwticket_wrlock(&rw_shared_lock);
 }
 
 void _stm_start_safe_point(void)
 {
     assert(!_STM_TL2->need_abort);
-    stm_stop_lock();
+    stm_stop_shared_lock();
 }
 
 void _stm_stop_safe_point(void)
@@ -376,9 +376,12 @@
     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))) {
-        usleep(1);              /* XXXXXX */
-        if (!(previous = __sync_lock_test_and_set(&write_locks[lock_idx], 1))) 
-            break;
+        /* XXXXXX */
+        //_stm_start_semi_safe_point();
+        usleep(1);
+        //_stm_stop_semi_safe_point();
+        //if (!(previous = __sync_lock_test_and_set(&write_locks[lock_idx], 1))) 
+        //    break;
         stm_abort_transaction();
         /* XXX: only abort if we are younger */
         spin_loop();
@@ -583,13 +586,8 @@
 
 
 void stm_setup(void)
-{    
-    pthread_rwlockattr_t attr;
-    pthread_rwlockattr_init(&attr);
-    pthread_rwlockattr_setkind_np(&attr,
-                                  PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP);
-    pthread_rwlock_init(&rwlock_shared, &attr);
-    pthread_rwlockattr_destroy(&attr);
+{
+    memset(&rw_shared_lock, 0, sizeof(rwticket));
 
     /* Check that some values are acceptable */
     assert(4096 <= ((uintptr_t)_STM_TL1));
@@ -685,8 +683,8 @@
 
 void _stm_teardown_thread(void)
 {
-    assert(!pthread_rwlock_trywrlock(&rwlock_shared));
-    assert(!pthread_rwlock_unlock(&rwlock_shared));
+    assert(!rwticket_wrtrylock(&rw_shared_lock));
+    assert(!rwticket_wrunlock(&rw_shared_lock));
     
     stm_list_free(_STM_TL2->modified_objects);
     _STM_TL2->modified_objects = NULL;
@@ -708,7 +706,6 @@
     munmap(object_pages, TOTAL_MEMORY);
     memset(flag_page_private, 0, sizeof(flag_page_private));
     memset(write_locks, 0, sizeof(write_locks));
-    pthread_rwlock_destroy(&rwlock_shared);
     object_pages = NULL;
 }
 
@@ -794,7 +791,7 @@
 void stm_stop_transaction(void)
 {
     assert(_STM_TL2->running_transaction);
-    stm_stop_lock();
+    stm_stop_shared_lock();
     stm_start_exclusive_lock();
 
     _STM_TL1->jmpbufptr = NULL;          /* cannot abort any more */
@@ -899,7 +896,7 @@
     /* } */
 
     _STM_TL2->running_transaction = 0;
-    stm_stop_lock();
+    stm_stop_exclusive_lock();
     fprintf(stderr, "%c", 'C'+_STM_TL2->thread_num*32);
 }
 
@@ -978,7 +975,7 @@
     assert(_STM_TL1->jmpbufptr != NULL);
     assert(_STM_TL1->jmpbufptr != (jmpbufptr_t *)-1);   /* for tests only */
     _STM_TL2->running_transaction = 0;
-    stm_stop_lock();
+    stm_stop_shared_lock();
     fprintf(stderr, "%c", 'A'+_STM_TL2->thread_num*32);
 
     /* reset all the modified objects (incl. re-adding GCFLAG_WRITE_BARRIER) */
diff --git a/c7/demo2.c b/c7/demo2.c
--- a/c7/demo2.c
+++ b/c7/demo2.c
@@ -57,7 +57,9 @@
             r_n = r_n->next;
             stm_read((objptr_t)r_n);
             sum += r_n->value;
-        
+
+            _stm_start_safe_point();
+            _stm_stop_safe_point();
             if (prev >= r_n->value) {
                 stm_stop_transaction();
                 return -1;
@@ -184,7 +186,6 @@
         sem_post(&initialized);
         status = sem_wait(&go);
         assert(status == 0);
-
     }
     
     while (check_sorted() == -1) {
diff --git a/c7/test/support.py b/c7/test/support.py
--- a/c7/test/support.py
+++ b/c7/test/support.py
@@ -7,9 +7,9 @@
 parent_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
 
 header_files = [os.path.join(parent_dir, _n) for _n in
-                "core.h pagecopy.h list.h".split()]
+                "core.h pagecopy.h list.h reader_writer_lock.h".split()]
 source_files = [os.path.join(parent_dir, _n) for _n in
-                "core.c pagecopy.c list.c".split()]
+                "core.c pagecopy.c list.c reader_writer_lock.c".split()]
 
 _pycache_ = os.path.join(parent_dir, 'test', '__pycache__')
 if os.path.exists(_pycache_):


More information about the pypy-commit mailing list