Author: Remi Meier <[email protected]>
Branch:
Changeset: r1664:e32b94df8ecb
Date: 2015-02-25 13:15 +0100
http://bitbucket.org/pypy/stmgc/changeset/e32b94df8ecb/
Log: c8: add some marker macros and stop/resume_all_other_threads
diff --git a/c8/stm/core.c b/c8/stm/core.c
--- a/c8/stm/core.c
+++ b/c8/stm/core.c
@@ -1089,6 +1089,27 @@
}
+void stm_stop_all_other_threads(void)
+{
+ if (!stm_is_inevitable()) /* may still abort */
+ _stm_become_inevitable("stop_all_other_threads");
+
+ s_mutex_lock();
+ synchronize_all_threads(STOP_OTHERS_AND_BECOME_GLOBALLY_UNIQUE);
+ s_mutex_unlock();
+}
+
+void stm_resume_all_other_threads(void)
+{
+ /* this calls 'committed_globally_unique_transaction()' even though
+ we're not committing now. It's a way to piggyback on the existing
+ implementation for stm_become_globally_unique_transaction(). */
+ s_mutex_lock();
+ committed_globally_unique_transaction();
+ s_mutex_unlock();
+}
+
+
static inline void _synchronize_fragment(stm_char *frag, ssize_t frag_size)
{
diff --git a/c8/stmgc.h b/c8/stmgc.h
--- a/c8/stmgc.h
+++ b/c8/stmgc.h
@@ -269,6 +269,37 @@
void stm_become_globally_unique_transaction(stm_thread_local_t *tl, const char
*msg);
void stm_validate(void);
+/* Temporarily stop all the other threads, by waiting until they
+ reach a safe-point. Don't nest the calls to stop/resume and make sure
+ that resume is called. The current transaction is turned inevitable. */
+void stm_stop_all_other_threads(void);
+void stm_resume_all_other_threads(void);
+
+
+/* Convenience macros to push the markers into the shadowstack */
+#define STM_PUSH_MARKER(tl, odd_num, p) do { \
+ uintptr_t _odd_num = (odd_num); \
+ assert(_odd_num & 1); \
+ STM_PUSH_ROOT(tl, _odd_num); \
+ STM_PUSH_ROOT(tl, p); \
+} while (0)
+
+#define STM_POP_MARKER(tl) ({ \
+ object_t *_popped = STM_POP_ROOT_RET(tl); \
+ STM_POP_ROOT_RET(tl); \
+ _popped; \
+})
+
+#define STM_UPDATE_MARKER_NUM(tl, odd_num) do { \
+ uintptr_t _odd_num = (odd_num); \
+ assert(_odd_num & 1); \
+ struct stm_shadowentry_s *_ss = (tl).shadowstack - 2; \
+ while (!(((uintptr_t)(_ss->ss)) & 1)) { \
+ _ss--; \
+ assert(_ss >= (tl).shadowstack_base); \
+ } \
+ _ss->ss = (object_t *)_odd_num; \
+} while (0)
/* Support for light finalizers. This is a simple version of
diff --git a/c8/test/support.py b/c8/test/support.py
--- a/c8/test/support.py
+++ b/c8/test/support.py
@@ -78,6 +78,8 @@
bool _check_abort_transaction(void);
bool _check_become_inevitable(stm_thread_local_t *tl);
bool _check_become_globally_unique_transaction(stm_thread_local_t *tl);
+bool _check_stop_all_other_threads(void);
+void stm_resume_all_other_threads(void);
int stm_is_inevitable(void);
long current_segment_num(void);
@@ -225,6 +227,10 @@
CHECKED(stm_become_globally_unique_transaction(tl, "TESTGUT"));
}
+bool _check_stop_all_other_threads(void) {
+ CHECKED(stm_stop_all_other_threads());
+}
+
bool _check_stm_validate(void) {
CHECKED(stm_validate());
}
@@ -668,3 +674,11 @@
tl = self.tls[self.current_thread]
if lib._check_become_globally_unique_transaction(tl):
raise Conflict()
+
+ def stop_all_other_threads(self):
+ if lib._check_stop_all_other_threads():
+ raise Conflict()
+
+ def resume_all_other_threads(self):
+ if lib.stm_resume_all_other_threads():
+ raise Conflict()
diff --git a/c8/test/test_extra.py b/c8/test/test_extra.py
--- a/c8/test/test_extra.py
+++ b/c8/test/test_extra.py
@@ -192,3 +192,24 @@
assert lib.stm_is_inevitable()
#
py.test.raises(Conflict, self.switch, 0)
+
+ def test_stm_stop_all_other_threads_1(self):
+ self.start_transaction()
+ #
+ self.switch(1)
+ self.start_transaction()
+ self.stop_all_other_threads()
+ assert lib.stm_is_inevitable()
+ #
+ py.test.raises(Conflict, self.switch, 0)
+
+ def test_stm_stop_all_other_threads_2(self):
+ self.start_transaction()
+ #
+ self.switch(1)
+ self.start_transaction()
+ self.stop_all_other_threads()
+ self.resume_all_other_threads()
+ assert lib.stm_is_inevitable()
+ #
+ self.switch(0) # no conflict
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit