Thanks to visit codestin.com
Credit goes to github.com

Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion libgc/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
7 changes: 7 additions & 0 deletions libgc/configure.in
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
9 changes: 8 additions & 1 deletion libgc/dyn_load.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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

Expand Down Expand Up @@ -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)


Expand Down Expand Up @@ -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
Expand Down
5 changes: 5 additions & 0 deletions libgc/include/gc_config_macros.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
32 changes: 32 additions & 0 deletions libgc/include/private/gcconfig.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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"
Expand Down Expand Up @@ -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)
Expand Down
12 changes: 12 additions & 0 deletions libgc/include/private/openbsd_stop_world.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#ifndef GC_OPENBSD_STOP_WORLD_H
#define GC_OPENBSD_STOP_WORLD_H

#if !defined(GC_OPENBSD_THREADS)
#error openbsd_stop_world.h included without GC_OPENBSD_THREADS defined
#endif

struct thread_stop_info {
ptr_t stack_ptr; /* Valid only when stopped. */
};

#endif
2 changes: 2 additions & 0 deletions libgc/include/private/pthread_support.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion libgc/mach_dep.c
Original file line number Diff line number Diff line change
Expand Up @@ -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");
Expand Down
4 changes: 2 additions & 2 deletions libgc/misc.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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) \
Expand Down
161 changes: 161 additions & 0 deletions libgc/openbsd_stop_world.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
#include "private/pthread_support.h"

/* derived from pthread_stop_world.c */

# if defined(GC_OPENBSD_THREADS)

#define THREAD_EQUAL(id1, id2) pthread_equal(id1, id2)

/* We hold allocation lock. Should do exactly the right thing if the */
/* world is stopped. Should not fail if it isn't. */
void GC_push_all_stacks()
{
GC_bool found_me = FALSE;
size_t nthreads = 0;
int i;
GC_thread p;
ptr_t lo, hi;
pthread_t me = pthread_self();

if (!GC_thr_initialized) GC_thr_init();
# if DEBUG_THREADS
GC_printf("Pushing stacks from thread 0x%x\n", (unsigned) me);
# endif
for (i = 0; i < THREAD_TABLE_SZ; i++) {
for (p = GC_threads[i]; p != 0; p = p -> next) {
if (p -> flags & FINISHED) continue;
++nthreads;
if (THREAD_EQUAL(p -> id, me)) {
# ifdef SPARC
lo = (ptr_t)GC_save_regs_in_stack();
# else
lo = GC_approx_sp();
# endif
found_me = TRUE;
} else {
lo = p -> stop_info.stack_ptr;
}
if ((p -> flags & MAIN_THREAD) == 0) {
hi = p -> stack_end;
} else {
/* The original stack. */
hi = GC_stackbottom;
}
# if DEBUG_THREADS
GC_printf("Stack for thread 0x%x = [%p,%p)\n",
(unsigned)(p -> id), lo, hi);
# endif
if (0 == lo) ABORT("GC_push_all_stacks: sp not set!\n");
# ifdef STACK_GROWS_UP
/* We got them backwards! */
GC_push_all_stack(hi, lo);
# else
GC_push_all_stack(lo, hi);
# endif
}
}
if (!found_me && !GC_in_thread_creation)
ABORT("Collecting from unknown thread.");
}

/* We hold the allocation lock. Suspend all threads that might */
/* still be running. */
void GC_suspend_all()
{
int i;
GC_thread p;
int result;
pthread_t my_thread = pthread_self();

for (i = 0; i < THREAD_TABLE_SZ; i++) {
for (p = GC_threads[i]; p != 0; p = p -> next) {
if (!THREAD_EQUAL(p -> id, my_thread)) {
if (p -> flags & FINISHED) continue;
if (p -> thread_blocked) /* Will wait */ continue;
# if DEBUG_THREADS
GC_printf("Suspending thread 0x%x\n",
(unsigned)(p -> id));
# endif

if (pthread_suspend_np(p -> id) != 0)
ABORT("pthread_suspend_np failed");

/*
* This will only work for userland pthreads. It will
* fail badly on rthreads. Perhaps we should consider
* a pthread_sp_np() function that returns the stack
* pointer for a suspended thread and implement in
* both pthreads and rthreads.
*/
p -> stop_info.stack_ptr = *(ptr_t*)((char *)p -> id + UTHREAD_SP_OFFSET);
}
}
}
}

void GC_stop_world()
{
int i;

GC_ASSERT(I_HOLD_LOCK());
# if DEBUG_THREADS
GC_printf("Stopping the world from 0x%x\n", (unsigned)pthread_self());
# endif

/* Make sure all free list construction has stopped before we start. */
/* No new construction can start, since free list construction is */
/* required to acquire and release the GC lock before it starts, */
/* and we have the lock. */
# ifdef PARALLEL_MARK
GC_acquire_mark_lock();
GC_ASSERT(GC_fl_builder_count == 0);
/* We should have previously waited for it to become zero. */
# endif /* PARALLEL_MARK */

GC_suspend_all();

# ifdef PARALLEL_MARK
GC_release_mark_lock();
# endif
#if DEBUG_THREADS
GC_printf("World stopped from 0x%x\n", (unsigned)pthread_self());
#endif
}

/* Caller holds allocation lock, and has held it continuously since */
/* the world stopped. */
void GC_start_world()
{
pthread_t my_thread = pthread_self();
register int i;
register GC_thread p;
register int result;

# if DEBUG_THREADS
GC_printf("World starting\n");
# endif

for (i = 0; i < THREAD_TABLE_SZ; i++) {
for (p = GC_threads[i]; p != 0; p = p -> next) {
if (!THREAD_EQUAL(p -> id, my_thread)) {
if (p -> flags & FINISHED) continue;
if (p -> thread_blocked) continue;
#if DEBUG_THREADS
GC_printf("Resuming thread 0x%x\n",
(unsigned)(p -> id));
#endif

if (pthread_resume_np(p -> id) != 0)
ABORT("pthread_kill failed");
}
}
}
# if DEBUG_THREADS
GC_printf("World started\n");
# endif
}

void GC_stop_init() {
}

#endif
Loading