diff options
author | Stanislav Sedov <stas@FreeBSD.org> | 2009-10-12 13:15:50 +0000 |
---|---|---|
committer | Stanislav Sedov <stas@FreeBSD.org> | 2009-10-12 13:15:50 +0000 |
commit | ef38fc3bb89f43ad4af429b617528baac1c78b77 (patch) | |
tree | 7d2bd23454400343e4b9807f863c4b71576e65ad /lang/ruby18 | |
parent | 136555d3280309c3f5cf250085972097920fc8c3 (diff) |
Notes
Diffstat (limited to 'lang/ruby18')
-rw-r--r-- | lang/ruby18/Makefile | 7 | ||||
-rw-r--r-- | lang/ruby18/files/patch-gc.c | 75 | ||||
-rw-r--r-- | lang/ruby18/files/patch-main.c | 86 |
3 files changed, 150 insertions, 18 deletions
diff --git a/lang/ruby18/Makefile b/lang/ruby18/Makefile index 5ab744a3f44f..9d175d627ee7 100644 --- a/lang/ruby18/Makefile +++ b/lang/ruby18/Makefile @@ -56,6 +56,13 @@ _SUF1= _${PORTREVISION} PKGNAMESUFFIX= #empty +# +# pthreads in earlier versions has problems with malloc after fork +# +.if ${OSVERSION} < 702000 +WITHOUT_PTHREADS= yes +.endif + .if defined(WITHOUT_PTHREADS) CONFIGURE_ARGS+=--disable-pthread PKGNAMESUFFIX:= ${PKGNAMESUFFIX}+nopthreads diff --git a/lang/ruby18/files/patch-gc.c b/lang/ruby18/files/patch-gc.c index 873c96c76908..2ca3a480416f 100644 --- a/lang/ruby18/files/patch-gc.c +++ b/lang/ruby18/files/patch-gc.c @@ -1,5 +1,5 @@ --- gc.c.orig 2009-03-27 13:25:23.000000000 +0300 -+++ gc.c 2009-06-19 16:26:54.000000000 +0400 ++++ gc.c 2009-09-29 01:09:29.000000000 +0400 @@ -30,6 +30,10 @@ #include <sys/resource.h> #endif @@ -19,7 +19,16 @@ int ruby_gc_stress = 0; -@@ -534,9 +539,14 @@ +@@ -485,6 +490,8 @@ + # define STACK_LEVEL_MAX 655300 + #endif + ++VALUE *stack_bottom_addr = 0x0; ++ + #ifdef C_ALLOCA + # define SET_STACK_END VALUE stack_end; alloca(0); + # define STACK_END (&stack_end) +@@ -534,9 +541,22 @@ #define GC_WATER_MARK 512 @@ -27,27 +36,35 @@ +#define CHECK_STACK(ret, prev) do {\ SET_STACK_END;\ - (ret) = (STACK_LENGTH > STACK_LEVEL_MAX + GC_WATER_MARK);\ -+ ssize_t avail = STACK_LEVEL_MAX + GC_WATER_MARK - STACK_LENGTH;\ -+ if (avail <= 0 || (prev != -1 && (signed)(STACK_LENGTH - prev) > avail))\ ++ ssize_t avail;\ ++ if (stack_bottom_addr != 0) {\ ++ if (STACK_UPPER(&avail, 1, -1) > 0)\ ++ avail = stack_bottom_addr - STACK_END;\ ++ else\ ++ avail = STACK_END - stack_bottom_addr;\ ++ } else {\ ++ avail = STACK_LEVEL_MAX + GC_WATER_MARK - STACK_LENGTH;\ ++ }\ ++ if (avail <= 0 || (prev != 0 && (prev - avail) > avail))\ + (ret) = 1;\ + else\ + (ret) = 0;\ -+ (prev) = STACK_LENGTH;\ ++ (prev) = avail;\ } while (0) size_t -@@ -552,8 +562,9 @@ +@@ -552,8 +572,9 @@ ruby_stack_check() { int ret; -+ static size_t prev = -1; ++ static ssize_t prev = 0; - CHECK_STACK(ret); + CHECK_STACK(ret, prev); return ret; } -@@ -1599,18 +1610,50 @@ +@@ -1599,18 +1620,72 @@ } rb_gc_stack_start = addr; #endif @@ -70,7 +87,9 @@ +#elif defined _WIN32 + { + MEMORY_BASIC_INFORMATION mi; -+ + +- if (space > 1024*1024) space = 1024*1024; +- STACK_LEVEL_MAX = (rlim.rlim_cur - space) / sizeof(VALUE); + if (VirtualQuery(&mi, &mi, sizeof(mi))) { + stacksize = (char *)mi.BaseAddress - (char *)mi.AllocationBase; + } @@ -80,29 +99,49 @@ + { + pthread_attr_t attr; + size_t size; - -- if (space > 1024*1024) space = 1024*1024; -- STACK_LEVEL_MAX = (rlim.rlim_cur - space) / sizeof(VALUE); ++ void *addr; ++ + pthread_attr_init(&attr); + if (pthread_attr_get_np(pthread_self(), &attr) == 0) { -+ pthread_attr_getstacksize(&attr, &size); ++ pthread_attr_getstack(&attr, &addr, &size); + if (stacksize == 0 || size < stacksize) + stacksize = size; - } ++ stack_bottom_addr = addr; ++ } + pthread_attr_destroy(&attr); - } - #endif ++ } ++#endif + if (stacksize) { + unsigned int space = stacksize / 5; + + if (space > 1024*1024) + space = 1024*1024; + STACK_LEVEL_MAX = (stacksize - space) / sizeof(VALUE); ++#if defined(__FreeBSD__) ++#include <sys/sysctl.h> ++ if (stack_bottom_addr == 0) { ++ size_t len; ++ void *usrstack; ++ int mib[2]; ++ int error; ++ ++ len = sizeof(usrstack); ++ mib[0] = CTL_KERN; ++ mib[1] = KERN_USRSTACK; ++ error = sysctl(mib, 2, &usrstack, &len, NULL, 0); ++ if (error == 0) { ++ if (STACK_UPPER(&avail, 1, -1) > 0) ++ stack_bottom_addr = usrstack + (stacksize - space); ++ else ++ stack_bottom_addr = usrstack - (stacksize - space); + } + } + #endif + } } void ruby_init_stack(VALUE *addr -@@ -1631,31 +1674,7 @@ +@@ -1631,31 +1706,7 @@ rb_gc_register_stack_start = (VALUE*)bsp; } #endif @@ -135,7 +174,7 @@ } /* -@@ -1980,7 +1999,7 @@ +@@ -1980,7 +2031,7 @@ chain_finalized_object(st_data_t key, st_data_t val, st_data_t arg) { RVALUE *p = (RVALUE *)key, **final_list = (RVALUE **)arg; diff --git a/lang/ruby18/files/patch-main.c b/lang/ruby18/files/patch-main.c new file mode 100644 index 000000000000..2fe3acb6c778 --- /dev/null +++ b/lang/ruby18/files/patch-main.c @@ -0,0 +1,86 @@ +--- main.c.orig 2007-02-13 02:01:19.000000000 +0300 ++++ main.c 2009-09-28 15:55:36.000000000 +0400 +@@ -29,10 +29,21 @@ + static void objcdummyfunction( void ) { objc_msgSend(); } + #endif + ++#if defined(__FreeBSD__) && defined(_THREAD_SAFE) ++static int argc; ++static char **argv; ++static char **envp; ++#endif ++ ++#if defined(__FreeBSD__) && defined(_THREAD_SAFE) ++void * ++main_entry(void *arg) ++#else + int + main(argc, argv, envp) + int argc; + char **argv, **envp; ++#endif + { + #ifdef _WIN32 + NtInitialize(&argc, &argv); +@@ -47,5 +58,61 @@ + ruby_options(argc, argv); + ruby_run(); + } ++#if defined(__FreeBSD__) && defined(_THREAD_SAFE) ++ return (NULL); ++#else + return 0; ++#endif + } ++ ++#if defined(__FreeBSD__) && defined(_THREAD_SAFE) ++#include <sys/types.h> ++#include <sys/time.h> ++#include <sys/resource.h> ++int ++main(main_argc, main_argv, main_envp) ++ int main_argc; ++ char **main_argv, **main_envp; ++{ ++ struct rlimit rl; ++ pthread_attr_t attr; ++ pthread_t tid; ++ size_t stacksize; ++ int error; ++ ++ argc = main_argc; ++ argv = main_argv; ++ envp = main_envp; ++ /* Get the system imposed limit. */ ++ error = getrlimit(RLIMIT_STACK, &rl); ++ if (error != 0) { ++ fprintf(stderr, "cannot obtain resource limit\n"); ++ exit(1); ++ } ++ stacksize = rl.rlim_cur * 3 / 4; /* Set initial size to 3/4 of limit */ ++ error = pthread_attr_init(&attr); ++ if (error != 0) { ++ fprintf(stderr, "cannot initialize thread attributes\n"); ++ exit(1); ++ } ++ while (stacksize > 0) { ++ error = pthread_attr_setstacksize(&attr, stacksize); ++ if (error != 0) ++ goto next; ++ error = pthread_create(&tid, &attr, &main_entry, NULL); ++ if (error == 0) ++ break; ++ next: ++ stacksize = stacksize >> 1; ++ } ++ if (stacksize != 0) { /* Success. */ ++ pthread_detach(tid); ++ pthread_exit(NULL); ++ return (0); ++ } ++ else { ++ fprintf(stderr, "Cannot create main thread\n"); ++ return (1); ++ } ++} ++#endif |