static void fiber_set_stack_location(void) { rb_thread_t *th = GET_THREAD(); VALUE *ptr; SET_MACHINE_STACK_END(&ptr); th->machine_stack_start = (void*)(((VALUE)ptr & RB_PAGE_MASK) + STACK_UPPER((void *)&ptr, 0, RB_PAGE_SIZE)); }
void ruby_init_stack(volatile VALUE *addr #ifdef __ia64 , void *bsp #endif ) { native_main_thread.id = pthread_self(); #ifdef STACK_END_ADDRESS native_main_thread.stack_start = STACK_END_ADDRESS; #else if (!native_main_thread.stack_start || STACK_UPPER((VALUE *)(void *)&addr, native_main_thread.stack_start > addr, native_main_thread.stack_start < addr)) { native_main_thread.stack_start = (VALUE *)addr; } #endif #ifdef __ia64 if (!native_main_thread.register_stack_start || (VALUE*)bsp < native_main_thread.register_stack_start) { native_main_thread.register_stack_start = (VALUE*)bsp; } #endif { size_t size = 0; size_t space = 0; #if defined(STACKADDR_AVAILABLE) void* stackaddr; STACK_GROW_DIR_DETECTION; get_stack(&stackaddr, &size); space = STACK_DIR_UPPER((char *)addr - (char *)stackaddr, (char *)stackaddr - (char *)addr); #elif defined(HAVE_GETRLIMIT) struct rlimit rlim; if (getrlimit(RLIMIT_STACK, &rlim) == 0) { size = (size_t)rlim.rlim_cur; } space = size > 5 * 1024 * 1024 ? 1024 * 1024 : size / 5; #endif native_main_thread.stack_maxsize = size - space; } }
void ruby_init_stack(volatile VALUE *addr #ifdef __ia64 , void *bsp #endif ) { native_main_thread.id = pthread_self(); #ifdef STACK_END_ADDRESS native_main_thread.stack_start = STACK_END_ADDRESS; #else if (!native_main_thread.stack_start || STACK_UPPER((VALUE *)(void *)&addr, native_main_thread.stack_start > addr, native_main_thread.stack_start < addr)) { native_main_thread.stack_start = (VALUE *)addr; } #endif #ifdef __ia64 if (!native_main_thread.register_stack_start || (VALUE*)bsp < native_main_thread.register_stack_start) { native_main_thread.register_stack_start = (VALUE*)bsp; } #endif { size_t size = 0; size_t space = 0; #if defined(HAVE_PTHREAD_ATTR_GET_NP) void* addr; get_stack(&addr, &size); #elif defined(HAVE_GETRLIMIT) struct rlimit rlim; if (getrlimit(RLIMIT_STACK, &rlim) == 0) { size = (size_t)rlim.rlim_cur; } #endif space = size > 5 * 1024 * 1024 ? 1024 * 1024 : size / 5; native_main_thread.stack_maxsize = size - space; } }
void ruby_init_stack(VALUE *addr #ifdef __ia64 , void *bsp #endif ) { native_main_thread.id = pthread_self(); #ifdef STACK_END_ADDRESS native_main_thread.stack_start = STACK_END_ADDRESS; #else if (!native_main_thread.stack_start || STACK_UPPER((VALUE *)(void *)&addr, native_main_thread.stack_start > addr, native_main_thread.stack_start < addr)) { native_main_thread.stack_start = addr; } #endif #ifdef __ia64 if (!native_main_thread.register_stack_start || (VALUE*)bsp < native_main_thread.register_stack_start) { native_main_thread.register_stack_start = (VALUE*)bsp; } #endif #ifdef HAVE_GETRLIMIT { struct rlimit rlim; if (getrlimit(RLIMIT_STACK, &rlim) == 0) { size_t space = (size_t)(rlim.rlim_cur/5); if (space > 1024*1024) space = 1024*1024; native_main_thread.stack_maxsize = (size_t)rlim.rlim_cur - space; } } #endif }
int ruby_cleanup(int ex) { int state; volatile VALUE errs[2]; rb_thread_t *th = GET_THREAD(); int nerr; errs[1] = th->errinfo; th->safe_level = 0; Init_stack((void*)&errs[STACK_UPPER(errs, 0, 1)]); PUSH_TAG(); if ((state = EXEC_TAG()) == 0) { SAVE_ROOT_JMPBUF(th, ruby_finalize_0()); } POP_TAG(); errs[0] = th->errinfo; PUSH_TAG(); if ((state = EXEC_TAG()) == 0) { SAVE_ROOT_JMPBUF(th, rb_thread_terminate_all()); } else if (ex == 0) { ex = state; } th->errinfo = errs[1]; ex = error_handle(ex); ruby_finalize_1(); POP_TAG(); rb_thread_stop_timer_thread(); for (nerr = 0; nerr < sizeof(errs) / sizeof(errs[0]); ++nerr) { VALUE err = errs[nerr]; if (!RTEST(err)) continue; /* th->errinfo contains a NODE while break'ing */ if (TYPE(err) == T_NODE) continue; if (rb_obj_is_kind_of(err, rb_eSystemExit)) { return sysexit_status(err); } else if (rb_obj_is_kind_of(err, rb_eSignal)) { VALUE sig = rb_iv_get(err, "signo"); ruby_default_signal(NUM2INT(sig)); } else if (ex == 0) { ex = 1; } } #if EXIT_SUCCESS != 0 || EXIT_FAILURE != 1 switch (ex) { #if EXIT_SUCCESS != 0 case 0: return EXIT_SUCCESS; #endif #if EXIT_FAILURE != 1 case 1: return EXIT_FAILURE; #endif } #endif return ex; }
/* Set stack bottom of Ruby implementation. * * You must call this function before any heap allocation by Ruby implementation. * Or GC will break living objects */ void ruby_init_stack(volatile VALUE *addr #ifdef __ia64 , void *bsp #endif ) { native_main_thread.id = pthread_self(); #if MAINSTACKADDR_AVAILABLE if (native_main_thread.stack_maxsize) return; { void* stackaddr; size_t size; if (get_main_stack(&stackaddr, &size) == 0) { native_main_thread.stack_maxsize = size; native_main_thread.stack_start = stackaddr; reserve_stack(stackaddr, size); return; } } #endif #ifdef STACK_END_ADDRESS native_main_thread.stack_start = STACK_END_ADDRESS; #else if (!native_main_thread.stack_start || STACK_UPPER((VALUE *)(void *)&addr, native_main_thread.stack_start > addr, native_main_thread.stack_start < addr)) { native_main_thread.stack_start = (VALUE *)addr; } #endif #ifdef __ia64 if (!native_main_thread.register_stack_start || (VALUE*)bsp < native_main_thread.register_stack_start) { native_main_thread.register_stack_start = (VALUE*)bsp; } #endif { #if defined(HAVE_GETRLIMIT) #if defined(PTHREAD_STACK_DEFAULT) # if PTHREAD_STACK_DEFAULT < RUBY_STACK_SPACE*5 # error "PTHREAD_STACK_DEFAULT is too small" # endif size_t size = PTHREAD_STACK_DEFAULT; #else size_t size = RUBY_VM_THREAD_VM_STACK_SIZE; #endif size_t space; int pagesize = getpagesize(); struct rlimit rlim; STACK_GROW_DIR_DETECTION; if (getrlimit(RLIMIT_STACK, &rlim) == 0) { size = (size_t)rlim.rlim_cur; } addr = native_main_thread.stack_start; if (IS_STACK_DIR_UPPER()) { space = ((size_t)((char *)addr + size) / pagesize) * pagesize - (size_t)addr; } else { space = (size_t)addr - ((size_t)((char *)addr - size) / pagesize + 1) * pagesize; } native_main_thread.stack_maxsize = space; #endif } /* If addr is out of range of main-thread stack range estimation, */ /* it should be on co-routine (alternative stack). [Feature #2294] */ { void *start, *end; STACK_GROW_DIR_DETECTION; if (IS_STACK_DIR_UPPER()) { start = native_main_thread.stack_start; end = (char *)native_main_thread.stack_start + native_main_thread.stack_maxsize; } else { start = (char *)native_main_thread.stack_start - native_main_thread.stack_maxsize; end = native_main_thread.stack_start; } if ((void *)addr < start || (void *)addr > end) { /* out of range */ native_main_thread.stack_start = (VALUE *)addr; native_main_thread.stack_maxsize = 0; /* unknown */ } } }
PN_SIZE potion_stack_len(Potion *P, _PN **p) { _PN *esp, *c = P->mem->cstack; POTION_ESP(&esp); if (p) *p = STACK_UPPER(c, esp); return esp < c ? c - esp : esp - c + 1; }