Author: Armin Rigo <[email protected]>
Branch: c7-fork
Changeset: r1069:a1db46a027b5
Date: 2014-03-18 14:06 +0100
http://bitbucket.org/pypy/stmgc/changeset/a1db46a027b5/
Log: progress
diff --git a/c7/stm/forksupport.c b/c7/stm/forksupport.c
--- a/c7/stm/forksupport.c
+++ b/c7/stm/forksupport.c
@@ -8,10 +8,12 @@
static char *fork_big_copy = NULL;
+static stm_thread_local_t *fork_this_tl;
static char *setup_mmap(char *reason); /* forward, in setup.c */
static void do_or_redo_setup_after_fork(void); /* forward, in setup.c */
static void do_or_redo_teardown_after_fork(void); /* forward, in setup.c */
+static pthread_t *_get_cpth(stm_thread_local_t *);/* forward, in setup.c */
static void forksupport_prepare(void)
@@ -19,15 +21,35 @@
if (stm_object_pages == NULL)
return;
- /* This silently assumes that fork() is not called from transactions.
- It's hard to check though...
- */
+ /* This assumes that fork() is not called from transactions.
+ So far we attempt to check this by walking all stm_thread_local_t,
+ marking the one from the current thread, and verifying that it's not
+ running a transaction. This assumes that the stm_thread_local_t is just
+ a __thread variable, so never changes threads.
+ */
s_mutex_lock();
synchronize_all_threads();
mutex_pages_lock();
+ fork_this_tl = NULL;
+ stm_thread_local_t *tl = stm_all_thread_locals;
+ do {
+ if (pthread_equal(*_get_cpth(tl), pthread_self())) {
+ if (_stm_in_transaction(tl))
+ stm_fatalerror("fork(): cannot be used inside a transaction");
+ if (fork_this_tl != NULL)
+ stm_fatalerror("fork(): found several stm_thread_local_t"
+ " from the same thread");
+ fork_this_tl = tl;
+ }
+ tl = tl->next;
+ } while (tl != stm_all_thread_locals);
+
+ if (fork_this_tl == NULL)
+ stm_fatalerror("fork(): found no stm_thread_local_t from this thread");
+
char *big_copy = setup_mmap("stmgc's fork support");
uintptr_t pagenum, endpagenum;
@@ -80,6 +102,15 @@
mutex_pages_unlock();
s_mutex_unlock();
+ stm_thread_local_t *tl = stm_all_thread_locals;
+ do {
+ stm_thread_local_t *nexttl = tl->next;
+ if (tl != fork_this_tl) {
+ stm_unregister_thread_local(tl);
+ }
+ tl = nexttl;
+ } while (tl != stm_all_thread_locals);
+
do_or_redo_teardown_after_fork();
assert(fork_big_copy != NULL);
diff --git a/c7/stm/setup.c b/c7/stm/setup.c
--- a/c7/stm/setup.c
+++ b/c7/stm/setup.c
@@ -139,7 +139,7 @@
teardown_pages();
}
-void _init_shadow_stack(stm_thread_local_t *tl)
+static void _init_shadow_stack(stm_thread_local_t *tl)
{
struct stm_shadowentry_s *s = (struct stm_shadowentry_s *)
malloc(SHADOW_STACK_SIZE * sizeof(struct stm_shadowentry_s));
@@ -148,13 +148,18 @@
tl->shadowstack_base = s;
}
-void _done_shadow_stack(stm_thread_local_t *tl)
+static void _done_shadow_stack(stm_thread_local_t *tl)
{
free(tl->shadowstack_base);
tl->shadowstack = NULL;
tl->shadowstack_base = NULL;
}
+static pthread_t *_get_cpth(stm_thread_local_t *tl)
+{
+ assert(sizeof(pthread_t) <= sizeof(tl->creating_pthread));
+ return (pthread_t *)(tl->creating_pthread);
+}
void stm_register_thread_local(stm_thread_local_t *tl)
{
@@ -178,6 +183,7 @@
numbers automatically. */
num = (num % NB_SEGMENTS) + 1;
tl->associated_segment_num = num;
+ *_get_cpth(tl) = pthread_self();
_init_shadow_stack(tl);
set_gs_register(get_segment_base(num));
s_mutex_unlock();
diff --git a/c7/stmgc.h b/c7/stmgc.h
--- a/c7/stmgc.h
+++ b/c7/stmgc.h
@@ -69,6 +69,7 @@
/* the next fields are handled internally by the library */
int associated_segment_num;
struct stm_thread_local_s *prev, *next;
+ long creating_pthread[4];
} stm_thread_local_t;
/* this should use llvm's coldcc calling convention,
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit