mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
* 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
This commit is contained in:
parent
436b02b332
commit
fc3c60f608
7 changed files with 163 additions and 106 deletions
14
ChangeLog
14
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.
|
||||
|
|
90
gc.c
90
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);
|
||||
}
|
||||
|
||||
|
|
16
gc.h
16
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 */
|
||||
|
|
6
thread.c
6
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)
|
||||
{
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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);
|
||||
|
|
25
vm.c
25
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());
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue