Project

General

Profile

Feature #14487 ยป 0001-simplify-altstack-and-enable-reuse-with-thread-cache.patch

normalperson (Eric Wong), 02/18/2018 09:28 PM

View differences:

gc.c
heap_add_pages(objspace, heap_eden, gc_params.heap_init_slots / HEAP_PAGE_OBJ_LIMIT);
init_mark_stack(&objspace->mark_stack);
#ifdef USE_SIGALTSTACK
{
/* altstack of another threads are allocated in another place */
rb_thread_t *th = GET_THREAD();
void *tmp = th->altstack;
th->altstack = malloc(rb_sigaltstack_size());
free(tmp); /* free previously allocated area */
}
#endif
objspace->profile.invoke_time = getrusage_time();
finalizer_table = st_init_numtable();
}
internal.h
/* signal.c */
extern int ruby_enable_coredump;
int rb_get_next_signal(void);
int rb_sigaltstack_size(void);
/* st.c */
extern void rb_hash_bulk_insert(long, const VALUE *, VALUE);
signal.c
#endif
#ifdef USE_SIGALTSTACK
int
static int
rb_sigaltstack_size(void)
{
/* XXX: BSD_vfprintf() uses >1500KiB stack and x86-64 need >5KiB stack. */
......
}
/* alternate stack for SIGSEGV */
void
rb_register_sigaltstack(rb_thread_t *th)
void *
rb_register_sigaltstack(void)
{
stack_t newSS, oldSS;
if (!th->altstack)
rb_bug("rb_register_sigaltstack: th->altstack not initialized\n");
newSS.ss_sp = th->altstack;
newSS.ss_size = rb_sigaltstack_size();
newSS.ss_sp = xmalloc(newSS.ss_size);
newSS.ss_flags = 0;
sigaltstack(&newSS, &oldSS); /* ignore error. */
return newSS.ss_sp;
}
#endif /* USE_SIGALTSTACK */
......
install_sighandler(SIGILL, (sighandler_t)sigill);
#endif
#ifdef SIGSEGV
# ifdef USE_SIGALTSTACK
rb_register_sigaltstack(GET_THREAD());
# endif
RB_ALTSTACK_INIT(GET_VM()->main_altstack);
install_sighandler(SIGSEGV, (sighandler_t)sigsegv);
#endif
}
thread.c
rb_thread_list_t *join_list;
rb_thread_t *main_th;
VALUE errinfo = Qnil;
# ifdef USE_SIGALTSTACK
void rb_register_sigaltstack(rb_thread_t *th);
rb_register_sigaltstack(th);
# endif
if (th == th->vm->main_thread)
rb_bug("thread_start_func_2 must not be used for main thread");
thread_pthread.c
thread_start_func_1(void *th_ptr)
{
rb_thread_t *th = th_ptr;
RB_ALTSTACK_INIT(void *altstack);
#if USE_THREAD_CACHE
thread_start:
#endif
......
}
}
#endif
RB_ALTSTACK_FREE(altstack);
return 0;
}
vm.c
vm->frozen_strings = 0;
}
rb_vm_gvl_destroy(vm);
RB_ALTSTACK_FREE(vm->main_altstack);
if (objspace) {
rb_objspace_free(objspace);
}
......
RUBY_GC_INFO("main thread\n");
}
else {
#ifdef USE_SIGALTSTACK
free(th->altstack);
#endif
ruby_xfree(ptr);
}
......
th->self = self;
rb_threadptr_root_fiber_setup(th);
/* allocate thread stack */
#ifdef USE_SIGALTSTACK
/* altstack of main thread is reallocated in another place */
th->altstack = malloc(rb_sigaltstack_size());
#endif
{
/* vm_stack_size is word number.
* th->vm->default_params.thread_vm_stack_size is byte size. */
vm_core.h
#endif
#if defined(SIGSEGV) && defined(HAVE_SIGALTSTACK) && defined(SA_SIGINFO) && !defined(__NetBSD__)
#define USE_SIGALTSTACK
# define USE_SIGALTSTACK
void *rb_register_sigaltstack(void);
# define RB_ALTSTACK_INIT(var) var = rb_register_sigaltstack()
# define RB_ALTSTACK_FREE(var) xfree(var)
#else /* noop */
# define RB_ALTSTACK_INIT(var)
# define RB_ALTSTACK_FREE(var)
#endif
/*****************/
......
struct rb_thread_struct *main_thread;
struct rb_thread_struct *running_thread;
#ifdef USE_SIGALTSTACK
void *main_altstack;
#endif
struct list_head waiting_fds; /* <=> struct waiting_fd */
struct list_head living_threads;
......
/* misc */
unsigned int abort_on_exception: 1;
unsigned int report_on_exception: 1;
#ifdef USE_SIGALTSTACK
void *altstack;
#endif
uint32_t running_time_us; /* 12500..800000 */
VALUE name;
} rb_thread_t;
-
    (1-1/1)