aboutsummaryrefslogtreecommitdiff
path: root/lang/ruby18
diff options
context:
space:
mode:
authorStanislav Sedov <stas@FreeBSD.org>2009-10-12 13:15:50 +0000
committerStanislav Sedov <stas@FreeBSD.org>2009-10-12 13:15:50 +0000
commitef38fc3bb89f43ad4af429b617528baac1c78b77 (patch)
tree7d2bd23454400343e4b9807f863c4b71576e65ad /lang/ruby18
parent136555d3280309c3f5cf250085972097920fc8c3 (diff)
Notes
Diffstat (limited to 'lang/ruby18')
-rw-r--r--lang/ruby18/Makefile7
-rw-r--r--lang/ruby18/files/patch-gc.c75
-rw-r--r--lang/ruby18/files/patch-main.c86
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