diff options
Diffstat (limited to 'pthread_stop_world.c')
-rw-r--r-- | pthread_stop_world.c | 87 |
1 files changed, 42 insertions, 45 deletions
diff --git a/pthread_stop_world.c b/pthread_stop_world.c index b8a548b3..254fca17 100644 --- a/pthread_stop_world.c +++ b/pthread_stop_world.c @@ -287,11 +287,11 @@ STATIC void GC_suspend_handler_inner(ptr_t dummy, void *context); /* The implementation of the function is the same as that of */ /* GC_lookup_thread except for the attribute added here. */ GC_ATTR_NO_SANITIZE_THREAD - static GC_thread GC_lookup_thread_async(pthread_t id) + static GC_thread GC_lookup_thread_async(thread_id_t id) { GC_thread p = GC_threads[THREAD_TABLE_INDEX(id)]; - for (; p != NULL; p = p -> next) { + for (; p != NULL; p = p -> tm.next) { if (THREAD_EQUAL(p -> id, id)) break; } return p; @@ -310,15 +310,14 @@ 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->stop_info.stack_ptr, + ao_store_async((volatile AO_t *)&(me -> 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(); # endif - ao_store_async((volatile AO_t *)&me->stop_info.stack_ptr, - (AO_t)GC_approx_sp()); + ao_store_async((volatile AO_t *)&(me -> stack_ptr), (AO_t)GC_approx_sp()); # endif } @@ -358,8 +357,7 @@ STATIC void GC_suspend_handler_inner(ptr_t dummy, void *context) GC_log_printf("Suspending %p\n", (void *)self); # endif me = GC_lookup_thread_async(self); - if ((me->stop_info.last_stop_count & ~(word)THREAD_RESTARTED) - == my_stop_count) { + if ((me -> last_stop_count & ~(word)THREAD_RESTARTED) == my_stop_count) { /* Duplicate signal. OK if we are retrying. */ if (!GC_retry_signals) { WARN("Duplicate suspend signal in thread %p\n", self); @@ -375,14 +373,14 @@ STATIC void GC_suspend_handler_inner(ptr_t dummy, void *context) me -> backing_store_ptr = bs_lo + stack_size; # endif # ifdef GC_ENABLE_SUSPEND_THREAD - suspend_cnt = (word)ao_load_async(&(me -> stop_info.ext_suspend_cnt)); + suspend_cnt = (word)ao_load_async(&(me -> ext_suspend_cnt)); # endif /* Tell the thread that wants to stop the world that this */ /* thread has been stopped. Note that sem_post() is */ /* the only async-signal-safe primitive in LinuxThreads. */ sem_post(&GC_suspend_ack_sem); - ao_store_release_async(&me->stop_info.last_stop_count, my_stop_count); + ao_store_release_async(&(me -> last_stop_count), my_stop_count); /* Wait until that thread tells us to restart by sending */ /* this thread a GC_sig_thr_restart signal (should be masked */ @@ -400,7 +398,7 @@ STATIC void GC_suspend_handler_inner(ptr_t dummy, void *context) } while (ao_load_acquire_async(&GC_stop_count) == my_stop_count # ifdef GC_ENABLE_SUSPEND_THREAD || ((suspend_cnt & 1) != 0 - && (word)ao_load_async(&(me -> stop_info.ext_suspend_cnt)) + && (word)ao_load_async(&(me -> ext_suspend_cnt)) == suspend_cnt) # endif ); @@ -426,7 +424,7 @@ STATIC void GC_suspend_handler_inner(ptr_t dummy, void *context) sem_post(&GC_suspend_ack_sem); /* Set the flag that the thread has been restarted. */ if (GC_retry_signals) - ao_store_release_async(&me->stop_info.last_stop_count, + ao_store_release_async(&(me -> last_stop_count), my_stop_count | THREAD_RESTARTED); } RESTORE_CANCEL(cancel_state); @@ -622,7 +620,7 @@ STATIC void GC_restart_handler(int sig) # ifdef DEBUG_THREADS GC_log_printf("Suspend self: %p\n", (void *)(me -> id)); # endif - while ((word)ao_load_acquire_async(&(me -> stop_info.ext_suspend_cnt)) + while ((word)ao_load_acquire_async(&(me -> ext_suspend_cnt)) == suspend_cnt) { /* TODO: Use sigsuspend() even for self-suspended threads. */ GC_brief_async_signal_safe_sleep(); @@ -646,21 +644,21 @@ STATIC void GC_restart_handler(int sig) UNLOCK(); return; } - suspend_cnt = (word)(t -> stop_info.ext_suspend_cnt); + suspend_cnt = (word)(t -> ext_suspend_cnt); if ((suspend_cnt & 1) != 0) /* already suspended? */ { GC_ASSERT(!THREAD_EQUAL((pthread_t)thread, pthread_self())); UNLOCK(); return; } if ((t -> flags & (FINISHED | DO_BLOCKING)) != 0) { - t -> stop_info.ext_suspend_cnt = (AO_t)(suspend_cnt | 1); /* suspend */ + t -> ext_suspend_cnt = (AO_t)(suspend_cnt | 1); /* suspend */ /* Terminated but not joined yet, or in do-blocking state. */ UNLOCK(); return; } if (THREAD_EQUAL((pthread_t)thread, pthread_self())) { - t -> stop_info.ext_suspend_cnt = (AO_t)(suspend_cnt | 1); + t -> ext_suspend_cnt = (AO_t)(suspend_cnt | 1); GC_with_callee_saves_pushed(GC_suspend_self_blocked, (ptr_t)t); UNLOCK(); return; @@ -693,8 +691,7 @@ STATIC void GC_restart_handler(int sig) AO_store(&GC_stop_count, next_stop_count); /* Set the flag making the change visible to the signal handler. */ - AO_store_release(&(t -> stop_info.ext_suspend_cnt), - (AO_t)(suspend_cnt | 1)); + AO_store_release(&(t -> ext_suspend_cnt), (AO_t)(suspend_cnt | 1)); /* TODO: Support GC_retry_signals (not needed for TSan) */ switch (raise_signal(t, GC_sig_suspend)) { @@ -724,12 +721,12 @@ STATIC void GC_restart_handler(int sig) LOCK(); t = GC_lookup_thread((pthread_t)thread); if (t != NULL) { - word suspend_cnt = (word)(t -> stop_info.ext_suspend_cnt); + word suspend_cnt = (word)(t -> ext_suspend_cnt); if ((suspend_cnt & 1) != 0) /* is suspended? */ { GC_ASSERT((GC_stop_count & THREAD_RESTARTED) != 0); /* Mark the thread as not suspended - it will be resumed shortly. */ - AO_store(&(t -> stop_info.ext_suspend_cnt), (AO_t)(suspend_cnt + 1)); + AO_store(&(t -> ext_suspend_cnt), (AO_t)(suspend_cnt + 1)); if ((t -> flags & (FINISHED | DO_BLOCKING)) == 0) { int result = raise_signal(t, GC_sig_thr_restart); @@ -761,7 +758,7 @@ STATIC void GC_restart_handler(int sig) LOCK(); t = GC_lookup_thread((pthread_t)thread); - if (t != NULL && (t -> stop_info.ext_suspend_cnt & 1) != 0) + if (t != NULL && (t -> ext_suspend_cnt & 1) != 0) is_suspended = (int)TRUE; UNLOCK(); return is_suspended; @@ -797,12 +794,12 @@ GC_INNER void GC_push_all_stacks(void) GC_log_printf("Pushing stacks from thread %p\n", (void *)self); # endif for (i = 0; i < THREAD_TABLE_SZ; i++) { - for (p = GC_threads[i]; p != 0; p = p -> next) { + for (p = GC_threads[i]; p != NULL; p = p -> tm.next) { # if defined(E2K) || defined(IA64) GC_bool is_self = FALSE; # endif - if (p -> flags & FINISHED) continue; + if (KNOWN_FINISHED(p)) continue; ++nthreads; traced_stack_sect = p -> traced_stack_sect; if (THREAD_EQUAL(p -> id, self)) { @@ -828,7 +825,7 @@ GC_INNER void GC_push_all_stacks(void) is_self = TRUE; # endif } else { - lo = (ptr_t)AO_load((volatile AO_t *)&p->stop_info.stack_ptr); + lo = (ptr_t)AO_load((volatile AO_t *)&(p -> stack_ptr)); # ifdef IA64 bs_hi = p -> backing_store_ptr; # elif defined(E2K) @@ -874,14 +871,14 @@ GC_INNER void GC_push_all_stacks(void) # endif # ifdef NACL /* Push reg_storage as roots, this will cover the reg context. */ - GC_push_all_stack((ptr_t)p -> stop_info.reg_storage, - (ptr_t)(p -> stop_info.reg_storage + NACL_GC_REG_STORAGE_SIZE)); + GC_push_all_stack((ptr_t)p -> reg_storage, + (ptr_t)(p -> reg_storage + NACL_GC_REG_STORAGE_SIZE)); total_size += NACL_GC_REG_STORAGE_SIZE * sizeof(ptr_t); # endif # ifdef E2K if ((GC_stop_count & THREAD_RESTARTED) != 0 # ifdef GC_ENABLE_SUSPEND_THREAD - && (p -> stop_info.ext_suspend_cnt & 1) == 0 + && (p -> ext_suspend_cnt & 1) == 0 # endif && !is_self && (p -> flags & DO_BLOCKING) == 0) continue; /* procedure stack buffer has already been freed */ @@ -933,14 +930,14 @@ STATIC int GC_suspend_all(void) # endif GC_ASSERT(I_HOLD_LOCK()); for (i = 0; i < THREAD_TABLE_SZ; i++) { - for (p = GC_threads[i]; p != 0; p = p -> next) { + for (p = GC_threads[i]; p != NULL; p = p -> tm.next) { if (!THREAD_EQUAL(p -> id, self)) { if ((p -> flags & (FINISHED | DO_BLOCKING)) != 0) continue; # ifndef GC_OPENBSD_UTHREADS # ifdef GC_ENABLE_SUSPEND_THREAD - if ((p -> stop_info.ext_suspend_cnt & 1) != 0) continue; + if ((p -> ext_suspend_cnt & 1) != 0) continue; # endif - if (AO_load(&p->stop_info.last_stop_count) == GC_stop_count) + if (AO_load(&(p -> last_stop_count)) == GC_stop_count) continue; /* matters only if GC_retry_signals */ n_live_threads++; # endif @@ -958,7 +955,7 @@ STATIC int GC_suspend_all(void) GC_release_dirty_lock(); if (pthread_stackseg_np(p->id, &stack)) ABORT("pthread_stackseg_np failed"); - p -> stop_info.stack_ptr = (ptr_t)stack.ss_sp - stack.ss_size; + p -> stack_ptr = (ptr_t)stack.ss_sp - stack.ss_size; if (GC_on_thread_event) GC_on_thread_event(GC_EVENT_THREAD_SUSPENDED, (void *)p->id); @@ -1110,9 +1107,9 @@ 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->stop_info.stack_ptr)); \ - BCOPY(GC_nacl_gc_thread_self->stop_info.stack_ptr, \ - GC_nacl_gc_thread_self->stop_info.reg_storage, \ + : "=m" (GC_nacl_gc_thread_self -> stack_ptr)); \ + BCOPY(GC_nacl_gc_thread_self -> stack_ptr, \ + GC_nacl_gc_thread_self -> reg_storage, \ NACL_GC_REG_STORAGE_SIZE * sizeof(ptr_t)); \ __asm__ __volatile__ ("naclasp $48, %r15"); \ } while (0) @@ -1124,9 +1121,9 @@ 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->stop_info.stack_ptr)); \ - BCOPY(GC_nacl_gc_thread_self->stop_info.stack_ptr, \ - GC_nacl_gc_thread_self->stop_info.reg_storage, \ + : "=m" (GC_nacl_gc_thread_self -> stack_ptr)); \ + BCOPY(GC_nacl_gc_thread_self -> stack_ptr, \ + GC_nacl_gc_thread_self -> reg_storage, \ NACL_GC_REG_STORAGE_SIZE * sizeof(ptr_t));\ __asm__ __volatile__ ("add $16, %esp"); \ } while (0) @@ -1135,11 +1132,11 @@ 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->stop_info.stack_ptr)); \ + : : "r" (&GC_nacl_gc_thread_self -> stack_ptr)); \ __asm__ __volatile__ ("bic r0, r0, #0xc0000000"); \ __asm__ __volatile__ ("str sp, [r0]"); \ - BCOPY(GC_nacl_gc_thread_self->stop_info.stack_ptr, \ - GC_nacl_gc_thread_self->stop_info.reg_storage, \ + BCOPY(GC_nacl_gc_thread_self -> stack_ptr, \ + GC_nacl_gc_thread_self -> reg_storage, \ NACL_GC_REG_STORAGE_SIZE * sizeof(ptr_t)); \ __asm__ __volatile__ ("add sp, sp, #40"); \ __asm__ __volatile__ ("bic sp, sp, #0xc0000000"); \ @@ -1152,7 +1149,7 @@ GC_INNER void GC_stop_world(void) { if (GC_nacl_thread_idx != -1) { NACL_STORE_REGS(); - GC_nacl_gc_thread_self->stop_info.stack_ptr = GC_approx_sp(); + GC_nacl_gc_thread_self -> stack_ptr = GC_approx_sp(); GC_nacl_thread_parked[GC_nacl_thread_idx] = 1; } } @@ -1175,7 +1172,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->stop_info.stack_ptr = GC_approx_sp(); + GC_nacl_gc_thread_self -> stack_ptr = GC_approx_sp(); } GC_nacl_thread_parked[GC_nacl_thread_idx] = 1; while (GC_nacl_park_threads_now) { @@ -1184,7 +1181,7 @@ GC_INNER void GC_stop_world(void) GC_nacl_thread_parked[GC_nacl_thread_idx] = 0; /* Clear out the reg storage for next suspend. */ - BZERO(GC_nacl_gc_thread_self->stop_info.reg_storage, + BZERO(GC_nacl_gc_thread_self -> reg_storage, NACL_GC_REG_STORAGE_SIZE * sizeof(ptr_t)); } } @@ -1268,15 +1265,15 @@ GC_INNER void GC_stop_world(void) GC_ASSERT((GC_stop_count & THREAD_RESTARTED) != 0); # endif for (i = 0; i < THREAD_TABLE_SZ; i++) { - for (p = GC_threads[i]; p != NULL; p = p -> next) { + for (p = GC_threads[i]; p != NULL; p = p -> tm.next) { if (!THREAD_EQUAL(p -> id, self)) { if ((p -> flags & (FINISHED | DO_BLOCKING)) != 0) continue; # ifndef GC_OPENBSD_UTHREADS # ifdef GC_ENABLE_SUSPEND_THREAD - if ((p -> stop_info.ext_suspend_cnt & 1) != 0) continue; + if ((p -> ext_suspend_cnt & 1) != 0) continue; # endif if (GC_retry_signals - && AO_load(&p->stop_info.last_stop_count) == GC_stop_count) + && AO_load(&(p -> last_stop_count)) == GC_stop_count) continue; /* The thread has been restarted. */ n_live_threads++; # endif |