예제 #1
0
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));
}
예제 #2
0
파일: thread_pthread.c 프로젝트: amtep/ruby
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;
    }
}
예제 #3
0
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;
    }
}
예제 #4
0
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
}
예제 #5
0
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;
}
예제 #6
0
/* 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 */
	}
    }
}
예제 #7
0
파일: gc.c 프로젝트: adamsanderson/potion
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;
}