Author: Armin Rigo <ar...@tunes.org> 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 pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit