[pypy-commit] pypy stm-gc-2: Comments; fix allocate_object_of_size()

arigo noreply at buildbot.pypy.org
Wed Apr 17 16:11:36 CEST 2013


Author: Armin Rigo <arigo at tunes.org>
Branch: stm-gc-2
Changeset: r63445:bcb33801e8ac
Date: 2013-04-17 15:19 +0200
http://bitbucket.org/pypy/pypy/changeset/bcb33801e8ac/

Log:	Comments; fix allocate_object_of_size()

diff --git a/rpython/memory/gc/stmtls.py b/rpython/memory/gc/stmtls.py
--- a/rpython/memory/gc/stmtls.py
+++ b/rpython/memory/gc/stmtls.py
@@ -272,16 +272,31 @@
             fatalerror("malloc in a non-main thread but outside a transaction")
         if llmemory.raw_malloc_usage(size) > self.nursery_size // 8 * 7:
             fatalerror("XXX object too large to ever fit in the nursery")
+        #
+        self.local_collection(run_finalizers=True)
+        #
+        # call this here in case another thread is waiting for a global GC
         self.stm_operations.should_break_transaction()
-        step = 0
-        while True:
-            free = self.nursery_free
-            top  = self.nursery_top
-            if (top - free) >= llmemory.raw_malloc_usage(size):
-                return free
-            ll_assert(step < 2, "nursery must be empty [0]")
-            self.local_collection(run_finalizers=(step==0))
-            step += 1
+        #
+        # if we have now enough space, return it
+        free = self.nursery_free
+        top  = self.nursery_top
+        if (top - free) >= llmemory.raw_malloc_usage(size):
+            return free
+        #
+        # no, it might be because we ran finalizers or did a global GC.
+        # Try again without running the finalizers.
+        self.local_collection(run_finalizers=False)
+        #
+        # now we must have enough space
+        free = self.nursery_free
+        top  = self.nursery_top
+        if (top - free) >= llmemory.raw_malloc_usage(size):
+            return free
+        #
+        ll_assert(False,
+                  "local_collection(run_finalizers=0) didn't free enough mem")
+        return NULL
 
     def is_in_nursery(self, addr):
         ll_assert(llmemory.cast_adr_to_int(addr) & 1 == 0,
diff --git a/rpython/rlib/rstm.py b/rpython/rlib/rstm.py
--- a/rpython/rlib/rstm.py
+++ b/rpython/rlib/rstm.py
@@ -46,12 +46,6 @@
 def abort_and_retry():
     stmgcintf.StmOperations.abort_and_retry()
 
-def start_single_thread():
-    stmgcintf.StmOperations.start_single_thread()
-
-def stop_single_thread():
-    stmgcintf.StmOperations.stop_single_thread()
-
 def before_external_call():
     if not is_atomic():
         e = get_errno()
diff --git a/rpython/translator/stm/src_stm/et.c b/rpython/translator/stm/src_stm/et.c
--- a/rpython/translator/stm/src_stm/et.c
+++ b/rpython/translator/stm/src_stm/et.c
@@ -75,6 +75,10 @@
 static volatile revision_t next_locked_value = LOCKED + 3;   /* always odd */
 static __thread struct tx_descriptor *thread_descriptor = NULL;
 
+/* 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 reached_safe_point(). */
 static pthread_rwlock_t rwlock_in_transaction =
          PTHREAD_RWLOCK_WRITER_NONRECURSIVE_INITIALIZER_NP;
 
diff --git a/rpython/translator/stm/src_stm/rpyintf.c b/rpython/translator/stm/src_stm/rpyintf.c
--- a/rpython/translator/stm/src_stm/rpyintf.c
+++ b/rpython/translator/stm/src_stm/rpyintf.c
@@ -243,6 +243,8 @@
     {
       err = pthread_rwlock_unlock(&rwlock_in_transaction);
       assert(err == 0);
+      /* another thread should be waiting in pthread_rwlock_wrlock(),
+         which takes priority here */
       err = pthread_rwlock_rdlock(&rwlock_in_transaction);
       assert(err == 0);
     }


More information about the pypy-commit mailing list