summaryrefslogtreecommitdiff
path: root/thread_pthread.c
diff options
context:
space:
mode:
authorusa <usa@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2014-07-03 04:36:58 +0000
committerusa <usa@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2014-07-03 04:36:58 +0000
commit750e2a7db7bf61b6e28c1472b106112f07048df4 (patch)
treee9393c99a68c6b9240f0726e93126ae44078f66b /thread_pthread.c
parent60fb08739642c2eee7ea4aacd946cee9393ca454 (diff)
merge revision(s) 44712,44715,44716,44722,44725,44726,44753: [Backport #9454] [Backport #9945]
* thread_pthread.c: get current main thread stack size, which may be expanded than allocated size at initialization, by rlimit(). [ruby-core:60113] [Bug #9454] * thread_pthread.c: get current main thread stack size, which may be expanded than allocated size at initialization, by rlimit(). [ruby-core:60113] [Bug #9454] * thread_pthread.c: rlimit is only available on Linux. At least r44712 breaks FreeBSD. [ruby-core:60113] [Bug #9454] * thread_pthread.c (ruby_init_stack, ruby_stack_overflowed_p): place get_stack above others to get stack boundary information. [ruby-core:60113] [Bug #9454] * thread_pthread.c (ruby_init_stack, ruby_stack_overflowed_p): place get_stack above others to get stack boundary information. [ruby-core:60113] [Bug #9454] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_2_0_0@46667 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'thread_pthread.c')
-rw-r--r--thread_pthread.c87
1 files changed, 57 insertions, 30 deletions
diff --git a/thread_pthread.c b/thread_pthread.c
index 55e2856e43..11b665fda4 100644
--- a/thread_pthread.c
+++ b/thread_pthread.c
@@ -633,6 +633,18 @@ ruby_init_stack(volatile VALUE *addr
)
{
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;
+ return;
+ }
+ }
+#endif
#ifdef STACK_END_ADDRESS
native_main_thread.stack_start = STACK_END_ADDRESS;
#else
@@ -650,6 +662,7 @@ ruby_init_stack(volatile VALUE *addr
}
#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"
@@ -658,15 +671,7 @@ ruby_init_stack(volatile VALUE *addr
#else
size_t size = RUBY_VM_THREAD_VM_STACK_SIZE;
#endif
- size_t space = space_size(size);
-#if MAINSTACKADDR_AVAILABLE
- void* stackaddr;
- STACK_GROW_DIR_DETECTION;
- if (get_stack(&stackaddr, &size) == 0) {
- space = STACK_DIR_UPPER((char *)addr - (char *)stackaddr, (char *)stackaddr - (char *)addr);
- }
- native_main_thread.stack_maxsize = size - space;
-#elif defined(HAVE_GETRLIMIT)
+ size_t space;
int pagesize = getpagesize();
struct rlimit rlim;
STACK_GROW_DIR_DETECTION;
@@ -716,8 +721,8 @@ 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;
+ th->machine.stack_start = native_main_thread.stack_start;
+ th->machine.stack_maxsize = native_main_thread.stack_maxsize;
}
else {
#ifdef STACKADDR_AVAILABLE
@@ -725,17 +730,22 @@ native_thread_init_stack(rb_thread_t *th)
size_t size;
if (get_stack(&start, &size) == 0) {
- th->machine_stack_start = start;
- th->machine_stack_maxsize = size;
+ th->machine.stack_start = start;
+ th->machine.stack_maxsize = size;
+ }
+#elif defined get_stack_of
+ if (!th->machine.stack_maxsize) {
+ native_mutex_lock(&th->interrupt_lock);
+ native_mutex_unlock(&th->interrupt_lock);
}
#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;
+ 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;
}
@@ -762,7 +772,7 @@ thread_start_func_1(void *th_ptr)
native_thread_init(th);
/* run */
#if defined USE_NATIVE_THREAD_INIT
- thread_start_func_2(th, th->machine_stack_start, rb_ia64_bsp());
+ thread_start_func_2(th, th->machine.stack_start, rb_ia64_bsp());
#else
thread_start_func_2(th, &stack_start, rb_ia64_bsp());
#endif
@@ -886,10 +896,10 @@ native_thread_create(rb_thread_t *th)
const size_t stack_size = th->vm->default_params.thread_machine_stack_size;
const size_t space = space_size(stack_size);
- th->machine_stack_maxsize = stack_size - space;
+ th->machine.stack_maxsize = stack_size - space;
#ifdef __ia64
- th->machine_stack_maxsize /= 2;
- th->machine_register_stack_maxsize = th->machine_stack_maxsize;
+ th->machine.stack_maxsize /= 2;
+ th->machine.register_stack_maxsize = th->machine.stack_maxsize;
#endif
#ifdef HAVE_PTHREAD_ATTR_INIT
@@ -904,10 +914,18 @@ native_thread_create(rb_thread_t *th)
CHECK_ERR(pthread_attr_setinheritsched(&attr, PTHREAD_INHERIT_SCHED));
# endif
CHECK_ERR(pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED));
-
- err = pthread_create(&th->thread_id, &attr, thread_start_func_1, th);
-#else
- err = pthread_create(&th->thread_id, NULL, thread_start_func_1, th);
+#endif
+#ifdef get_stack_of
+ native_mutex_lock(&th->interrupt_lock);
+#endif
+ err = pthread_create(&th->thread_id, attrp, thread_start_func_1, th);
+#ifdef get_stack_of
+ if (!err) {
+ get_stack_of(th->thread_id,
+ &th->machine.stack_start,
+ &th->machine.stack_maxsize);
+ }
+ native_mutex_unlock(&th->interrupt_lock);
#endif
thread_debug("create: %p (%d)\n", (void *)th, err);
#ifdef HAVE_PTHREAD_ATTR_INIT
@@ -1501,15 +1519,24 @@ ruby_stack_overflowed_p(const rb_thread_t *th, const void *addr)
const size_t water_mark = 1024 * 1024;
STACK_GROW_DIR_DETECTION;
- if (th) {
- size = th->machine_stack_maxsize;
- base = (char *)th->machine_stack_start - STACK_DIR_UPPER(0, size);
- }
#ifdef STACKADDR_AVAILABLE
- else if (get_stack(&base, &size) == 0) {
- STACK_DIR_UPPER((void)(base = (char *)base + size), (void)0);
+ if (get_stack(&base, &size) == 0) {
+# ifdef __APPLE__
+ if (pthread_equal(th->thread_id, native_main_thread.id)) {
+ struct rlimit rlim;
+ if (getrlimit(RLIMIT_STACK, &rlim) == 0 && rlim.rlim_cur > size) {
+ size = (size_t)rlim.rlim_cur;
+ }
+ }
+# endif
+ base = (char *)base + STACK_DIR_UPPER(+size, -size);
}
+ else
#endif
+ if (th) {
+ size = th->machine.stack_maxsize;
+ base = (char *)th->machine.stack_start - STACK_DIR_UPPER(0, size);
+ }
else {
return 0;
}