Author: Armin Rigo <[email protected]>
Branch:
Changeset: r336:637f6c9d19f7
Date: 2013-07-01 16:17 +0200
http://bitbucket.org/pypy/stmgc/changeset/637f6c9d19f7/
Log: stm_enter_callback_call(), for possibly-recursive invocations
diff --git a/c4/et.c b/c4/et.c
--- a/c4/et.c
+++ b/c4/et.c
@@ -1538,15 +1538,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));
@@ -1594,16 +1593,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/c4/et.h b/c4/et.h
--- a/c4/et.h
+++ b/c4/et.h
@@ -193,7 +193,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/c4/stmgc.h b/c4/stmgc.h
--- a/c4/stmgc.h
+++ b/c4/stmgc.h
@@ -48,6 +48,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/c4/stmsync.c b/c4/stmsync.c
--- a/c4/stmsync.c
+++ b/c4/stmsync.c
@@ -77,29 +77,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/c4/test/support.py b/c4/test/support.py
--- a/c4/test/support.py
+++ b/c4/test/support.py
@@ -63,6 +63,8 @@
void stm_set_transaction_length(long length_max);
_Bool stm_should_break_transaction(void);
long stm_atomic(long delta);
+ int stm_enter_callback_call(void);
+ void stm_leave_callback_call(int);
/* extra non-public code */
void printfcolor(char *msg);
diff --git a/c4/test/test_et.py b/c4/test/test_et.py
--- a/c4/test/test_et.py
+++ b/c4/test/test_et.py
@@ -630,7 +630,15 @@
assert lib.stm_hash(p) != lib.stm_id(p)
run_parallel(f1, f2)
-
-
-
-
+def test_enter_callback_call():
+ lib.stm_commit_transaction()
+ x = lib.stm_enter_callback_call()
+ assert x == 0
+ lib.stm_leave_callback_call(x)
+ lib.stm_begin_inevitable_transaction()
+ #
+ lib.stm_finalize()
+ x = lib.stm_enter_callback_call()
+ assert x == 1
+ lib.stm_leave_callback_call(x)
+ lib.stm_initialize_tests(0)
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit