Add support for the internal boehm-gc on OpenBSD
authorRobert Nagy <robert@openbsd.org>
Mon, 29 Nov 2010 14:56:37 +0000 (15:56 +0100)
committerZoltan Varga <vargaz@gmail.com>
Mon, 29 Nov 2010 16:05:46 +0000 (17:05 +0100)
13 files changed:
libgc/Makefile.am
libgc/configure.in
libgc/dyn_load.c
libgc/include/gc_config_macros.h
libgc/include/private/gcconfig.h
libgc/include/private/pthread_support.h
libgc/mach_dep.c
libgc/misc.c
libgc/os_dep.c
libgc/pthread_stop_world.c
libgc/pthread_support.c
libgc/threadlibs.c
po/mcs/de.po

index 0700ae8b5b4a1737daef9920d11d5ae9740f5cdb..45d4b0f69255b24785eac57e91d41a4c6e9bc5cc 100644 (file)
@@ -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:
index 865988a2b4f852b0875c2b8aec5a91ec7b569de1..8c735a1760d8a739a7fe0d58a109e31b44476862 100644 (file)
@@ -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
index a42efd4e25d7264d6d4a93f26051cf614b8ca0ca..e4be3c7d183e31d4410d2f99c4c5ec32d4676a15 100644 (file)
@@ -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
 
 #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 <stddef.h>
+# if !defined(OPENBSD)
 #   include <elf.h>
+# endif
 #   include <link.h>
 #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 <sys/exec_elf.h>
+# endif
 /* for compatibility with 1.4.x */
 #  ifndef DT_DEBUG
 #  define DT_DEBUG     21
index d8f38303c0a62de9acd79fd9328208e59527f74b..c11caa7748e0a7c2baff69d7bfcd9478f5a675e3 100644 (file)
@@ -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
 #   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
index e517d70fc3f9b53a8ee8dcc79d08b6949b202cef..d1c46944bfecd13034bed7f817d6d5869abccf6f 100644 (file)
 #    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
 #   endif
 #   ifdef OPENBSD
 #      define OS_TYPE "OPENBSD"
+#    ifdef GC_OPENBSD_THREADS
+#       define UTHREAD_SP_OFFSET 192
+#    else
+#       include <sys/param.h>
+#       include <uvm/uvm_extern.h>
+#       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"
        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 <sys/param.h>
+#       include <uvm/uvm_extern.h>
+#       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)
index ec53e46fc45320a4760d073f49469ff4431057fa..852d3815bc61ef1c9bc1c973dc9dc184d0362fe3 100644 (file)
@@ -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
index ba1e0b6fe506d35692c0de98f1bfaa2eff9917fc..1e20b8ab77bcec8f2522839b5f6e8acc5723aee4 100644 (file)
@@ -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");
index e21db5b3209890893ba09853cc01a6bdaac89378..5b2868d808b691d90fd521f01e6b28757f5c86f9 100644 (file)
@@ -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) \
index 3a4b8a006338990cd3c02700d29314bf61e423f5..ee2e409ad42ca3b3d3973e14000330c20d716426 100644 (file)
@@ -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 <sys/syscall.h>
+    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 <stddef.h>
@@ -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 <sys/signal.h>
+# include <pthread.h>
+# include <pthread_np.h>
+        
+#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 */
index 5a1b9f37172db62df18dabaa9468a422e07c2058..bf2faafe3d60dd4e1933b20178b950bd40723727 100644 (file)
@@ -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 <signal.h>
 #include <semaphore.h>
index 2d54a513d017a742472cdb1c77a86f342047369d..c307ac0eec588a5ec2eb000a77bf05a8d9f83e6f 100644 (file)
@@ -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
 
 # include <sys/sysctl.h>
 #endif /* GC_DARWIN_THREADS */
 
-#if defined(GC_NETBSD_THREADS)
+#if defined(GC_NETBSD_THREADS) || defined(GC_OPENBSD_THREADS)
 # include <sys/param.h>
 # include <sys/sysctl.h>
 #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;
index 9078c8d8cd99f4e7bcf71a3d4990375a9ab9e9fd..79428a9e49a028aea5e61faa280b4b653af4e4c9 100644 (file)
@@ -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
index 6764c4f4e5f295ae4212fe2f5e989d363f15c749..bf3a16eb9455933d2c3d3a237403cc6e56b97ea3 100644 (file)
@@ -6,6 +6,7 @@ msgstr ""
 "PO-Revision-Date: 2008-09-26 15:14+0100\n"
 "Last-Translator: Daniel Nauck <dna@mono-project.de>\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"