summaryrefslogtreecommitdiff
path: root/pthread_stop_world.c
diff options
context:
space:
mode:
authorIvan Maidanski <ivmai@mail.ru>2022-12-11 11:16:30 +0300
committerIvan Maidanski <ivmai@mail.ru>2022-12-11 11:23:02 +0300
commit7eb49a4e623cd6a73c595b077697702e345ce00a (patch)
tree615efaa3981369764c8278c29834882a5941c232 /pthread_stop_world.c
parent99a571390d13d93f4fe321c40bd22759518e4ca4 (diff)
downloadbdwgc-7eb49a4e623cd6a73c595b077697702e345ce00a.tar.gz
Move stack-related fields out of GC_thread to GC_stack_context_t
(refactoring) Issue #362 (bdwgc). * darwin_stop_world.c (GC_stack_range_for): Define and crtn local variable; use crtn instead of p to access stack_ptr, topOfStack, stack_end, altstack, altstack_size, normstack, normstack_size, backing_store_end, backing_store_ptr. * pthread_stop_world.c [!NACL] (GC_suspend_handler_inner, GC_push_all_stacks): Likewise. * pthread_support.c [!GC_NO_FINALIZATION] (GC_reset_finalizer_nested, GC_check_finalizer_nested): Likewise. * pthread_support.c [!GC_WIN32_THREADS] (GC_register_altstack): Likewise. * pthread_support.c (do_blocking_enter, do_blocking_leave, GC_set_stackbottom, GC_get_my_stackbottom, GC_call_with_gc_active): Likewise. * win32_threads.c (GC_push_stack_for, GC_get_next_stack): Likewise. * darwin_stop_world.c (GC_push_all_stacks): Use p->crtn instead of p to access traced_stack_sect. * win32_threads.c (GC_suspend, GC_stop_world, GC_start_world): Likewise. * include/private/pthread_support.h (GC_StackContext_Rep): New struct type (move dummy, stack_end, stack_ptr, last_stack_min, initial_stack_base, topOfStack, backing_store_end, backing_store_ptr, altstack, altstack_size, normstack, normstack_size, finalizer_nested, finalizer_skipped, traced_stack_sect from GC_Thread_Rep). * include/private/pthread_support.h [!GC_NO_THREADS_DISCOVERY && GC_WIN32_THREADS] (GC_StackContext_Rep.stack_end): Add volatile. * include/private/pthread_support.h [!GC_NO_FINALIZATION] (GC_StackContext_Rep.fnlz_pad): New field. * include/private/pthread_support.h (GC_stack_context_t): New type. * include/private/pthread_support.h (GC_Thread_Rep.crtn, GC_Thread_Rep.flags_pad): New field. * include/private/pthread_support.h [GC_NO_FINALIZATION] (GC_Thread_Rep.no_fnlz_pad): Remove field. * include/private/pthread_support.h (GC_threads): Move (and refine) comment from GC_Thread_Rep. * include/private/pthread_support.h [GC_WIN32_THREADS] (GC_record_stack_base): Change me argument to crtn. * pthread_stop_world.c [!NACL] (GC_store_stack_ptr): Likewise. * pthread_support.c (GC_record_stack_base): Likewise. * pthread_stop_world.c [NACL] (NACL_STORE_REGS, nacl_pre_syscall_hook, __nacl_suspend_thread_if_needed): Use p->crtn instead of p to access stack_ptr. * pthread_support.c (first_crtn): New static variable. * pthread_support.c (first_thread): Update comment. * pthread_support.c (first_thread_used): Remove variable. * pthread_support.c (GC_push_thread_structures): Push first_thread.crtn symbol * pthread_support.c (GC_push_thread_structures): Push first_crtn.backing_store_end instead of that in first_thread. * pthread_support.c [MPROTECT_VDB && GC_WIN32_THREADS] (GC_win32_unprotect_thread): Call GC_remove_protection() for t->crtn. * pthread_support.c (GC_new_thread): Use first_thread.crtn!=0 instead of first_thread_used; set first_thread.crtn to &first_crtn; allocate GC_StackContext_Rep object using GC_INTERNAL_MALLOC() and store the pointer to result->crtn. * pthread_support.c [CPPCHECK] (GC_new_thread): Call GC_noop1() for first_thread.flags_pad, for first_crtn.dummy instead of result->dummy, and for first_crtn.fnlz_pad instead of result->no_fnlz_pad. * pthread_support.c (GC_delete_thread): Call GC_INTERNAL_FREE(p->crtn) along with that for p. * pthread_support.c [CAN_HANDLE_FORK && (!THREAD_SANITIZER || !CAN_CALL_ATFORK)] (GC_remove_all_threads_but_me): Likewise. * pthread_support.c [GC_PTHREADS] (GC_pthread_join, GC_pthread_detach): Likewise. * pthread_support.c (GC_segment_is_thread_stack, GC_greatest_stack_base_below): Use p->crtn instead of p to access stack_end. * pthread_support.c (GC_call_with_gc_active): Move assertions about me fields to be after LOCK; add assertion that me->crtn==crtn. * win32_threads.c (dll_thread_table): Make it static. * win32_threads.c [!GC_NO_THREADS_DISCOVERY] (dll_crtn_table): New static variable. * win32_threads.c (GC_register_my_thread_inner): Reformat comment; set me->crtn. * win32_threads.c (GC_push_stack_for): Define stack_end local variable; immediately return (zero) if stack_end is NULL. * win32_threads.c (GC_push_all_stacks): Call GC_push_stack_for() (and increment nthreads) even if stack_end is NULL. * win32_threads.c (GC_get_next_stack): Rename s local variable to stack_end.
Diffstat (limited to 'pthread_stop_world.c')
-rw-r--r--pthread_stop_world.c70
1 files changed, 37 insertions, 33 deletions
diff --git a/pthread_stop_world.c b/pthread_stop_world.c
index 993db7d9..4099ae95 100644
--- a/pthread_stop_world.c
+++ b/pthread_stop_world.c
@@ -298,7 +298,7 @@ STATIC void GC_suspend_handler_inner(ptr_t dummy, void *context);
# define GC_lookup_thread_async GC_lookup_thread
#endif
-GC_INLINE void GC_store_stack_ptr(GC_thread me)
+GC_INLINE void GC_store_stack_ptr(GC_stack_context_t crtn)
{
/* There is no data race between the suspend handler (storing */
/* stack_ptr) and GC_push_all_stacks (fetching stack_ptr) because */
@@ -308,14 +308,15 @@ GC_INLINE void GC_store_stack_ptr(GC_thread me)
/* and fetched (by GC_push_all_stacks) using the atomic primitives to */
/* avoid the related TSan warning. */
# ifdef SPARC
- ao_store_async((volatile AO_t *)&(me -> stack_ptr),
+ ao_store_async((volatile AO_t *)&(crtn -> stack_ptr),
(AO_t)GC_save_regs_in_stack());
/* TODO: regs saving already done by GC_with_callee_saves_pushed */
# else
# ifdef IA64
- me -> backing_store_ptr = GC_save_regs_in_stack();
+ crtn -> backing_store_ptr = GC_save_regs_in_stack();
# endif
- ao_store_async((volatile AO_t *)&(me -> stack_ptr), (AO_t)GC_approx_sp());
+ ao_store_async((volatile AO_t *)&(crtn -> stack_ptr),
+ (AO_t)GC_approx_sp());
# endif
}
@@ -323,6 +324,7 @@ STATIC void GC_suspend_handler_inner(ptr_t dummy, void *context)
{
pthread_t self;
GC_thread me;
+ GC_stack_context_t crtn;
# ifdef E2K
ptr_t bs_lo;
size_t stack_size;
@@ -363,12 +365,13 @@ STATIC void GC_suspend_handler_inner(ptr_t dummy, void *context)
RESTORE_CANCEL(cancel_state);
return;
}
- GC_store_stack_ptr(me);
+ crtn = me -> crtn;
+ GC_store_stack_ptr(crtn);
# ifdef E2K
- GC_ASSERT(NULL == me -> backing_store_end);
+ GC_ASSERT(NULL == crtn -> backing_store_end);
GET_PROCEDURE_STACK_LOCAL(&bs_lo, &stack_size);
- me -> backing_store_end = bs_lo;
- me -> backing_store_ptr = bs_lo + stack_size;
+ crtn -> backing_store_end = bs_lo;
+ crtn -> backing_store_ptr = bs_lo + stack_size;
# endif
# ifdef GC_ENABLE_SUSPEND_THREAD
suspend_cnt = (word)ao_load_async(&(me -> ext_suspend_cnt));
@@ -405,10 +408,10 @@ STATIC void GC_suspend_handler_inner(ptr_t dummy, void *context)
GC_log_printf("Continuing %p\n", (void *)self);
# endif
# ifdef E2K
- GC_ASSERT(me -> backing_store_end == bs_lo);
+ GC_ASSERT(crtn -> backing_store_end == bs_lo);
FREE_PROCEDURE_STACK_LOCAL(bs_lo, stack_size);
- me -> backing_store_ptr = NULL;
- me -> backing_store_end = NULL;
+ crtn -> backing_store_ptr = NULL;
+ crtn -> backing_store_end = NULL;
# endif
# ifndef GC_NETBSD_THREADS_WORKAROUND
@@ -797,10 +800,11 @@ GC_INNER void GC_push_all_stacks(void)
# if defined(E2K) || defined(IA64)
GC_bool is_self = FALSE;
# endif
+ GC_stack_context_t crtn = p -> crtn;
if (KNOWN_FINISHED(p)) continue;
++nthreads;
- traced_stack_sect = p -> traced_stack_sect;
+ traced_stack_sect = crtn -> traced_stack_sect;
if (THREAD_EQUAL(p -> id, self)) {
GC_ASSERT((p -> flags & DO_BLOCKING) == 0);
# ifdef SPARC
@@ -810,7 +814,7 @@ GC_INNER void GC_push_all_stacks(void)
# ifdef IA64
bs_hi = GC_save_regs_in_stack();
# elif defined(E2K)
- GC_ASSERT(NULL == p -> backing_store_end);
+ GC_ASSERT(NULL == crtn -> backing_store_end);
(void)GC_save_regs_in_stack();
{
size_t stack_size;
@@ -824,25 +828,25 @@ GC_INNER void GC_push_all_stacks(void)
is_self = TRUE;
# endif
} else {
- lo = (ptr_t)AO_load((volatile AO_t *)&(p -> stack_ptr));
+ lo = (ptr_t)AO_load((volatile AO_t *)&(crtn -> stack_ptr));
# ifdef IA64
- bs_hi = p -> backing_store_ptr;
+ bs_hi = crtn -> backing_store_ptr;
# elif defined(E2K)
- bs_lo = p -> backing_store_end;
- bs_hi = p -> backing_store_ptr;
+ bs_lo = crtn -> backing_store_end;
+ bs_hi = crtn -> backing_store_ptr;
# endif
if (traced_stack_sect != NULL
- && traced_stack_sect->saved_stack_ptr == lo) {
+ && traced_stack_sect -> saved_stack_ptr == lo) {
/* If the thread has never been stopped since the recent */
/* GC_call_with_gc_active invocation then skip the top */
/* "stack section" as stack_ptr already points to. */
- traced_stack_sect = traced_stack_sect->prev;
+ traced_stack_sect = traced_stack_sect -> prev;
}
}
if (EXPECT((p -> flags & MAIN_THREAD) == 0, TRUE)) {
- hi = p -> stack_end;
+ hi = crtn -> stack_end;
# ifdef IA64
- bs_lo = p -> backing_store_end;
+ bs_lo = crtn -> backing_store_end;
# endif
} else {
/* The original stack. */
@@ -855,10 +859,10 @@ GC_INNER void GC_push_all_stacks(void)
GC_log_printf("Stack for thread %p is [%p,%p)\n",
(void *)p->id, (void *)lo, (void *)hi);
# endif
- if (0 == lo) ABORT("GC_push_all_stacks: sp not set!");
- if (p->altstack != NULL && (word)p->altstack <= (word)lo
- && (word)lo <= (word)p->altstack + p->altstack_size) {
- hi = p->altstack + p->altstack_size;
+ if (NULL == lo) ABORT("GC_push_all_stacks: sp not set!");
+ if (crtn -> altstack != NULL && (word)(crtn -> altstack) <= (word)lo
+ && (word)lo <= (word)(crtn -> altstack) + crtn -> altstack_size) {
+ hi = crtn -> altstack + crtn -> altstack_size;
/* FIXME: Need to scan the normal stack too, but how ? */
/* FIXME: Assume stack grows down */
}
@@ -1085,8 +1089,8 @@ GC_INNER void GC_stop_world(void)
__asm__ __volatile__ ("push %r14"); \
__asm__ __volatile__ ("push %r15"); \
__asm__ __volatile__ ("mov %%esp, %0" \
- : "=m" (GC_nacl_gc_thread_self -> stack_ptr)); \
- BCOPY(GC_nacl_gc_thread_self -> stack_ptr, \
+ : "=m" (GC_nacl_gc_thread_self -> crtn -> stack_ptr)); \
+ BCOPY(GC_nacl_gc_thread_self -> crtn -> stack_ptr, \
GC_nacl_gc_thread_self -> reg_storage, \
NACL_GC_REG_STORAGE_SIZE * sizeof(ptr_t)); \
__asm__ __volatile__ ("naclasp $48, %r15"); \
@@ -1099,8 +1103,8 @@ GC_INNER void GC_stop_world(void)
__asm__ __volatile__ ("push %esi"); \
__asm__ __volatile__ ("push %edi"); \
__asm__ __volatile__ ("mov %%esp, %0" \
- : "=m" (GC_nacl_gc_thread_self -> stack_ptr)); \
- BCOPY(GC_nacl_gc_thread_self -> stack_ptr, \
+ : "=m" (GC_nacl_gc_thread_self -> crtn -> stack_ptr)); \
+ BCOPY(GC_nacl_gc_thread_self -> crtn -> stack_ptr, \
GC_nacl_gc_thread_self -> reg_storage, \
NACL_GC_REG_STORAGE_SIZE * sizeof(ptr_t));\
__asm__ __volatile__ ("add $16, %esp"); \
@@ -1110,10 +1114,10 @@ GC_INNER void GC_stop_world(void)
do { \
__asm__ __volatile__ ("push {r4-r8,r10-r12,lr}"); \
__asm__ __volatile__ ("mov r0, %0" \
- : : "r" (&GC_nacl_gc_thread_self -> stack_ptr)); \
+ : : "r" (&GC_nacl_gc_thread_self -> crtn -> stack_ptr)); \
__asm__ __volatile__ ("bic r0, r0, #0xc0000000"); \
__asm__ __volatile__ ("str sp, [r0]"); \
- BCOPY(GC_nacl_gc_thread_self -> stack_ptr, \
+ BCOPY(GC_nacl_gc_thread_self -> crtn -> stack_ptr, \
GC_nacl_gc_thread_self -> reg_storage, \
NACL_GC_REG_STORAGE_SIZE * sizeof(ptr_t)); \
__asm__ __volatile__ ("add sp, sp, #40"); \
@@ -1127,7 +1131,7 @@ GC_INNER void GC_stop_world(void)
{
if (GC_nacl_thread_idx != -1) {
NACL_STORE_REGS();
- GC_nacl_gc_thread_self -> stack_ptr = GC_approx_sp();
+ GC_nacl_gc_thread_self -> crtn -> stack_ptr = GC_approx_sp();
GC_nacl_thread_parked[GC_nacl_thread_idx] = 1;
}
}
@@ -1150,7 +1154,7 @@ GC_INNER void GC_stop_world(void)
/* so don't bother storing registers again, the GC has a set. */
if (!GC_nacl_thread_parked[GC_nacl_thread_idx]) {
NACL_STORE_REGS();
- GC_nacl_gc_thread_self -> stack_ptr = GC_approx_sp();
+ GC_nacl_gc_thread_self -> crtn -> stack_ptr = GC_approx_sp();
}
GC_nacl_thread_parked[GC_nacl_thread_idx] = 1;
while (GC_nacl_park_threads_now) {