aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authornobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2008-06-14 02:59:19 +0000
committernobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2008-06-14 02:59:19 +0000
commitfc3c60f6081d85f6274986a7a08b59db1515fcb5 (patch)
tree5b7e96855783c55294b0a9824a598b9b269a991d
parent436b02b3322d6809c2bf4cbadbe8b324a53e07e4 (diff)
downloadruby-fc3c60f6081d85f6274986a7a08b59db1515fcb5.tar.gz
* 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
-rw-r--r--ChangeLog14
-rw-r--r--gc.c90
-rw-r--r--gc.h16
-rw-r--r--thread.c6
-rw-r--r--thread_pthread.c87
-rw-r--r--thread_win32.c31
-rw-r--r--vm.c25
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 <nobu@ruby-lang.org>
+
+ * 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 <nobu@ruby-lang.org>
+
+ * 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 <akr@fsij.org>
* 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 <sys/resource.h>
+#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());
}