Author: Armin Rigo <[email protected]>
Branch: stm-thread
Changeset: r54882:38e65854dff3
Date: 2012-05-02 19:13 +0200
http://bitbucket.org/pypy/pypy/changeset/38e65854dff3/

Log:    This also makes no sense any more.

diff --git a/pypy/rlib/rstm.py b/pypy/rlib/rstm.py
deleted file mode 100644
--- a/pypy/rlib/rstm.py
+++ /dev/null
@@ -1,265 +0,0 @@
-from pypy.rpython.lltypesystem import lltype, llmemory, rffi
-from pypy.rpython.lltypesystem.lloperation import llop
-from pypy.rpython.annlowlevel import llhelper, cast_instance_to_base_ptr
-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.objectmodel import specialize
-from pypy.rlib.debug import ll_assert
-from pypy.rlib.nonconst import NonConstant
-from pypy.translator.stm.stmgcintf import StmOperations
-
-from pypy.rlib.rgc import stm_is_enabled     # re-exported here
-
-
-NUM_THREADS_DEFAULT = 4     # XXX for now
-
-MAIN_THREAD_ID = 0
-
-
-class TransactionError(Exception):
-    pass
-
-class Transaction(object):
-    _next_transaction = None
-    _scheduled = False         # for debugging
-
-    def run(self):
-        # subclasses can access 'self.retry_counter' here
-        raise NotImplementedError
-
-
-def stm_operations():
-    if we_are_translated():
-        return StmOperations
-    else:
-        from pypy.rlib.test.test_rstm import fake_stm_operations
-        return fake_stm_operations
-
-
-def in_transaction():
-    return bool(stm_operations().in_transaction())
-
-def thread_id():
-    return stm_operations().thread_id()
-
-
-def run_all_transactions(initial_transaction,
-                         num_threads = NUM_THREADS_DEFAULT):
-    if in_transaction():
-        raise TransactionError("nested call to rstm.run_all_transactions()")
-    #
-    _transactionalstate.initialize()
-    #
-    # Tell the GC we are entering transactional mode.  This makes
-    # sure that 'initial_transaction' is flagged as GLOBAL.
-    # (Actually it flags all surviving objects as GLOBAL.)
-    # No more GC operation afterwards!
-    llop.stm_enter_transactional_mode(lltype.Void)
-    #
-    # Keep alive 'initial_transaction'.  In truth we would like it to
-    # survive a little bit longer, for the beginning of the C code in
-    # run_all_transactions().  This should be equivalent because there
-    # is no possibility of having a GC collection inbetween.
-    keepalive_until_here(initial_transaction)
-    #
-    # The following line causes the _stm_run_transaction() function to be
-    # generated in the C source with a specific signature, where it
-    # can be called by the C code.
-    llop.nop(lltype.Void, llhelper(StmOperations.RUN_TRANSACTION,
-                                   _stm_run_transaction))
-    #
-    # The same about the _stm_thread_starting() and _stm_thread_stopping()
-    llop.nop(lltype.Void, llhelper(StmOperations.INIT_DONE,
-                                   _stm_thread_starting))
-    llop.nop(lltype.Void, llhelper(StmOperations.INIT_DONE,
-                                   _stm_thread_stopping))
-    #
-    # Tell the C code to run all transactions.
-    ptr = _cast_transaction_to_voidp(initial_transaction)
-    stm_operations().run_all_transactions(ptr, num_threads)
-    #
-    # Tell the GC we are leaving transactional mode.
-    llop.stm_leave_transactional_mode(lltype.Void)
-    #
-    # Hack
-    if not we_are_translated():
-        stm_operations().leaving()
-    #
-    # If an exception was raised, re-raise it here.
-    _transactionalstate.close_exceptions()
-
-
-def _cast_transaction_to_voidp(transaction):
-    if we_are_translated():
-        ptr = cast_instance_to_base_ptr(transaction)
-        return rffi.cast(rffi.VOIDP, ptr)
-    else:
-        return stm_operations().cast_transaction_to_voidp(transaction)
-
-def _cast_voidp_to_transaction(transactionptr):
-    if we_are_translated():
-        ptr = rffi.cast(base_ptr_lltype(), transactionptr)
-        return cast_base_ptr_to_instance(Transaction, ptr)
-    else:
-        return stm_operations().cast_voidp_to_transaction(transactionptr)
-
-
-class _TransactionalState(object):
-    """This is the class of a global singleton, seen by every transaction.
-    Used for cross-transaction synchronization.  Of course writing to it
-    will likely cause conflicts.  Reserved for now for storing the
-    exception that must be re-raised by run_all_transactions().
-    """
-    # The logic ensures that once a transaction calls must_reraise_exception()
-    # and commits, all uncommitted transactions will abort (because they have
-    # read '_reraise_exception' when they started) and then, when they retry,
-    # do nothing.  This makes the transaction committing an exception the last
-    # one to commit, and it cleanly shuts down all other pending transactions.
-
-    def initialize(self):
-        self._reraise_exception = None
-
-    def has_exception(self):
-        return self._reraise_exception is not None
-
-    def must_reraise_exception(self, got_exception):
-        self._got_exception = got_exception
-        self._reraise_exception = self.reraise_exception_callback
-        if not we_are_translated():
-            import sys; self._got_tb = sys.exc_info()[2]
-
-    def close_exceptions(self):
-        if self._reraise_exception is not None:
-            self._reraise_exception()
-
-    @staticmethod
-    def reraise_exception_callback():
-        self = _transactionalstate
-        exc = self._got_exception
-        self._got_exception = None
-        if not we_are_translated() and hasattr(self, '_got_tb'):
-            raise exc.__class__, exc, self._got_tb
-        raise exc
-
-_transactionalstate = _TransactionalState()
-
-
-def _stm_run_transaction(transactionptr, retry_counter):
-    #
-    # Tell the GC we are starting a transaction
-    # (at this point, we have no stack root at all; the following
-    # call will clear any remaining garbage from the shadowstack,
-    # in case of an aborted transaction)
-    llop.stm_start_transaction(lltype.Void)
-    #
-    # Now we can use the GC
-    next = None
-    try:
-        if _transactionalstate.has_exception():
-            # a previously committed transaction raised: don't do anything
-            # more in this transaction
-            pass
-        else:
-            # run!
-            next = _run_really(transactionptr, retry_counter)
-        #
-    except Exception, e:
-        _transactionalstate.must_reraise_exception(e)
-    #
-    # Stop using the GC.  This will make 'next' and all transactions linked
-    # from there GLOBAL objects.
-    llop.stm_stop_transaction(lltype.Void)
-    #
-    # Mark 'next' as kept-alive-until-here.  In truth we would like to
-    # keep it alive after the return, for the C code.  This should be
-    # equivalent because there is no possibility of having a GC collection
-    # inbetween.
-    keepalive_until_here(next)
-    return _cast_transaction_to_voidp(next)
-
-
-def _run_really(transactionptr, retry_counter):
-    # Call the RPython method run() on the Transaction instance.
-    # This logic is in a sub-function because we want to catch
-    # the MemoryErrors that could occur.
-    transaction = _cast_voidp_to_transaction(transactionptr)
-    #
-    # 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
-    transaction._scheduled = False
-    new_transactions = transaction.run()
-    return _link_new_transactions(new_transactions)
-_run_really._dont_inline_ = True
-
-def _link_new_transactions(new_transactions):
-    # in order to schedule the new transactions, we have to return a
-    # raw pointer to the first one, with their field '_next_transaction'
-    # making a linked list.  The C code reads directly from this
-    # field '_next_transaction'.
-    if new_transactions is None:
-        return None
-    n = len(new_transactions) - 1
-    next = None
-    while n >= 0:
-        new_transactions[n]._next_transaction = next
-        next = new_transactions[n]
-        #
-        ll_assert(not next._scheduled,
-                  "the same Transaction instance is scheduled more than once")
-        next._scheduled = True
-        #
-        n -= 1
-    return next
-
-
-def _stm_thread_starting():
-    llop.stm_thread_starting(lltype.Void)
-
-def _stm_thread_stopping():
-    llop.stm_thread_stopping(lltype.Void)
-
-
-class DISABLEDThreadLocal(object):
-    """
-    A thread-local container.  Use only for one or a few static places,
-    e.g. the ExecutionContext in the PyPy interpreter; and store any
-    number of stuff on the ExecutionContext instead.  The point of this
-    is to have proper GC support: if at the end of a transaction some
-    objects are only reachable via a ThreadLocal object, then these
-    objects don't need to be turned GLOBAL.  It avoids the overhead of
-    STM, notably the two copies that are needed for every transaction
-    that changes a GLOBAL object.
-    """
-    STMTHREADLOCAL = lltype.Struct('StmThreadLocal',
-                                   ('content', base_ptr_lltype()),
-                                   hints={'stm_thread_local': True})
-
-    def __init__(self, Class):
-        """NOT_RPYTHON: You can only have a small number of ThreadLocal()
-        instances built during translation."""
-        self.Class = Class
-        self.threadlocal = lltype.malloc(self.STMTHREADLOCAL, immortal=True)
-
-    def _freeze_(self):
-        return True      # but the thread-local value can be read and written
-
-    @specialize.arg(0)
-    def getvalue(self):
-        """Read the thread-local value.
-        It can be either None (the default) or an instance of self.Class."""
-        ptr = self.threadlocal.content
-        return cast_base_ptr_to_instance(self.Class, ptr)
-
-    @specialize.arg(0)
-    def setvalue(self, value):
-        """Write the thread-local value."""
-        assert value is None or isinstance(value, self.Class)
-        ptr = cast_instance_to_base_ptr(value)
-        self.threadlocal.content = ptr
diff --git a/pypy/rlib/test/test_rstm.py b/pypy/rlib/test/test_rstm.py
deleted file mode 100644
--- a/pypy/rlib/test/test_rstm.py
+++ /dev/null
@@ -1,140 +0,0 @@
-import random
-import py
-from pypy.rpython.lltypesystem import lltype, rffi
-from pypy.rlib import rstm
-
-
-class FakeStmOperations:
-    _in_transaction = 0
-    _thread_id = 0
-    _mapping = {}
-
-    def in_transaction(self):
-        return self._in_transaction
-
-    def thread_id(self):
-        return self._thread_id
-
-    def _add(self, transactionptr):
-        r = random.random()
-        assert r not in self._pending    # very bad luck if it is
-        self._pending[r] = transactionptr
-
-    def run_all_transactions(self, initial_transaction_ptr, num_threads=4):
-        self._pending = {}
-        self._add(initial_transaction_ptr)
-        thread_ids = [-10000 - 123 * i for i in range(num_threads)]  # random
-        self._in_transaction = True
-        try:
-            while self._pending:
-                self._thread_id = thread_ids.pop(0)
-                thread_ids.append(self._thread_id)
-                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:
-                    self._add(self.cast_transaction_to_voidp(next))
-                    next = next._next_transaction
-        finally:
-            self._in_transaction = False
-            self._thread_id = 0
-            del self._pending
-
-    def cast_transaction_to_voidp(self, transaction):
-        if transaction is None:
-            return lltype.nullptr(rffi.VOIDP.TO)
-        assert isinstance(transaction, rstm.Transaction)
-        num = 10000 + len(self._mapping)
-        self._mapping[num] = transaction
-        return rffi.cast(rffi.VOIDP, num)
-
-    def cast_voidp_to_transaction(self, transactionptr):
-        if not transactionptr:
-            return None
-        num = rffi.cast(lltype.Signed, transactionptr)
-        return self._mapping[num]
-
-    def leaving(self):
-        self._mapping.clear()
-
-fake_stm_operations = FakeStmOperations()
-
-
-def test_in_transaction():
-    res = rstm.in_transaction()
-    assert res is False
-    res = rstm.thread_id()
-    assert res == 0
-
-def test_run_all_transactions_minimal():
-    seen = []
-    class Empty(rstm.Transaction):
-        def run(self):
-            res = rstm.in_transaction()
-            seen.append(res is True)
-            res = rstm.thread_id()
-            seen.append(res != 0)
-    rstm.run_all_transactions(Empty())
-    assert seen == [True, True]
-
-def test_run_all_transactions_recursive():
-    seen = []
-    class DoInOrder(rstm.Transaction):
-        def run(self):
-            assert self._next_transaction is None
-            if len(seen) < 10:
-                seen.append(len(seen))
-                return [self]
-    rstm.run_all_transactions(DoInOrder())
-    assert seen == range(10)
-
-def test_run_all_transactions_random_order():
-    seen = []
-    class AddToSeen(rstm.Transaction):
-        def run(self):
-            seen.append(self.value)
-    class DoInOrder(rstm.Transaction):
-        count = 0
-        def run(self):
-            assert self._next_transaction is None
-            if self.count < 50:
-                other = AddToSeen()
-                other.value = self.count
-                self.count += 1
-                return [self, other]
-    rstm.run_all_transactions(DoInOrder())
-    assert seen != range(50) and sorted(seen) == range(50)
-
-def test_raise():
-    class MyException(Exception):
-        pass
-    class FooBar(rstm.Transaction):
-        def run(self):
-            raise MyException
-    class DoInOrder(rstm.Transaction):
-        def run(self):
-            return [FooBar() for i in range(10)]
-    py.test.raises(MyException, rstm.run_all_transactions, DoInOrder())
-
-def test_threadlocal():
-    py.test.skip("disabled")
-    # not testing the thread-local factor, but only the general interface
-    class Point:
-        def __init__(self, x, y):
-            self.x = x
-            self.y = y
-    p1 = Point(10, 2)
-    p2 = Point(-1, 0)
-    tl = rstm.ThreadLocal(Point)
-    assert tl.getvalue() is None
-    tl.setvalue(p1)
-    assert tl.getvalue() is p1
-    tl.setvalue(p2)
-    assert tl.getvalue() is p2
-    tl.setvalue(None)
-    assert tl.getvalue() is None
-
-def test_stm_is_enabled():
-    assert rstm.stm_is_enabled() is None    # not translated
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to