Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/mono.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/libgc
diff options
context:
space:
mode:
authorRobert Nagy <robert@openbsd.org>2010-11-29 17:56:37 +0300
committerZoltan Varga <vargaz@gmail.com>2010-11-29 19:05:46 +0300
commit065506369b2f69c1104e6059ae884a205b414273 (patch)
treeda4ab0b7163f86cd4a17482d88cb869b6ebcc712 /libgc
parentf2e095f92cd1829f515e014779378240d3ae0e8e (diff)
Add support for the internal boehm-gc on OpenBSD
Diffstat (limited to 'libgc')
-rw-r--r--libgc/Makefile.am2
-rw-r--r--libgc/configure.in7
-rw-r--r--libgc/dyn_load.c9
-rw-r--r--libgc/include/gc_config_macros.h5
-rw-r--r--libgc/include/private/gcconfig.h32
-rw-r--r--libgc/include/private/pthread_support.h2
-rw-r--r--libgc/mach_dep.c2
-rw-r--r--libgc/misc.c4
-rw-r--r--libgc/os_dep.c146
-rw-r--r--libgc/pthread_stop_world.c3
-rw-r--r--libgc/pthread_support.c9
-rw-r--r--libgc/threadlibs.c2
12 files changed, 210 insertions, 13 deletions
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 <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
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 <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"
@@ -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 <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)
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 <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 */
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 <signal.h>
#include <semaphore.h>
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 <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;
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