From: Robert Nagy Date: Mon, 29 Nov 2010 14:56:37 +0000 (+0100) Subject: Add support for the internal boehm-gc on OpenBSD X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=commitdiff_plain;h=065506369b2f69c1104e6059ae884a205b414273;p=mono.git Add support for the internal boehm-gc on OpenBSD --- diff --git a/libgc/Makefile.am b/libgc/Makefile.am index 0700ae8b5b4..45d4b0f6925 100644 --- a/libgc/Makefile.am +++ b/libgc/Makefile.am @@ -47,7 +47,7 @@ obj_map.c os_dep.c pcr_interface.c ptr_chck.c real_malloc.c reclaim.c \ solaris_pthreads.c solaris_threads.c specific.c stubborn.c typd_mlc.c \ backgraph.c win32_threads.c \ pthread_support.c pthread_stop_world.c darwin_stop_world.c \ -mach_dep.c $(asm_libgc_sources) +openbsd_stop_world.c mach_dep.c $(asm_libgc_sources) # Include THREADDLLIBS here to ensure that the correct versions of # linuxthread semaphore functions get linked: diff --git a/libgc/configure.in b/libgc/configure.in index 865988a2b4f..8c735a1760d 100644 --- a/libgc/configure.in +++ b/libgc/configure.in @@ -147,6 +147,13 @@ case "$THREADS" in fi AC_DEFINE(THREAD_LOCAL_ALLOC) ;; + *-*-openbsd*) + AC_DEFINE(GC_OPENBSD_THREADS) + if test "${enable_parallel_mark}" = yes; then + AC_DEFINE(PARALLEL_MARK) + fi + AC_DEFINE(THREAD_LOCAL_ALLOC) + ;; *-*-osf*) AC_DEFINE(GC_OSF1_THREADS) if test "${enable_parallel_mark}" = yes; then diff --git a/libgc/dyn_load.c b/libgc/dyn_load.c index a42efd4e25d..e4be3c7d183 100644 --- a/libgc/dyn_load.c +++ b/libgc/dyn_load.c @@ -57,6 +57,7 @@ !defined(HPUX) && !(defined(LINUX) && defined(__ELF__)) && \ !defined(RS6000) && !defined(SCO_ELF) && !defined(DGUX) && \ !(defined(FREEBSD) && defined(__ELF__)) && \ + !(defined(OPENBSD) && (defined(__ELF__) || defined(M68K))) && \ !(defined(NETBSD) && defined(__ELF__)) && !defined(HURD) && \ !defined(DARWIN) --> We only know how to find data segments of dynamic libraries for the @@ -92,9 +93,12 @@ #if defined(LINUX) && defined(__ELF__) || defined(SCO_ELF) || \ (defined(FREEBSD) && defined(__ELF__)) || defined(DGUX) || \ + (defined(OPENBSD) && defined(__ELF__)) || \ (defined(NETBSD) && defined(__ELF__)) || defined(HURD) # include +# if !defined(OPENBSD) # include +# endif # include #endif @@ -295,6 +299,7 @@ void GC_register_dynamic_libraries() #if defined(LINUX) && defined(__ELF__) || defined(SCO_ELF) || \ (defined(FREEBSD) && defined(__ELF__)) || defined(DGUX) || \ + (defined(OPENBSD) && defined(__ELF__)) || \ (defined(NETBSD) && defined(__ELF__)) || defined(HURD) @@ -473,8 +478,10 @@ GC_bool GC_register_main_static_data() /* This doesn't necessarily work in all cases, e.g. with preloaded * dynamic libraries. */ -#if defined(NETBSD) +#if defined(NETBSD) || defined(OPENBSD) +# if !defined(OPENBSD) # include +# endif /* for compatibility with 1.4.x */ # ifndef DT_DEBUG # define DT_DEBUG 21 diff --git a/libgc/include/gc_config_macros.h b/libgc/include/gc_config_macros.h index d8f38303c0a..c11caa7748e 100644 --- a/libgc/include/gc_config_macros.h +++ b/libgc/include/gc_config_macros.h @@ -57,6 +57,7 @@ defined(GC_HPUX_THREADS) || defined(GC_OSF1_THREADS) || \ defined(GC_DGUX386_THREADS) || defined(GC_DARWIN_THREADS) || \ defined(GC_AIX_THREADS) || defined(GC_NETBSD_THREADS) || \ + defined(GC_OPENBSD_THREADS) || \ (defined(GC_WIN32_THREADS) && defined(__CYGWIN32__)) # define GC_PTHREADS # endif @@ -87,6 +88,10 @@ # define GC_DARWIN_THREADS # define GC_PTHREADS # endif +# if !defined(GC_PTHREADS) && defined(__OpenBSD__) +# define GC_OPENBSD_THREADS +# define GC_PTHREADS +# endif # if !defined(GC_PTHREADS) && defined(__FreeBSD__) # define GC_FREEBSD_THREADS # define GC_PTHREADS diff --git a/libgc/include/private/gcconfig.h b/libgc/include/private/gcconfig.h index e517d70fc3f..d1c46944bfe 100644 --- a/libgc/include/private/gcconfig.h +++ b/libgc/include/private/gcconfig.h @@ -231,6 +231,10 @@ # define I386 # define mach_type_known # endif +# if defined(OPENBSD) && defined(__amd64__) +# define X86_64 +# define mach_type_known +# endif # if defined(LINUX) && defined(__x86_64__) # define X86_64 # define mach_type_known @@ -1304,6 +1308,18 @@ # endif # ifdef OPENBSD # define OS_TYPE "OPENBSD" +# ifdef GC_OPENBSD_THREADS +# define UTHREAD_SP_OFFSET 192 +# else +# include +# include +# define STACKBOTTOM USRSTACK +# endif + extern int __data_start[]; +# define DATASTART ((ptr_t)(__data_start)) + extern char _end[]; +# define DATAEND ((ptr_t)(&_end)) +# define DYNAMIC_LOADING # endif # ifdef FREEBSD # define OS_TYPE "FREEBSD" @@ -2086,6 +2102,22 @@ extern char etext[]; # define SEARCH_FOR_DATA_START # endif +# ifdef OPENBSD +# define OS_TYPE "OPENBSD" +# define ELF_CLASS ELFCLASS64 +# ifdef GC_OPENBSD_THREADS +# define UTHREAD_SP_OFFSET 400 +# else +# include +# include +# define STACKBOTTOM USRSTACK +# endif + extern int __data_start[]; +# define DATASTART ((ptr_t)(__data_start)) + extern char _end[]; +# define DATAEND ((ptr_t)(&_end)) +# define DYNAMIC_LOADING +# endif # endif #if defined(LINUX) && defined(USE_MMAP) diff --git a/libgc/include/private/pthread_support.h b/libgc/include/private/pthread_support.h index ec53e46fc45..852d3815bc6 100644 --- a/libgc/include/private/pthread_support.h +++ b/libgc/include/private/pthread_support.h @@ -8,6 +8,8 @@ #if defined(GC_DARWIN_THREADS) # include "private/darwin_stop_world.h" +#elif defined(GC_OPENBSD_THREADS) +# include "private/openbsd_stop_world.h" #else # include "private/pthread_stop_world.h" #endif diff --git a/libgc/mach_dep.c b/libgc/mach_dep.c index ba1e0b6fe50..1e20b8ab77b 100644 --- a/libgc/mach_dep.c +++ b/libgc/mach_dep.c @@ -492,7 +492,7 @@ ptr_t cold_gc_frame; /* the stack. Return sp. */ # ifdef SPARC asm(" .seg \"text\""); -# if defined(SVR4) || defined(NETBSD) || defined(FREEBSD) +# if defined(SVR4) || defined(NETBSD) || defined(FREEBSD) || defined(OPENBSD) asm(" .globl GC_save_regs_in_stack"); asm("GC_save_regs_in_stack:"); asm(" .type GC_save_regs_in_stack,#function"); diff --git a/libgc/misc.c b/libgc/misc.c index e21db5b3209..5b2868d808b 100644 --- a/libgc/misc.c +++ b/libgc/misc.c @@ -473,7 +473,7 @@ size_t GC_get_total_bytes GC_PROTO(()) int GC_get_suspend_signal GC_PROTO(()) { -#if defined(SIG_SUSPEND) && defined(GC_PTHREADS) && !defined(GC_MACOSX_THREADS) +#if defined(SIG_SUSPEND) && defined(GC_PTHREADS) && !defined(GC_MACOSX_THREADS) && !defined(GC_OPENBSD_THREADS) return SIG_SUSPEND; #else return -1; @@ -684,7 +684,7 @@ void GC_init_inner() # if defined(SEARCH_FOR_DATA_START) GC_init_linux_data_start(); # endif -# if (defined(NETBSD) || defined(OPENBSD)) && defined(__ELF__) +# if defined(NETBSD) && defined(__ELF__) GC_init_netbsd_elf(); # endif # if defined(GC_PTHREADS) || defined(GC_SOLARIS_THREADS) \ diff --git a/libgc/os_dep.c b/libgc/os_dep.c index 3a4b8a00633..ee2e409ad42 100644 --- a/libgc/os_dep.c +++ b/libgc/os_dep.c @@ -392,7 +392,7 @@ static void *tiny_sbrk(ptrdiff_t increment) #define sbrk tiny_sbrk # endif /* ECOS */ -#if (defined(NETBSD) || defined(OPENBSD)) && defined(__ELF__) +#if defined(NETBSD) && defined(__ELF__) ptr_t GC_data_start; void GC_init_netbsd_elf() @@ -405,6 +405,102 @@ static void *tiny_sbrk(ptrdiff_t increment) } #endif +#if defined(OPENBSD) + static struct sigaction old_segv_act; + sigjmp_buf GC_jmp_buf_openbsd; + +# if defined(GC_OPENBSD_THREADS) +# include + sigset_t __syscall(quad_t, ...); +# endif + + /* + * Dont use GC_find_limit() because siglongjmp out of the + * signal handler by-passes our userland pthreads lib, leaving + * SIGSEGV and SIGPROF masked. Instead use this custom one + * that works-around the issues. + */ + + /*ARGSUSED*/ + void GC_fault_handler_openbsd(int sig) + { + siglongjmp(GC_jmp_buf_openbsd, 1); + } + + /* Return the first nonaddressible location > p or bound */ + /* Requires allocation lock. */ + ptr_t GC_find_limit_openbsd(ptr_t p, ptr_t bound) + { + static volatile ptr_t result; + /* Safer if static, since otherwise it may not be */ + /* preserved across the longjmp. Can safely be */ + /* static since it's only called with the */ + /* allocation lock held. */ + struct sigaction act; + size_t pgsz = (size_t)sysconf(_SC_PAGESIZE); + + GC_ASSERT(I_HOLD_LOCK()); + + act.sa_handler = GC_fault_handler_openbsd; + sigemptyset(&act.sa_mask); + act.sa_flags = SA_NODEFER | SA_RESTART; + sigaction(SIGSEGV, &act, &old_segv_act); + + if (sigsetjmp(GC_jmp_buf_openbsd, 1) == 0) { + result = (ptr_t)(((word)(p)) & ~(pgsz-1)); + for (;;) { + result += pgsz; + if (result >= bound) { + result = bound; + break; + } + GC_noop1((word)(*result)); + } + } + +# if defined(GC_OPENBSD_THREADS) + /* due to the siglongjump we need to manually unmask SIGPROF */ + __syscall(SYS_sigprocmask, SIG_UNBLOCK, sigmask(SIGPROF)); +# endif + + sigaction(SIGSEGV, &old_segv_act, 0); + + return(result); + } + + /* Return first addressable location > p or bound */ + /* Requires allocation lock. */ + ptr_t GC_skip_hole_openbsd(ptr_t p, ptr_t bound) + { + static volatile ptr_t result; + struct sigaction act; + size_t pgsz = (size_t)sysconf(_SC_PAGESIZE); + static volatile int firstpass; + + GC_ASSERT(I_HOLD_LOCK()); + + act.sa_handler = GC_fault_handler_openbsd; + sigemptyset(&act.sa_mask); + act.sa_flags = SA_NODEFER | SA_RESTART; + sigaction(SIGSEGV, &act, &old_segv_act); + + firstpass = 1; + result = (ptr_t)(((word)(p)) & ~(pgsz-1)); + if (sigsetjmp(GC_jmp_buf_openbsd, 1) != 0 || firstpass) { + firstpass = 0; + result += pgsz; + if (result >= bound) { + result = bound; + } else + GC_noop1((word)(*result)); + } + + sigaction(SIGSEGV, &old_segv_act, 0); + + return(result); + } +#endif + # ifdef OS2 # include @@ -1021,7 +1117,8 @@ void *GC_set_stackbottom = NULL; #endif /* FREEBSD_STACKBOTTOM */ #if !defined(BEOS) && !defined(AMIGA) && !defined(MSWIN32) \ - && !defined(MSWINCE) && !defined(OS2) && !defined(NOSYS) && !defined(ECOS) + && !defined(MSWINCE) && !defined(OS2) && !defined(NOSYS) && !defined(ECOS) \ + && !defined(GC_OPENBSD_THREADS) ptr_t GC_get_stack_base() { @@ -1081,6 +1178,25 @@ ptr_t GC_get_stack_base() # endif /* ! AMIGA, !OS 2, ! MS Windows, !BEOS, !NOSYS, !ECOS */ +#if defined(GC_OPENBSD_THREADS) + +/* Find the stack using pthread_stackseg_np() */ + +# include +# include +# include + +#define HAVE_GET_STACK_BASE + +ptr_t GC_get_stack_base() +{ + stack_t stack; + pthread_stackseg_np(pthread_self(), &stack); + return stack.ss_sp; +} + +#endif /* GC_OPENBSD_THREADS */ + /* * Register static data segment(s) as roots. * If more data segments are added later then they need to be registered @@ -1445,6 +1561,31 @@ int * etext_addr; #else /* !OS2 && !Windows && !AMIGA */ +#if defined(OPENBSD) + +/* + * Depending on arch alignment there can be multiple holes + * between DATASTART & DATAEND. Scan from DATASTART - DATAEND + * and register each region. + */ +void GC_register_data_segments(void) +{ + ptr_t region_start, region_end; + + region_start = DATASTART; + + for(;;) { + region_end = GC_find_limit_openbsd(region_start, DATAEND); + GC_add_roots_inner(region_start, region_end, FALSE); + if (region_end < DATAEND) + region_start = GC_skip_hole_openbsd(region_end, DATAEND); + else + break; + } +} + +# else /* !OS2 && !Windows && !AMIGA && !OPENBSD */ + void GC_register_data_segments() { # if !defined(PCR) && !defined(SRC_M3) && !defined(MACOS) @@ -1504,6 +1645,7 @@ void GC_register_data_segments() /* change. */ } +# endif /* ! OPENBSD */ # endif /* ! AMIGA */ # endif /* ! MSWIN32 && ! MSWINCE*/ # endif /* ! OS2 */ diff --git a/libgc/pthread_stop_world.c b/libgc/pthread_stop_world.c index 5a1b9f37172..bf2faafe3d6 100644 --- a/libgc/pthread_stop_world.c +++ b/libgc/pthread_stop_world.c @@ -2,7 +2,8 @@ #if defined(GC_PTHREADS) && !defined(GC_SOLARIS_THREADS) \ && !defined(GC_IRIX_THREADS) && !defined(GC_WIN32_THREADS) \ - && !defined(GC_DARWIN_THREADS) && !defined(GC_AIX_THREADS) + && !defined(GC_DARWIN_THREADS) && !defined(GC_AIX_THREADS) \ + && !defined(GC_OPENBSD_THREADS) #include #include diff --git a/libgc/pthread_support.c b/libgc/pthread_support.c index 2d54a513d01..c307ac0eec5 100644 --- a/libgc/pthread_support.c +++ b/libgc/pthread_support.c @@ -68,7 +68,8 @@ # if (defined(GC_DGUX386_THREADS) || defined(GC_OSF1_THREADS) || \ defined(GC_DARWIN_THREADS) || defined(GC_AIX_THREADS)) || \ - defined(GC_NETBSD_THREADS) && !defined(USE_PTHREAD_SPECIFIC) + defined(GC_NETBSD_THREADS) && !defined(USE_PTHREAD_SPECIFIC) || \ + defined(GC_OPENBSD_THREADS) # define USE_PTHREAD_SPECIFIC # endif @@ -129,7 +130,7 @@ # include #endif /* GC_DARWIN_THREADS */ -#if defined(GC_NETBSD_THREADS) +#if defined(GC_NETBSD_THREADS) || defined(GC_OPENBSD_THREADS) # include # include #endif @@ -1040,7 +1041,7 @@ void GC_thr_init() GC_nprocs = sysconf(_SC_NPROC_ONLN); if (GC_nprocs <= 0) GC_nprocs = 1; # endif -# if defined(GC_DARWIN_THREADS) || defined(GC_FREEBSD_THREADS) || defined(GC_NETBSD_THREADS) +# if defined(GC_DARWIN_THREADS) || defined(GC_FREEBSD_THREADS) || defined(GC_NETBSD_THREADS) || defined(GC_OPENBSD_THREADS) int ncpus = 1; size_t len = sizeof(ncpus); sysctl((int[2]) {CTL_HW, HW_NCPU}, 2, &ncpus, &len, NULL, 0); @@ -1116,7 +1117,7 @@ void GC_init_parallel() } -#if !defined(GC_DARWIN_THREADS) +#if !defined(GC_DARWIN_THREADS) && !defined(GC_OPENBSD_THREADS) int WRAP_FUNC(pthread_sigmask)(int how, const sigset_t *set, sigset_t *oset) { sigset_t fudged_set; diff --git a/libgc/threadlibs.c b/libgc/threadlibs.c index 9078c8d8cd9..79428a9e49a 100644 --- a/libgc/threadlibs.c +++ b/libgc/threadlibs.c @@ -15,7 +15,7 @@ int main() || defined(GC_DARWIN_THREADS) || defined(GC_AIX_THREADS) printf("-lpthread\n"); # endif -# if defined(GC_FREEBSD_THREADS) +# if defined(GC_FREEBSD_THREADS) || defined(GC_OPENBSD_THREADS) # if (__FREEBSD_version >= 500000) printf("-lpthread\n"); # else diff --git a/po/mcs/de.po b/po/mcs/de.po index 6764c4f4e5f..bf3a16eb945 100644 --- a/po/mcs/de.po +++ b/po/mcs/de.po @@ -6,6 +6,7 @@ msgstr "" "PO-Revision-Date: 2008-09-26 15:14+0100\n" "Last-Translator: Daniel Nauck \n" "Language-Team: http://www.mono-project.de\n" +"Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n"