Author: Armin Rigo <[email protected]>
Branch: stmgc-c7
Changeset: r70172:1d78acd6d99b
Date: 2014-03-22 20:01 +0100
http://bitbucket.org/pypy/pypy/changeset/1d78acd6d99b/
Log: import stmgc/a5f0a9669efe
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 @@
-0e5239ae07f2
+a5f0a9669efe
diff --git a/rpython/translator/stm/src_stm/stm/core.c
b/rpython/translator/stm/src_stm/stm/core.c
--- a/rpython/translator/stm/src_stm/stm/core.c
+++ b/rpython/translator/stm/src_stm/stm/core.c
@@ -462,7 +462,7 @@
/* force all other threads to be paused. They will unpause
automatically when we are done here, i.e. at mutex_unlock().
Important: we should not call cond_wait() in the meantime. */
- synchronize_all_threads();
+ synchronize_all_threads(STOP_OTHERS_UNTIL_MUTEX_UNLOCK);
/* detect conflicts */
if (detect_write_read_conflicts())
@@ -501,6 +501,8 @@
if (STM_PSEGMENT->transaction_state == TS_INEVITABLE) {
/* wake up one thread in wait_for_end_of_inevitable_transaction() */
cond_signal(C_INEVITABLE);
+ if (globally_unique_transaction)
+ committed_globally_unique_transaction();
}
/* done */
@@ -673,3 +675,12 @@
s_mutex_unlock();
}
+
+void stm_become_globally_unique_transaction(const char *msg)
+{
+ stm_become_inevitable(msg); /* may still abort */
+
+ s_mutex_lock();
+ synchronize_all_threads(STOP_OTHERS_AND_BECOME_GLOBALLY_UNIQUE);
+ s_mutex_unlock();
+}
diff --git a/rpython/translator/stm/src_stm/stm/forksupport.c
b/rpython/translator/stm/src_stm/stm/forksupport.c
--- a/rpython/translator/stm/src_stm/stm/forksupport.c
+++ b/rpython/translator/stm/src_stm/stm/forksupport.c
@@ -69,7 +69,7 @@
}
s_mutex_lock();
- synchronize_all_threads();
+ synchronize_all_threads(STOP_OTHERS_UNTIL_MUTEX_UNLOCK);
mutex_pages_lock();
/* Make a new mmap at some other address, but of the same size as
diff --git a/rpython/translator/stm/src_stm/stm/gcpage.c
b/rpython/translator/stm/src_stm/stm/gcpage.c
--- a/rpython/translator/stm/src_stm/stm/gcpage.c
+++ b/rpython/translator/stm/src_stm/stm/gcpage.c
@@ -135,7 +135,7 @@
if (is_major_collection_requested()) { /* if still true */
- synchronize_all_threads();
+ synchronize_all_threads(STOP_OTHERS_UNTIL_MUTEX_UNLOCK);
if (is_major_collection_requested()) { /* if *still* true */
major_collection_now_at_safe_point();
diff --git a/rpython/translator/stm/src_stm/stm/sync.c
b/rpython/translator/stm/src_stm/stm/sync.c
--- a/rpython/translator/stm/src_stm/stm/sync.c
+++ b/rpython/translator/stm/src_stm/stm/sync.c
@@ -320,7 +320,9 @@
/* If we are requested to enter a safe-point, we cannot proceed now.
Wait until the safe-point request is removed for us. */
-
+#ifdef STM_TESTS
+ abort_with_mutex();
+#endif
cond_signal(C_AT_SAFE_POINT);
STM_PSEGMENT->safe_point = SP_WAIT_FOR_C_REQUEST_REMOVED;
cond_wait(C_REQUEST_REMOVED);
@@ -328,7 +330,7 @@
}
}
-static void synchronize_all_threads(void)
+static void synchronize_all_threads(enum sync_type_e sync_type)
{
enter_safe_point_if_requested();
@@ -336,7 +338,13 @@
why: if several threads call this function, the first one that
goes past this point will set the "request safe point" on all
other threads; then none of the other threads will go past the
- enter_safe_point_if_requested() above. */
+ enter_safe_point_if_requested() above.
+ */
+ if (UNLIKELY(globally_unique_transaction)) {
+ assert(count_other_threads_sp_running() == 0);
+ return;
+ }
+
signal_everybody_to_pause_running();
/* If some other threads are SP_RUNNING, we cannot proceed now.
@@ -353,6 +361,13 @@
}
}
+ if (UNLIKELY(sync_type == STOP_OTHERS_AND_BECOME_GLOBALLY_UNIQUE)) {
+ globally_unique_transaction = true;
+ assert(STM_SEGMENT->nursery_end == NSE_SIGPAUSE);
+ STM_SEGMENT->nursery_end = NURSERY_END;
+ return; /* don't remove the requests for safe-points in this case */
+ }
+
/* Remove the requests for safe-points now. In principle we should
remove it later, when the caller is done, but this is equivalent
as long as we hold the mutex.
@@ -360,6 +375,15 @@
remove_requests_for_safe_point(); /* => C_REQUEST_REMOVED */
}
+static void committed_globally_unique_transaction(void)
+{
+ assert(globally_unique_transaction);
+ assert(STM_SEGMENT->nursery_end == NURSERY_END);
+ STM_SEGMENT->nursery_end = NSE_SIGPAUSE;
+ globally_unique_transaction = false;
+ remove_requests_for_safe_point();
+}
+
void _stm_collectable_safe_point(void)
{
/* If 'nursery_end' was set to NSE_SIGxxx by another thread,
diff --git a/rpython/translator/stm/src_stm/stm/sync.h
b/rpython/translator/stm/src_stm/stm/sync.h
--- a/rpython/translator/stm/src_stm/stm/sync.h
+++ b/rpython/translator/stm/src_stm/stm/sync.h
@@ -30,6 +30,12 @@
static void release_thread_segment(stm_thread_local_t *tl);
static void wait_for_end_of_inevitable_transaction(bool can_abort);
-static void synchronize_all_threads(void);
-static bool pause_signalled;
+enum sync_type_e {
+ STOP_OTHERS_UNTIL_MUTEX_UNLOCK,
+ STOP_OTHERS_AND_BECOME_GLOBALLY_UNIQUE,
+};
+static void synchronize_all_threads(enum sync_type_e sync_type);
+static void committed_globally_unique_transaction(void);
+
+static bool pause_signalled, globally_unique_transaction;
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
@@ -326,6 +326,14 @@
void stm_call_on_abort(stm_thread_local_t *, void *key, void callback(void *));
+/* Similar to stm_become_inevitable(), but additionally suspend all
+ other threads. A very heavy-handed way to make sure that no other
+ transaction is running concurrently. Avoid as much as possible.
+ Other transactions will continue running only after this transaction
+ commits. */
+void stm_become_globally_unique_transaction(const char *msg);
+
+
/* ==================== END ==================== */
#endif
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit