From fc3c60f6081d85f6274986a7a08b59db1515fcb5 Mon Sep 17 00:00:00 2001 From: nobu Date: Sat, 14 Jun 2008 02:59:19 +0000 Subject: * gc.h (STACK_UPPER): moved from gc.c * thread.c, thread_{pthread,win32}.c (ruby_init_stack, ruby_thread_init_stack): moved stack initialization from gc.c. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@17155 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- ChangeLog | 14 +++++++++ gc.c | 90 ++++---------------------------------------------------- gc.h | 16 +++++++++- thread.c | 6 ++++ thread_pthread.c | 87 ++++++++++++++++++++++++++++++++++++++++++++++++++++-- thread_win32.c | 31 ++++++++++++++++--- vm.c | 25 +++++++--------- 7 files changed, 163 insertions(+), 106 deletions(-) diff --git a/ChangeLog b/ChangeLog index cc683be30d..9b7faa6b2a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,17 @@ +Sat Jun 14 11:59:17 2008 Nobuyoshi Nakada + + * gc.h (STACK_UPPER): moved from gc.c + + * thread.c, thread_{pthread,win32}.c (ruby_init_stack, + ruby_thread_init_stack): moved stack initialization from gc.c. + +Sat Jun 14 11:57:53 2008 Nobuyoshi Nakada + + * gc.h (STACK_UPPER): moved from gc.c + + * thread.c, thread_{pthread,win32}.c (ruby_init_stack, + ruby_thread_init_stack): moved stack initialization from gc.c. + Sat Jun 14 07:52:53 2008 Tanaka Akira * gc.c (ruby_initial_gc_stress): defined. diff --git a/gc.c b/gc.c index 969f1faca4..af88862393 100644 --- a/gc.c +++ b/gc.c @@ -244,25 +244,9 @@ rb_objspace_alloc(void) #define HEAP_OBJ_LIMIT (HEAP_SIZE / sizeof(struct RVALUE)) extern st_table *rb_class_tbl; -VALUE *rb_gc_stack_start = 0; -#ifdef __ia64 -VALUE *rb_gc_register_stack_start = 0; -#endif int ruby_disable_gc_stress = 0; - -#ifdef DJGPP -/* set stack size (http://www.delorie.com/djgpp/v2faq/faq15_9.html) */ -unsigned int _stklen = 0x180000; /* 1.5 kB */ -#endif - -#if defined(DJGPP) || defined(_WIN32_WCE) -size_t rb_gc_stack_maxsize = 65535*sizeof(VALUE); -#else -size_t rb_gc_stack_maxsize = 655300*sizeof(VALUE); -#endif - static void run_final(rb_objspace_t *objspace, VALUE obj); static int garbage_collect(rb_objspace_t *objspace); @@ -790,23 +774,17 @@ rb_data_object_alloc(VALUE klass, void *datap, RUBY_DATA_FUNC dmark, RUBY_DATA_F # define STACK_LENGTH ((STACK_END < STACK_START) ? STACK_START - STACK_END\ : STACK_END - STACK_START + 1) #endif -#if STACK_GROW_DIRECTION > 0 -# define STACK_UPPER(x, a, b) a -#elif STACK_GROW_DIRECTION < 0 -# define STACK_UPPER(x, a, b) b -#else -static int grow_direction; -static int -stack_grow_direction(VALUE *addr) +#if !STACK_GROW_DIRECTION +int ruby_stack_grow_direction; +int +ruby_get_stack_grow_direction(VALUE *addr) { rb_thread_t *th = GET_THREAD(); SET_STACK_END; - if (STACK_END > addr) return grow_direction = 1; - return grow_direction = -1; + if (STACK_END > addr) return ruby_stack_grow_direction = 1; + return ruby_stack_grow_direction = -1; } -# define stack_growup_p(x) ((grow_direction ? grow_direction : stack_grow_direction(x)) > 0) -# define STACK_UPPER(x, a, b) (stack_growup_p(x) ? a : b) #endif #define GC_WATER_MARK 512 @@ -1786,12 +1764,6 @@ rb_gc_start(void) return Qnil; } -void -ruby_set_stack_size(size_t size) -{ - rb_gc_stack_maxsize = size; -} - #undef Init_stack void @@ -1800,53 +1772,6 @@ Init_stack(VALUE *addr) ruby_init_stack(addr); } -#undef ruby_init_stack -void -ruby_init_stack(VALUE *addr -#ifdef __ia64 - , void *bsp -#endif - ) -{ - if (!rb_gc_stack_start || - STACK_UPPER(&addr, - rb_gc_stack_start > addr, - rb_gc_stack_start < addr)) { - rb_gc_stack_start = addr; - } -#ifdef __ia64 - if (!rb_gc_register_stack_start || - (VALUE*)bsp < rb_gc_register_stack_start) { - rb_gc_register_stack_start = (VALUE*)bsp; - } -#endif -#ifdef HAVE_GETRLIMIT - { - struct rlimit rlim; - - if (getrlimit(RLIMIT_STACK, &rlim) == 0) { - unsigned int space = rlim.rlim_cur/5; - - if (space > 1024*1024) space = 1024*1024; - rb_gc_stack_maxsize = rlim.rlim_cur - space; - } - } -#elif defined _WIN32 - { - MEMORY_BASIC_INFORMATION mi; - DWORD size; - DWORD space; - - if (VirtualQuery(&mi, &mi, sizeof(mi))) { - size = (char *)mi.BaseAddress - (char *)mi.AllocationBase; - space = size / 5; - if (space > 1024*1024) space = 1024*1024; - rb_gc_stack_maxsize = size - space; - } - } -#endif -} - /* * Document-class: ObjectSpace * @@ -1881,9 +1806,6 @@ ruby_init_stack(VALUE *addr void Init_heap(void) { - if (!rb_gc_stack_start) { - Init_stack(0); - } init_heap(&rb_objspace); } diff --git a/gc.h b/gc.h index fe2e07ded0..29fd6b407c 100644 --- a/gc.h +++ b/gc.h @@ -57,5 +57,19 @@ rb_gc_debug_body(char *mode, char *msg, int st, void *ptr) #define RUBY_MARK_UNLESS_NULL(ptr) if(RTEST(ptr)){rb_gc_mark(ptr);} #define RUBY_FREE_UNLESS_NULL(ptr) if(ptr){ruby_xfree(ptr);} -#endif /* RUBY_GC_H */ +#if STACK_GROW_DIRECTION > 0 +# define STACK_UPPER(x, a, b) a +#elif STACK_GROW_DIRECTION < 0 +# define STACK_UPPER(x, a, b) b +#else +RUBY_EXTERN int ruby_stack_grow_direction; +int ruby_get_stack_grow_direction(VALUE *addr); +# define stack_growup_p(x) ( \ + (ruby_stack_grow_direction ? \ + ruby_stack_grow_direction : \ + ruby_get_stack_grow_direction(x)) > 0) +# define STACK_UPPER(x, a, b) (stack_growup_p(x) ? a : b) +#endif + +#endif /* RUBY_GC_H */ diff --git a/thread.c b/thread.c index 73adab4b4c..3e501f6816 100644 --- a/thread.c +++ b/thread.c @@ -309,6 +309,12 @@ extern void ruby_error_print(void); static VALUE rb_thread_raise(int, VALUE *, rb_thread_t *); void rb_thread_recycle_stack_release(VALUE *); +void +ruby_thread_init_stack(rb_thread_t *th) +{ + native_thread_init_stack(th); +} + static int thread_start_func_2(rb_thread_t *th, VALUE *stack_start, VALUE *register_stack_start) { diff --git a/thread_pthread.c b/thread_pthread.c index 54b7677146..62ac28b808 100644 --- a/thread_pthread.c +++ b/thread_pthread.c @@ -11,6 +11,12 @@ #ifdef THREAD_SYSTEM_DEPENDENT_IMPLEMENTATION +#include "gc.h" + +#ifdef HAVE_SYS_RESOURCE_H +#include +#endif + static void native_mutex_lock(pthread_mutex_t *lock); static void native_mutex_unlock(pthread_mutex_t *lock); static int native_mutex_trylock(pthread_mutex_t *lock); @@ -164,6 +170,84 @@ native_thread_destroy(rb_thread_t *th) #define USE_THREAD_CACHE 0 +static struct { + rb_thread_id_t id; + size_t stack_maxsize; + VALUE *stack_start; +#ifdef __ia64 + VALUE *register_stack_start; +#endif +} native_main_thread; + +#undef ruby_init_stack +void +ruby_init_stack(VALUE *addr +#ifdef __ia64 + , void *bsp +#endif + ) +{ + native_main_thread.id = pthread_self(); + if (!native_main_thread.stack_start || + STACK_UPPER(&addr, + native_main_thread.stack_start > addr, + native_main_thread.stack_start < addr)) { + native_main_thread.stack_start = addr; + } +#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) { + unsigned int space = rlim.rlim_cur/5; + + if (space > 1024*1024) space = 1024*1024; + native_main_thread.stack_maxsize = rlim.rlim_cur - space; + } + } +#endif +} + +#define CHECK_ERR(expr) \ + {int err = (expr); if (err) {rb_bug("err: %d - %s", err, #expr);}} + +static int +native_thread_init_stack(rb_thread_t *th) +{ + rb_thread_id_t curr = pthread_self(); + + if (pthread_equal(curr, native_main_thread.id)) { + th->machine_stack_start = native_main_thread.stack_start; + th->machine_stack_maxsize = native_main_thread.stack_maxsize; + } + else { +#ifdef HAVE_PTHREAD_GETATTR_NP + pthread_attr_t attr; + CHECK_ERR(pthread_getattr_np(curr, &attr)); +# if defined HAVE_PTHREAD_ATTR_GETSTACK + CHECK_ERR(pthread_attr_getstack(&attr, &th->machine_stack_start, &th->machine_stack_maxsize)); +# elif defined HAVE_PTHREAD_ATTR_GETSTACKSIZE && defined HAVE_PTHREAD_ATTR_GETSTACKADDR + CHECK_ERR(pthread_attr_getstackaddr(&attr, &th->machine_stack_start)); + CHECK_ERR(pthread_attr_getstacksize(&attr, &th->machine_stack_maxsize)); +# endif +#else + rb_raise(rb_eNotImpError, "ruby engine can initialize only in the main thread"); +#endif + } +#ifdef __ia64 + th->machine_register_stack_start = native_main_thread.register_stack_start; + th->machine_stack_maxsize /= 2; + th->machine_register_stack_maxsize = th->machine_stack_maxsize; +#endif + return 0; +} + static void * thread_start_func_1(void *th_ptr) { @@ -282,9 +366,6 @@ use_cached_thread(rb_thread_t *th) return result; } -#define CHECK_ERR(expr) \ - { int err; if ((err = (expr)) != 0) { rb_bug("err: %d - %s", err, #expr); }} - static int native_thread_create(rb_thread_t *th) { diff --git a/thread_win32.c b/thread_win32.c index 2e05524ab2..d1d0886f43 100644 --- a/thread_win32.c +++ b/thread_win32.c @@ -424,6 +424,32 @@ native_cond_destroy(rb_thread_cond_t *cond) /* */ } +void +ruby_init_stack(VALUE *addr) +{ +} + +#define CHECK_ERR(expr) \ + {if (!(expr)) {rb_bug("err: %lu - %s", GetLastError(), #expr);}} + +static void +native_thread_init_stack(rb_thread_t *th) +{ + MEMORY_BASIC_INFORMATION mi; + char *base, *end; + DWORD size, space; + + CHECK_ERR(VirtualQuery(&mi, &mi, sizeof(mi))); + base = mi.AllocationBase; + end = mi.BaseAddress; + end += mi.RegionSize; + size = end - base; + space = size / 5; + if (space > 1024*1024) space = 1024*1024; + th->machine_stack_start = (VALUE *)end - 1; + th->machine_stack_maxsize = size - space; +} + static void native_thread_destroy(rb_thread_t *th) { @@ -441,6 +467,7 @@ thread_start_func_1(void *th_ptr) VALUE stack_start; volatile HANDLE thread_id = th->thread_id; + native_thread_init_stack(th); th->native_thread_data.interrupt_event = CreateEvent(0, TRUE, FALSE, 0); /* run */ @@ -453,16 +480,12 @@ thread_start_func_1(void *th_ptr) return 0; } -extern size_t rb_gc_stack_maxsize; - static int native_thread_create(rb_thread_t *th) { size_t stack_size = 4 * 1024; /* 4KB */ th->thread_id = w32_create_thread(stack_size, thread_start_func_1, th); - th->machine_stack_maxsize = rb_gc_stack_maxsize; /* not tested. */ - if ((th->thread_id) == 0) { st_delete_wrap(th->vm->living_threads, th->self); rb_raise(rb_eThreadError, "can't create Thread (%d)", errno); diff --git a/vm.c b/vm.c index 5814deb20b..64fbe2d1c9 100644 --- a/vm.c +++ b/vm.c @@ -1576,8 +1576,10 @@ thread_alloc(VALUE klass) } static void -th_init2(rb_thread_t *th) +th_init2(rb_thread_t *th, VALUE self) { + th->self = self; + /* allocate thread stack */ th->stack_size = RUBY_VM_THREAD_STACK_SIZE; th->stack = thread_recycle_stack(th->stack_size); @@ -1596,9 +1598,9 @@ th_init2(rb_thread_t *th) } static void -th_init(rb_thread_t *th) +th_init(rb_thread_t *th, VALUE self) { - th_init2(th); + th_init2(th, self); } static VALUE @@ -1608,8 +1610,7 @@ ruby_thread_init(VALUE self) rb_vm_t *vm = GET_THREAD()->vm; GetThreadPtr(self, th); - th_init(th); - th->self = self; + th_init(th, self); th->vm = vm; th->top_wrapper = 0; @@ -1763,6 +1764,7 @@ Init_VM(void) #if defined(ENABLE_VM_OBJSPACE) && ENABLE_VM_OBJSPACE struct rb_objspace *rb_objspace_alloc(void); #endif +void ruby_thread_init_stack(rb_thread_t *th); void Init_BareVM(void) @@ -1780,15 +1782,9 @@ Init_BareVM(void) #endif ruby_current_vm = vm; - th_init2(th); + th_init2(th, 0); th->vm = vm; - th->machine_stack_start = rb_gc_stack_start; - th->machine_stack_maxsize = rb_gc_stack_maxsize; -#ifdef __ia64 - th->machine_register_stack_start = rb_gc_register_stack_start; - th->machine_stack_maxsize /= 2; - th->machine_register_stack_maxsize = th->machine_stack_maxsize; -#endif + ruby_thread_init_stack(th); } /* top self */ @@ -1832,7 +1828,8 @@ rb_ruby_verbose_ptr(void) return ruby_vm_verbose_ptr(GET_VM()); } -VALUE *rb_ruby_debug_ptr(void) +VALUE * +rb_ruby_debug_ptr(void) { return ruby_vm_debug_ptr(GET_VM()); } -- cgit v1.2.3