[pypy-commit] pypy stmgc-c4: Fix start_new_thread with stm.
arigo
noreply at buildbot.pypy.org
Mon Jul 1 17:21:06 CEST 2013
Author: Armin Rigo <arigo at tunes.org>
Branch: stmgc-c4
Changeset: r65142:f0f5f39180fd
Date: 2013-07-01 17:13 +0200
http://bitbucket.org/pypy/pypy/changeset/f0f5f39180fd/
Log: Fix start_new_thread with stm.
diff --git a/rpython/memory/gc/stmgc.py b/rpython/memory/gc/stmgc.py
--- a/rpython/memory/gc/stmgc.py
+++ b/rpython/memory/gc/stmgc.py
@@ -53,9 +53,10 @@
needs_finalizer=False,
is_finalizer_light=False,
contains_weakptr=False):
- ll_assert(not needs_finalizer, 'XXX')
- ll_assert(not is_finalizer_light, 'XXX')
- ll_assert(not contains_weakptr, 'XXX')
+ # XXX finalizers are ignored for now
+ #ll_assert(not needs_finalizer, 'XXX needs_finalizer')
+ #ll_assert(not is_finalizer_light, 'XXX is_finalizer_light')
+ ll_assert(not contains_weakptr, 'XXX contains_weakptr')
# XXX call optimized versions, e.g. if size < GC_NURSERY_SECTION
return llop.stm_allocate(llmemory.GCREF, size, typeid16)
diff --git a/rpython/memory/gctransform/stmframework.py b/rpython/memory/gctransform/stmframework.py
--- a/rpython/memory/gctransform/stmframework.py
+++ b/rpython/memory/gctransform/stmframework.py
@@ -50,12 +50,7 @@
class StmRootWalker(BaseRootWalker):
def need_thread_support(self, gctransformer, getfn):
- def thread_start():
- llop.stm_initialize(lltype.Void)
- def thread_die():
- llop.stm_finalize(lltype.Void)
- self.thread_start_ptr = getfn(thread_start, [], annmodel.s_None)
- self.thread_die_ptr = getfn(thread_die, [], annmodel.s_None)
+ pass
def walk_stack_roots(self, collect_stack_root):
raise NotImplementedError
diff --git a/rpython/rlib/rstm.py b/rpython/rlib/rstm.py
--- a/rpython/rlib/rstm.py
+++ b/rpython/rlib/rstm.py
@@ -47,17 +47,21 @@
after_external_call._transaction_break_ = True
def enter_callback_call():
- # XXX assumes that we're not called in a fresh new thread
- llop.stm_begin_inevitable_transaction(lltype.Void)
- return 0
+ return llop.stm_enter_callback_call(lltype.Signed)
enter_callback_call._dont_reach_me_in_del_ = True
enter_callback_call._transaction_break_ = True
-def leave_callback_call(ignored):
- llop.stm_commit_transaction(lltype.Void)
+def leave_callback_call(token):
+ llop.stm_leave_callback_call(lltype.Void, token)
leave_callback_call._dont_reach_me_in_del_ = True
leave_callback_call._transaction_break_ = True
+def invoke_around_extcall():
+ """Initialize the STM system. Must be called once from the start-up."""
+ from rpython.rlib.objectmodel import invoke_around_extcall
+ invoke_around_extcall(before_external_call, after_external_call,
+ enter_callback_call, leave_callback_call)
+
# ____________________________________________________________
def make_perform_transaction(func, CONTAINERP):
diff --git a/rpython/rtyper/lltypesystem/lloperation.py b/rpython/rtyper/lltypesystem/lloperation.py
--- a/rpython/rtyper/lltypesystem/lloperation.py
+++ b/rpython/rtyper/lltypesystem/lloperation.py
@@ -441,6 +441,8 @@
'stm_change_atomic': LLOp(),
'stm_get_atomic': LLOp(sideeffects=False),
'stm_perform_transaction':LLOp(),
+ 'stm_enter_callback_call':LLOp(),
+ 'stm_leave_callback_call':LLOp(),
'stm_threadlocalref_get': LLOp(sideeffects=False),
'stm_threadlocalref_set': LLOp(),
diff --git a/rpython/translator/c/funcgen.py b/rpython/translator/c/funcgen.py
--- a/rpython/translator/c/funcgen.py
+++ b/rpython/translator/c/funcgen.py
@@ -604,6 +604,8 @@
OP_STM_THREADLOCAL_GET = _OP_STM
OP_STM_THREADLOCAL_SET = _OP_STM
OP_STM_PERFORM_TRANSACTION = _OP_STM
+ OP_STM_ENTER_CALLBACK_CALL = _OP_STM
+ OP_STM_LEAVE_CALLBACK_CALL = _OP_STM
def OP_PTR_NONZERO(self, op):
diff --git a/rpython/translator/stm/funcgen.py b/rpython/translator/stm/funcgen.py
--- a/rpython/translator/stm/funcgen.py
+++ b/rpython/translator/stm/funcgen.py
@@ -151,6 +151,14 @@
arg1 = funcgen.expr(op.args[1])
return 'stm_perform_transaction((gcptr)%s, %s);' % (arg0, arg1)
+def stm_enter_callback_call(funcgen, op):
+ result = funcgen.expr(op.result)
+ return '%s = stm_enter_callback_call();' % (result,)
+
+def stm_leave_callback_call(funcgen, op):
+ arg0 = funcgen.expr(op.args[0])
+ return 'stm_leave_callback_call(%s);' % (arg0,)
+
def op_stm(funcgen, op):
func = globals()[op.opname]
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
@@ -1539,15 +1539,14 @@
__thread gcptr stm_thread_local_obj;
-int DescriptorInit(void)
+void DescriptorInit(void)
{
if (GCFLAG_PREBUILT != PREBUILT_FLAGS)
{
stm_fatalerror("fix PREBUILT_FLAGS in stmgc.h by giving "
"it the same value as GCFLAG_PREBUILT!\n");
}
-
- if (thread_descriptor == NULL)
+ else
{
revision_t i;
struct tx_descriptor *d = stm_malloc(sizeof(struct tx_descriptor));
@@ -1595,16 +1594,14 @@
d->tx_next = stm_tx_head;
if (d->tx_next != NULL) d->tx_next->tx_prev = d;
stm_tx_head = d;
+ assert(thread_descriptor == NULL);
thread_descriptor = d;
dprintf(("[%lx] pthread %lx starting\n",
(long)d->public_descriptor_index, (long)pthread_self()));
stmgcpage_init_tls();
- return 1;
}
- else
- return 0;
}
void DescriptorDone(void)
diff --git a/rpython/translator/stm/src_stm/et.h b/rpython/translator/stm/src_stm/et.h
--- a/rpython/translator/stm/src_stm/et.h
+++ b/rpython/translator/stm/src_stm/et.h
@@ -194,7 +194,7 @@
_Bool stm_has_got_any_lock(struct tx_descriptor *);
struct tx_public_descriptor *stm_get_free_public_descriptor(revision_t *);
-int DescriptorInit(void);
+void DescriptorInit(void);
void DescriptorDone(void);
#endif /* _ET_H */
diff --git a/rpython/translator/stm/src_stm/revision b/rpython/translator/stm/src_stm/revision
--- a/rpython/translator/stm/src_stm/revision
+++ b/rpython/translator/stm/src_stm/revision
@@ -1,1 +1,1 @@
-bf56c12295c8
+637f6c9d19f7
diff --git a/rpython/translator/stm/src_stm/stmgc.h b/rpython/translator/stm/src_stm/stmgc.h
--- a/rpython/translator/stm/src_stm/stmgc.h
+++ b/rpython/translator/stm/src_stm/stmgc.h
@@ -49,6 +49,12 @@
void stm_initialize(void);
void stm_finalize(void);
+/* alternate initializers/deinitializers, to use for places that may or
+ may not be recursive, like callbacks from C code. The return value
+ of the first one must be passed as argument to the second. */
+int stm_enter_callback_call(void);
+void stm_leave_callback_call(int);
+
/* read/write barriers (the most general versions only for now) */
#if 0 // (optimized version below)
gcptr stm_read_barrier(gcptr);
diff --git a/rpython/translator/stm/src_stm/stmsync.c b/rpython/translator/stm/src_stm/stmsync.c
--- a/rpython/translator/stm/src_stm/stmsync.c
+++ b/rpython/translator/stm/src_stm/stmsync.c
@@ -78,29 +78,46 @@
d->max_aborts = max_aborts;
}
+int stm_enter_callback_call(void)
+{
+ int token = (thread_descriptor == NULL);
+ if (token == 1) {
+ stmgcpage_acquire_global_lock();
+ DescriptorInit();
+ stmgc_init_nursery();
+ init_shadowstack();
+ stmgcpage_release_global_lock();
+ }
+ BeginInevitableTransaction();
+ return token;
+}
+
+void stm_leave_callback_call(int token)
+{
+ if (token == 1)
+ stmgc_minor_collect(); /* force everything out of the nursery */
+
+ CommitTransaction();
+
+ if (token == 1) {
+ stmgcpage_acquire_global_lock();
+ done_shadowstack();
+ stmgc_done_nursery();
+ DescriptorDone();
+ stmgcpage_release_global_lock();
+ }
+}
+
void stm_initialize(void)
{
- stmgcpage_acquire_global_lock();
- int r = DescriptorInit();
+ int r = stm_enter_callback_call();
if (r != 1)
- stm_fatalerror("stm_initialize: DescriptorInit failure\n");
- stmgc_init_nursery();
- init_shadowstack();
- //stmgcpage_init_tls();
- stmgcpage_release_global_lock();
- BeginInevitableTransaction();
+ stm_fatalerror("stm_initialize: already initialized\n");
}
void stm_finalize(void)
{
- stmgc_minor_collect(); /* force everything out of the nursery */
- CommitTransaction();
- stmgcpage_acquire_global_lock();
- //stmgcpage_done_tls();
- done_shadowstack();
- stmgc_done_nursery();
- DescriptorDone();
- stmgcpage_release_global_lock();
+ stm_leave_callback_call(1);
}
/************************************************************/
diff --git a/rpython/translator/stm/test/targetdemo2.py b/rpython/translator/stm/test/targetdemo2.py
--- a/rpython/translator/stm/test/targetdemo2.py
+++ b/rpython/translator/stm/test/targetdemo2.py
@@ -1,7 +1,7 @@
import time
from rpython.rlib import rthread
from rpython.rlib import rstm, jit
-from rpython.rlib.objectmodel import invoke_around_extcall, we_are_translated
+from rpython.rlib.objectmodel import we_are_translated
from rpython.rlib.objectmodel import compute_identity_hash
from rpython.rlib.debug import ll_assert
from rpython.rtyper.lltypesystem import lltype, rffi, rclass
@@ -250,8 +250,7 @@
def setup_threads():
#space.threadlocals.setup_threads(space)
bootstrapper.setup()
- invoke_around_extcall(rstm.before_external_call, rstm.after_external_call,
- rstm.enter_callback_call, rstm.leave_callback_call)
+ rstm.invoke_around_extcall()
def start_thread(args):
bootstrapper.acquire(args)
diff --git a/rpython/translator/stm/test/test_ztranslated.py b/rpython/translator/stm/test/test_ztranslated.py
--- a/rpython/translator/stm/test/test_ztranslated.py
+++ b/rpython/translator/stm/test/test_ztranslated.py
@@ -62,12 +62,11 @@
glob = Global()
#
def threadfn():
- rthread.gc_thread_start()
x = Global()
x.value = 0
glob.seen = x
- rthread.gc_thread_die()
def entry_point(argv):
+ rstm.invoke_around_extcall()
glob.seen = None
rthread.start_new_thread(threadfn, ())
while glob.seen is None:
More information about the pypy-commit
mailing list