[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