[pypy-commit] stmgc c8-gil-like: intermediate check-in, will probably be changed again
arigo
noreply at buildbot.pypy.org
Wed Jun 10 22:50:15 CEST 2015
Author: Armin Rigo <arigo at tunes.org>
Branch: c8-gil-like
Changeset: r1798:c3d3a85bd978
Date: 2015-06-10 21:57 +0200
http://bitbucket.org/pypy/stmgc/changeset/c3d3a85bd978/
Log: intermediate check-in, will probably be changed again
diff --git a/c8/stm/detach.c b/c8/stm/detach.c
--- a/c8/stm/detach.c
+++ b/c8/stm/detach.c
@@ -5,17 +5,18 @@
/* _stm_detached_inevitable_from_thread is:
- - NULL: there is no inevitable transaction, or it is not detached
+ - 0: there is no inevitable transaction, or it is not detached
- a stm_thread_local_t pointer: this thread-local has detached its
own inevitable transaction, and might concurrently reattach to it
at any time
- - a stm_thread_local_t pointer with the last bit set to 1: another
- thread ran synchronize_all_threads(), so in order to reattach,
- the detaching thread must first go through
- s_mutex_lock()/s_mutex_unlock().
+ - DETACHED_AND_FETCHED: another thread ran
+ synchronize_all_threads(), so in order to reattach, the detaching
+ thread must first go through s_mutex_lock()/s_mutex_unlock().
*/
+#define DETACHED_AND_FETCHED 1
+
volatile uintptr_t _stm_detached_inevitable_from_thread;
@@ -38,6 +39,20 @@
}
}
+static struct stm_priv_segment_info_s *detached_and_fetched(void)
+{
+ long i;
+ struct stm_priv_segment_info_s *result = NULL;
+ for (i = 1; i < NB_SEGMENTS; i++) {
+ if (get_priv_segment(i)->safe_point == SP_RUNNING_DETACHED_FETCHED) {
+ assert(result == NULL);
+ result = get_priv_segment(i);
+ }
+ }
+ assert(result != NULL);
+ return result;
+}
+
void _stm_reattach_transaction(uintptr_t old, stm_thread_local_t *tl)
{
if (old == 0) {
@@ -46,19 +61,17 @@
return;
}
- if (old & 1) {
+ if (old == DETACHED_AND_FETCHED) {
/* The detached transaction was fetched; wait until the s_mutex_lock
- is free.
+ is free. The fetched transaction can only be reattached by the
+ code here; there should be no risk of its state changing while
+ we wait.
*/
- stm_thread_local_t *old_tl;
struct stm_priv_segment_info_s *pseg;
-
- old_tl = (stm_thread_local_t *)(--old);
- pseg = get_priv_segment(old_tl->last_associated_segment_num);
- assert(pseg->safe_point = SP_RUNNING_DETACHED_FETCHED);
-
s_mutex_lock();
+ pseg = detached_and_fetched();
pseg->safe_point = SP_RUNNING;
+ old = (uintptr_t)pseg->running_thread;
s_mutex_unlock();
}
@@ -88,13 +101,11 @@
old = _stm_detached_inevitable_from_thread;
if (old == 0)
return false;
- if (old & 1) {
- /* we have the mutex here, so this detached transaction with the
- last bit set cannot reattach in parallel */
- tl = (stm_thread_local_t *)(old - 1);
- pseg = get_priv_segment(tl->last_associated_segment_num);
- assert(pseg->safe_point == SP_RUNNING_DETACHED_FETCHED);
- (void)pseg;
+ if (old < NB_SEGMENTS) {
+ /* we have the mutex here, so this fetched detached transaction
+ cannot get reattached in parallel */
+ assert(get_priv_segment(old)->safe_point ==
+ SP_RUNNING_DETACHED_FETCHED);
return true;
}
@@ -115,3 +126,17 @@
_stm_commit_transaction();
_stm_start_transaction(tl);
}
+
+static void commit_own_inevitable_detached_transaction(stm_thread_local_t *tl)
+{
+ uintptr_t cur = _stm_detached_inevitable_from_thread;
+ if ((cur & ~1) == (uintptr_t)tl) {
+ stm_enter_transactional_zone(tl);
+ _stm_commit_transaction();
+ }
+}
+
+REWRITE:. we need a function to grab and commit the detached inev transaction
+anyway. So kill the special values of _stm_detached_inevitable_from_thread.
+And call that function from core.c when we wait for the inev transaction to
+finish
diff --git a/c8/stm/detach.h b/c8/stm/detach.h
--- a/c8/stm/detach.h
+++ b/c8/stm/detach.h
@@ -1,3 +1,4 @@
static void setup_detach(void);
static bool fetch_detached_transaction(void);
+static void commit_own_inevitable_detached_transaction(stm_thread_local_t *tl);
diff --git a/c8/stm/setup.c b/c8/stm/setup.c
--- a/c8/stm/setup.c
+++ b/c8/stm/setup.c
@@ -264,6 +264,9 @@
void stm_unregister_thread_local(stm_thread_local_t *tl)
{
+ /* If we own the detached inevitable transaction, commit it now */
+ commit_own_inevitable_detached_transaction(tl);
+
s_mutex_lock();
assert(tl->prev != NULL);
assert(tl->next != NULL);
More information about the pypy-commit
mailing list