[pypy-commit] pypy stm-gc: Ensure NEXT is cleared by C code after all.
arigo
noreply at buildbot.pypy.org
Sun Apr 22 23:00:00 CEST 2012
Author: Armin Rigo <arigo at tunes.org>
Branch: stm-gc
Changeset: r54629:c343346db868
Date: 2012-04-22 20:37 +0200
http://bitbucket.org/pypy/pypy/changeset/c343346db868/
Log: Ensure NEXT is cleared by C code after all. Adapt two more tests.
diff --git a/pypy/rlib/rstm.py b/pypy/rlib/rstm.py
--- a/pypy/rlib/rstm.py
+++ b/pypy/rlib/rstm.py
@@ -4,6 +4,7 @@
from pypy.rpython.annlowlevel import base_ptr_lltype, cast_base_ptr_to_instance
from pypy.rlib.objectmodel import keepalive_until_here, we_are_translated
from pypy.rlib.debug import ll_assert
+from pypy.rlib.nonconst import NonConstant
from pypy.translator.stm.stmgcintf import StmOperations
@@ -171,7 +172,15 @@
# This logic is in a sub-function because we want to catch
# the MemoryErrors that could occur.
transaction = _cast_voidp_to_transaction(transactionptr)
- transaction._next_transaction = None
+ #
+ # Sanity-check that C code cleared '_next_transaction' first.
+ # Also needs a bit of nonsensical code to make sure that
+ # '_next_transaction' is always created as a general field.
+ ll_assert(transaction._next_transaction is None,
+ "transaction._next_transaction should be cleared by the C code")
+ if NonConstant(False):
+ transaction._next_transaction = transaction
+ #
transaction.retry_counter = retry_counter
new_transactions = transaction.run()
return _link_new_transactions(new_transactions)
diff --git a/pypy/rlib/test/test_rstm.py b/pypy/rlib/test/test_rstm.py
--- a/pypy/rlib/test/test_rstm.py
+++ b/pypy/rlib/test/test_rstm.py
@@ -21,6 +21,8 @@
self._add(initial_transaction_ptr)
while self._pending:
r, transactionptr = self._pending.popitem()
+ transaction = self.cast_voidp_to_transaction(transactionptr)
+ transaction._next_transaction = None
nextptr = rstm._stm_run_transaction(transactionptr, 0)
next = self.cast_voidp_to_transaction(nextptr)
while next is not None:
diff --git a/pypy/translator/stm/src_stm/fifo.c b/pypy/translator/stm/src_stm/fifo.c
--- a/pypy/translator/stm/src_stm/fifo.c
+++ b/pypy/translator/stm/src_stm/fifo.c
@@ -40,17 +40,14 @@
return (fifo->first == NULL);
}
-/* static bool_t fifo_is_of_length_1(stm_fifo_t *fifo) */
-/* { */
-/* return (fifo->first != NULL && fifo->first == fifo->last); */
-/* } */
-
static void *fifo_popleft(stm_fifo_t *fifo)
{
void *item = fifo->first;
fifo->first = NEXT(item);
if (fifo->first == NULL)
fifo->last = NULL;
+ NEXT(item) = NULL; /* ensure the NEXT is cleared,
+ to avoid spurious keepalives */
return item;
}
diff --git a/pypy/translator/stm/src_stm/rpyintf.c b/pypy/translator/stm/src_stm/rpyintf.c
--- a/pypy/translator/stm/src_stm/rpyintf.c
+++ b/pypy/translator/stm/src_stm/rpyintf.c
@@ -93,7 +93,7 @@
while (1)
{
new_transaction_list = perform_transaction(transaction);
-
+
/* for now, always break out of this loop,
unless 'new_transaction_list' contains precisely one item */
if (new_transaction_list == NULL)
diff --git a/pypy/translator/stm/test/test_ztranslated.py b/pypy/translator/stm/test/test_ztranslated.py
--- a/pypy/translator/stm/test/test_ztranslated.py
+++ b/pypy/translator/stm/test/test_ztranslated.py
@@ -1,4 +1,5 @@
import py
+from pypy.rlib import rstm, rgc
from pypy.translator.stm.test.support import CompiledSTMTests
from pypy.translator.stm.test import targetdemo
@@ -11,33 +12,19 @@
assert 'check ok!' in data
def test_bug1(self):
- from pypy.rlib import rstm, rgc
- from pypy.module.transaction import threadintf
#
- class State:
- pass
- state = State()
- #
- def _foo(_, retry_counter):
- rgc.collect(0)
- def _run_thread():
- rstm.descriptor_init()
- rstm.perform_transaction(_foo, X, None)
- threadintf.release(state.ll_unfinished_lock)
- rstm.descriptor_done()
+ class InitialTransaction(rstm.Transaction):
+ def run(self):
+ rgc.collect(0)
#
class X:
def __init__(self, count):
self.count = count
def g():
x = X(1000)
- rstm.enter_transactional_mode()
- threadintf.start_new_thread(_run_thread)
- threadintf.acquire(state.ll_unfinished_lock, True)
- rstm.leave_transactional_mode()
+ rstm.run_all_transactions(InitialTransaction())
return x
def entry_point(argv):
- state.ll_unfinished_lock = threadintf.allocate_lock()
x = X(len(argv))
y = g()
print '<', x.count, y.count, '>'
@@ -48,7 +35,10 @@
assert '< 5 1000 >' in data, "got: %r" % (data,)
def test_bug2(self):
- from pypy.rlib import rstm
+ #
+ class DoNothing(rstm.Transaction):
+ def run(self):
+ pass
#
class X2:
pass
@@ -58,8 +48,8 @@
x = prebuilt2[count]
x.foobar = 2 # 'x' becomes a local
#
- rstm.enter_transactional_mode() # 'x' becomes the global again
- rstm.leave_transactional_mode()
+ rstm.run_all_transactions(DoNothing())
+ # 'x' becomes the global again
#
y = prebuilt2[count] # same prebuilt obj
y.foobar += 10 # 'y' becomes a local
More information about the pypy-commit
mailing list