Author: Remi Meier <[email protected]>
Branch: stmgc-c4
Changeset: r67867:e1fc1f6c0821
Date: 2013-11-06 19:51 +0100
http://bitbucket.org/pypy/pypy/changeset/e1fc1f6c0821/
Log: import stmgc that allows nesting of
stop_all_other_threads()-resume_..
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 @@
-8a3b7748ba7f
+14ac008e70a5
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,11 +78,17 @@
d->max_aborts = max_aborts;
}
+static void start_exclusivelock(void);
+static void stop_exclusivelock(void);
int stm_enter_callback_call(void)
{
int token = (thread_descriptor == NULL);
dprintf(("enter_callback_call(tok=%d)\n", token));
if (token == 1) {
+ /* acquire exclusive lock. Just to be safe...
+ XXX: remove again when sure it is not needed
+ (interaction with stop_all_other_threads()) */
+ start_exclusivelock();
stmgcpage_acquire_global_lock();
#ifdef STM_BARRIER_COUNT
static int seen = 0;
@@ -95,6 +101,7 @@
stmgc_init_nursery();
init_shadowstack();
stmgcpage_release_global_lock();
+ stop_exclusivelock();
}
BeginInevitableTransaction(0);
return token;
@@ -109,11 +116,13 @@
CommitTransaction(0);
if (token == 1) {
+ start_exclusivelock();
stmgcpage_acquire_global_lock();
done_shadowstack();
stmgc_done_nursery();
DescriptorDone();
stmgcpage_release_global_lock();
+ stop_exclusivelock();
}
}
@@ -293,6 +302,7 @@
void stm_stop_sharedlock(void)
{
+ assert(in_single_thread == NULL);
dprintf(("stm_stop_sharedlock\n"));
//assert(stmgc_nursery_hiding(thread_descriptor, 1));
int err = pthread_rwlock_unlock(&rwlock_shared);
@@ -312,6 +322,7 @@
static void stop_exclusivelock(void)
{
+ assert(in_single_thread == NULL);
dprintf(("stop_exclusivelock\n"));
int err = pthread_rwlock_unlock(&rwlock_shared);
if (err != 0)
@@ -320,17 +331,22 @@
}
+static int single_thread_nesting = 0;
void stm_stop_all_other_threads(void)
{ /* push gc roots! */
struct tx_descriptor *d;
BecomeInevitable("stop_all_other_threads");
- stm_start_single_thread();
-
- for (d = stm_tx_head; d; d = d->tx_next) {
- if (*d->active_ref == 1) // && d != thread_descriptor) <- TRUE
- AbortTransactionAfterCollect(d, ABRT_OTHER_THREADS);
+ if (!single_thread_nesting) {
+ assert(in_single_thread == NULL);
+ stm_start_single_thread();
+
+ for (d = stm_tx_head; d; d = d->tx_next) {
+ if (*d->active_ref == 1) // && d != thread_descriptor) <- TRUE
+ AbortTransactionAfterCollect(d, ABRT_OTHER_THREADS);
+ }
}
+ single_thread_nesting++;
}
@@ -340,20 +356,23 @@
assert(stm_active == 2);
int atomic = d->atomic;
- /* Give up atomicity during commit. This still works because
- we keep the inevitable status, thereby being guaranteed to
- commit before all others. */
- stm_atomic(-atomic);
-
- /* Commit and start new inevitable transaction while never
- giving up the inevitable status. */
- CommitTransaction(1); /* 1=stay_inevitable! */
- BeginInevitableTransaction(1);
-
- /* restore atomic-count */
- stm_atomic(atomic);
-
- stm_stop_single_thread();
+ single_thread_nesting--;
+ if (single_thread_nesting == 0) {
+ /* Give up atomicity during commit. This still works because
+ we keep the inevitable status, thereby being guaranteed to
+ commit before all others. */
+ stm_atomic(-atomic);
+
+ /* Commit and start new inevitable transaction while never
+ giving up the inevitable status. */
+ CommitTransaction(1); /* 1=stay_inevitable! */
+ BeginInevitableTransaction(1);
+
+ /* restore atomic-count */
+ stm_atomic(atomic);
+
+ stm_stop_single_thread();
+ }
}
void stm_start_single_thread(void)
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit