From feb609e10d4725bcf577c9d7f4bdc901465a6aaa Mon Sep 17 00:00:00 2001 From: Hans Boehm Date: Sat, 22 Sep 2001 00:00:00 +0000 Subject: gc6.1alpha1 tarball import --- Makefile | 28 ++++++--- Makefile.am | 6 +- Makefile.direct | 28 ++++++--- Makefile.dj | 2 + Makefile.in | 20 ++---- NT_THREADS_MAKEFILE | 16 ++--- allchblk.c | 1 + configure | 3 + configure.in | 11 +++- dbg_mlc.c | 59 ++++++++++++++--- doc/README | 2 +- doc/README.changes | 43 +++++++++++-- dyn_load.c | 111 +++++++++++++++++++++++++++++--- finalize.c | 4 +- gc.mak | 16 ++--- gc_dlopen.c | 5 +- ia64_save_regs_in_stack.s | 12 ++++ include/gc.h | 28 +++++---- include/gc_gcj.h | 2 - include/new_gc_alloc.h | 15 ++++- include/private/gc_locks.h | 14 ++--- include/private/gc_priv.h | 28 +++++---- include/private/gcconfig.h | 153 ++++++++++++++++++++++++++++----------------- irix_threads.c | 6 +- linux_threads.c | 50 ++++++++++----- mach_dep.c | 28 ++++++--- malloc.c | 6 +- mark_rts.c | 4 +- misc.c | 36 +++++------ new_hblk.c | 1 + os_dep.c | 54 ++++++++-------- reclaim.c | 30 ++++++--- solaris_pthreads.c | 4 +- solaris_threads.c | 4 +- specific.c | 4 +- tests/test.c | 75 +++++++++++----------- threadlibs.c | 15 ++--- version.h | 4 +- win32_threads.c | 4 +- 39 files changed, 620 insertions(+), 312 deletions(-) create mode 100644 ia64_save_regs_in_stack.s diff --git a/Makefile b/Makefile index a5d24c65..72dd4133 100644 --- a/Makefile +++ b/Makefile @@ -10,13 +10,20 @@ # c++ interface to gc.a # cord/de - builds dumb editor based on cords. ABI_FLAG= +# ABI_FLAG should be the cc flag that specifies the ABI. On most +# platforms this will be the empty string. Possible values: +# +DD64 for 64-bit executable on HP/UX. +# -n32, -n64, -o32 for SGI/MIPS ABIs. + +AS_ABI_FLAG=$(ABI_FLAG) +# ABI flag for assembler. On HP/UX this is +A64 for 64 bit +# executables. + CC=cc $(ABI_FLAG) CXX=g++ $(ABI_FLAG) -AS=as $(ABI_FLAG) +AS=as $(AS_ABI_FLAG) # The above doesn't work with gas, which doesn't run cpp. # Define AS as `gcc -c -x assembler-with-cpp' instead. -# Under Irix 6, you will have to specify the ABI (-o32, -n32, or -64) -# if you use something other than the default ABI on your machine. # Redefining srcdir allows object code for the nonPCR version of the collector # to be generated in different directories. @@ -54,12 +61,15 @@ HOSTCFLAGS=$(CFLAGS) # gc.h before performing thr_ or dl* or GC_ operations.) # Must also define -D_REENTRANT. # -DGC_SOLARIS_PTHREADS enables support for Solaris pthreads. -# Define SOLARIS_THREADS as well. +# (Internally this define GC_SOLARIS_THREADS as well.) # -DGC_IRIX_THREADS enables support for Irix pthreads. See README.irix. # -DGC_HPUX_THREADS enables support for HP/UX 11 pthreads. # Also requires -D_REENTRANT or -D_POSIX_C_SOURCE=199506L. See README.hp. # -DGC_LINUX_THREADS enables support for Xavier Leroy's Linux threads. # see README.linux. -D_REENTRANT may also be required. +# -DGC_OSF1_THREADS enables support for Tru64 pthreads. Untested. +# -DGC_FREEBSD_THREADS enables support for FreeBSD pthreads. Untested. +# Appeared to run into some underlying thread problems. # -DALL_INTERIOR_POINTERS allows all pointers to the interior # of objects to be recognized. (See gc_priv.h for consequences.) # Alternatively, GC_all_interior_pointers can be set at process @@ -191,8 +201,8 @@ HOSTCFLAGS=$(CFLAGS) # 15% or so. # -DUSE_3DNOW_PREFETCH causes the collector to issue AMD 3DNow style # prefetch instructions. Same restrictions as USE_I686_PREFETCH. -# UNTESTED!! -# -DGC_USE_LD_WRAP in combination with the gld flags listed in README.linux +# Minimally tested. Didn't appear to be an obvious win on a K6-2/500. +# -DGC_USE_LD_WRAP in combination with the old flags listed in README.linux # causes the collector some system and pthread calls in a more transparent # fashion than the usual macro-based approach. Requires GNU ld, and # currently probably works only with Linux. @@ -242,7 +252,8 @@ SRCS= $(CSRCS) mips_sgi_mach_dep.s rs6000_mach_dep.s alpha_mach_dep.s \ include/gc_local_alloc.h include/private/dbg_mlc.h \ include/private/specific.h powerpc_macosx_mach_dep.s \ include/leak_detector.h include/gc_amiga_redirects.h \ - include/gc_pthread_redirects.h $(CORD_SRCS) + include/gc_pthread_redirects.h ia64_save_regs_in_stack.s \ + $(CORD_SRCS) DOC_FILES= README.QUICK doc/README.Mac doc/README.MacOSX doc/README.OS2 \ doc/README.amiga doc/README.cords doc/debugging.html \ @@ -435,6 +446,9 @@ mach_dep.o: $(srcdir)/mach_dep.c $(srcdir)/mips_sgi_mach_dep.s $(srcdir)/mips_ul ./if_mach SPARC SUNOS4 $(AS) -o mach_dep.o $(srcdir)/sparc_sunos4_mach_dep.s ./if_mach SPARC OPENBSD $(AS) -o mach_dep.o $(srcdir)/sparc_sunos4_mach_dep.s ./if_mach SPARC NETBSD $(AS) -o mach_dep.o $(srcdir)/sparc_netbsd_mach_dep.s + ./if_mach IA64 HPUX as $(AS_ABI_FLAG) -o ia64_save_regs_in_stack.o $(srcdir)/ia64_save_regs_in_stack.s + ./if_mach IA64 HPUX $(CC) -c -o mach_dep1.o $(SPECIALCFLAGS) $(srcdir)/mach_dep.c + ./if_mach IA64 HPUX ld -r -o mach_dep.o mach_dep1.o ia64_save_regs_in_stack.o ./if_not_there mach_dep.o $(CC) -c $(SPECIALCFLAGS) $(srcdir)/mach_dep.c mark_rts.o: $(srcdir)/mark_rts.c $(UTILS) diff --git a/Makefile.am b/Makefile.am index 4fdf31b2..c0883ade 100644 --- a/Makefile.am +++ b/Makefile.am @@ -53,7 +53,7 @@ libgc_la_LDFLAGS = -version-info 1:1:0 -rpath $(toolexeclibdir) EXTRA_libgc_la_SOURCES = alpha_mach_dep.s \ mips_sgi_mach_dep.s mips_ultrix_mach_dep.s powerpc_macosx_mach_dep.s \ rs6000_mach_dep.s sparc_mach_dep.s sparc_netbsd_mach_dep.s \ -sparc_sunos4_mach_dep.s +sparc_sunos4_mach_dep.s ia64_save_regs_in_stack.s AM_CXXFLAGS = @GC_CFLAGS@ AM_CFLAGS = @GC_CFLAGS@ @@ -62,7 +62,9 @@ check_PROGRAMS = gctest # The following hack produces a warning from automake, but we need it in order # to build a file from a subdirectory. FIXME. test.o: tests/test.c - $(COMPILE) -c $< + $(COMPILE) -c tests/test.c +# Using $< in the above seems to fail with the HP/UX on Itanium make. + gctest_OBJECTS = test.o gctest_LDADD = ./libgc.la $(THREADLIBS) $(EXTRA_TEST_LIBS) TESTS_ENVIRONMENT = LD_LIBRARY_PATH=../../$(MULTIBUILDTOP)gcc diff --git a/Makefile.direct b/Makefile.direct index a5d24c65..72dd4133 100644 --- a/Makefile.direct +++ b/Makefile.direct @@ -10,13 +10,20 @@ # c++ interface to gc.a # cord/de - builds dumb editor based on cords. ABI_FLAG= +# ABI_FLAG should be the cc flag that specifies the ABI. On most +# platforms this will be the empty string. Possible values: +# +DD64 for 64-bit executable on HP/UX. +# -n32, -n64, -o32 for SGI/MIPS ABIs. + +AS_ABI_FLAG=$(ABI_FLAG) +# ABI flag for assembler. On HP/UX this is +A64 for 64 bit +# executables. + CC=cc $(ABI_FLAG) CXX=g++ $(ABI_FLAG) -AS=as $(ABI_FLAG) +AS=as $(AS_ABI_FLAG) # The above doesn't work with gas, which doesn't run cpp. # Define AS as `gcc -c -x assembler-with-cpp' instead. -# Under Irix 6, you will have to specify the ABI (-o32, -n32, or -64) -# if you use something other than the default ABI on your machine. # Redefining srcdir allows object code for the nonPCR version of the collector # to be generated in different directories. @@ -54,12 +61,15 @@ HOSTCFLAGS=$(CFLAGS) # gc.h before performing thr_ or dl* or GC_ operations.) # Must also define -D_REENTRANT. # -DGC_SOLARIS_PTHREADS enables support for Solaris pthreads. -# Define SOLARIS_THREADS as well. +# (Internally this define GC_SOLARIS_THREADS as well.) # -DGC_IRIX_THREADS enables support for Irix pthreads. See README.irix. # -DGC_HPUX_THREADS enables support for HP/UX 11 pthreads. # Also requires -D_REENTRANT or -D_POSIX_C_SOURCE=199506L. See README.hp. # -DGC_LINUX_THREADS enables support for Xavier Leroy's Linux threads. # see README.linux. -D_REENTRANT may also be required. +# -DGC_OSF1_THREADS enables support for Tru64 pthreads. Untested. +# -DGC_FREEBSD_THREADS enables support for FreeBSD pthreads. Untested. +# Appeared to run into some underlying thread problems. # -DALL_INTERIOR_POINTERS allows all pointers to the interior # of objects to be recognized. (See gc_priv.h for consequences.) # Alternatively, GC_all_interior_pointers can be set at process @@ -191,8 +201,8 @@ HOSTCFLAGS=$(CFLAGS) # 15% or so. # -DUSE_3DNOW_PREFETCH causes the collector to issue AMD 3DNow style # prefetch instructions. Same restrictions as USE_I686_PREFETCH. -# UNTESTED!! -# -DGC_USE_LD_WRAP in combination with the gld flags listed in README.linux +# Minimally tested. Didn't appear to be an obvious win on a K6-2/500. +# -DGC_USE_LD_WRAP in combination with the old flags listed in README.linux # causes the collector some system and pthread calls in a more transparent # fashion than the usual macro-based approach. Requires GNU ld, and # currently probably works only with Linux. @@ -242,7 +252,8 @@ SRCS= $(CSRCS) mips_sgi_mach_dep.s rs6000_mach_dep.s alpha_mach_dep.s \ include/gc_local_alloc.h include/private/dbg_mlc.h \ include/private/specific.h powerpc_macosx_mach_dep.s \ include/leak_detector.h include/gc_amiga_redirects.h \ - include/gc_pthread_redirects.h $(CORD_SRCS) + include/gc_pthread_redirects.h ia64_save_regs_in_stack.s \ + $(CORD_SRCS) DOC_FILES= README.QUICK doc/README.Mac doc/README.MacOSX doc/README.OS2 \ doc/README.amiga doc/README.cords doc/debugging.html \ @@ -435,6 +446,9 @@ mach_dep.o: $(srcdir)/mach_dep.c $(srcdir)/mips_sgi_mach_dep.s $(srcdir)/mips_ul ./if_mach SPARC SUNOS4 $(AS) -o mach_dep.o $(srcdir)/sparc_sunos4_mach_dep.s ./if_mach SPARC OPENBSD $(AS) -o mach_dep.o $(srcdir)/sparc_sunos4_mach_dep.s ./if_mach SPARC NETBSD $(AS) -o mach_dep.o $(srcdir)/sparc_netbsd_mach_dep.s + ./if_mach IA64 HPUX as $(AS_ABI_FLAG) -o ia64_save_regs_in_stack.o $(srcdir)/ia64_save_regs_in_stack.s + ./if_mach IA64 HPUX $(CC) -c -o mach_dep1.o $(SPECIALCFLAGS) $(srcdir)/mach_dep.c + ./if_mach IA64 HPUX ld -r -o mach_dep.o mach_dep1.o ia64_save_regs_in_stack.o ./if_not_there mach_dep.o $(CC) -c $(SPECIALCFLAGS) $(srcdir)/mach_dep.c mark_rts.o: $(srcdir)/mark_rts.c $(UTILS) diff --git a/Makefile.dj b/Makefile.dj index 09fae4e6..7aadaf34 100644 --- a/Makefile.dj +++ b/Makefile.dj @@ -5,6 +5,8 @@ # Primary targets: # gc.a - builds basic library # libgc.a - builds library for use with g++ "-fgc-keyword" extension +# -fgc-keyword was never really available. Historical +# interest only. # c++ - adds C++ interface to library # cords - adds cords (heavyweight strings) to library # test - prints porting information, then builds basic version of gc.a, diff --git a/Makefile.in b/Makefile.in index b9d776ee..da1a642d 100644 --- a/Makefile.in +++ b/Makefile.in @@ -86,8 +86,6 @@ CXXINCLUDES = @CXXINCLUDES@ DLLTOOL = @DLLTOOL@ EXEEXT = @EXEEXT@ EXTRA_TEST_LIBS = @EXTRA_TEST_LIBS@ -GCJ = @GCJ@ -GCJFLAGS = @GCJFLAGS@ GC_CFLAGS = @GC_CFLAGS@ INCLUDES = @INCLUDES@ LIBTOOL = @LIBTOOL@ @@ -96,10 +94,8 @@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MY_CFLAGS = @MY_CFLAGS@ OBJDUMP = @OBJDUMP@ -OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ RANLIB = @RANLIB@ -STRIP = @STRIP@ THREADLIBS = @THREADLIBS@ VERSION = @VERSION@ addobjs = @addobjs@ @@ -130,7 +126,7 @@ libgc_la_LIBADD = @addobjs@ $(THREADLIBS) libgc_la_DEPENDENCIES = @addobjs@ libgc_la_LDFLAGS = -version-info 1:1:0 -rpath $(toolexeclibdir) -EXTRA_libgc_la_SOURCES = alpha_mach_dep.s mips_sgi_mach_dep.s mips_ultrix_mach_dep.s powerpc_macosx_mach_dep.s rs6000_mach_dep.s sparc_mach_dep.s sparc_netbsd_mach_dep.s sparc_sunos4_mach_dep.s +EXTRA_libgc_la_SOURCES = alpha_mach_dep.s mips_sgi_mach_dep.s mips_ultrix_mach_dep.s powerpc_macosx_mach_dep.s rs6000_mach_dep.s sparc_mach_dep.s sparc_netbsd_mach_dep.s sparc_sunos4_mach_dep.s ia64_save_regs_in_stack.s AM_CXXFLAGS = @GC_CFLAGS@ @@ -138,6 +134,8 @@ AM_CXXFLAGS = @GC_CFLAGS@ AM_CFLAGS = @GC_CFLAGS@ check_PROGRAMS = gctest +# Using $< in the above seems to fail with the HP/UX on Itanium make. + gctest_OBJECTS = test.o gctest_LDADD = ./libgc.la $(THREADLIBS) $(EXTRA_TEST_LIBS) TESTS_ENVIRONMENT = LD_LIBRARY_PATH=../../$(MULTIBUILDTOP)gcc @@ -159,7 +157,7 @@ CONFIG_STATUS_DEPENDENCIES = $(srcdir)/configure.host MAKEOVERRIDES = ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs +mkinstalldirs = $(SHELL) $(top_srcdir)/$gc_basedir/mkinstalldirs CONFIG_CLEAN_FILES = LTLIBRARIES = $(toolexeclib_LTLIBRARIES) @@ -182,7 +180,7 @@ COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CF CCLD = $(CC) DIST_COMMON = Makefile.am Makefile.in acinclude.m4 aclocal.m4 \ config.guess config.sub configure configure.in install-sh ltconfig \ -ltmain.sh +ltmain.sh mkinstalldirs DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST) @@ -194,7 +192,7 @@ OBJECTS = $(libgc_la_OBJECTS) all: all-redirect .SUFFIXES: -.SUFFIXES: .S .c .lo .o .obj .s +.SUFFIXES: .S .c .lo .o .s $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) cd $(top_srcdir) && $(AUTOMAKE) --cygnus Makefile @@ -238,11 +236,6 @@ uninstall-toolexeclibLTLIBRARIES: .c.o: $(COMPILE) -c $< -# FIXME: We should only use cygpath when building on Windows, -# and only if it is available. -.c.obj: - $(COMPILE) -c `cygpath -w $<` - .s.o: $(COMPILE) -c $< @@ -251,7 +244,6 @@ uninstall-toolexeclibLTLIBRARIES: mostlyclean-compile: -rm -f *.o core *.core - -rm -f *.$(OBJEXT) clean-compile: diff --git a/NT_THREADS_MAKEFILE b/NT_THREADS_MAKEFILE index c90584ec..5f0b5462 100644 --- a/NT_THREADS_MAKEFILE +++ b/NT_THREADS_MAKEFILE @@ -114,10 +114,10 @@ CLEAN : CPP=cl.exe # ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /c -# ADD CPP /nologo /MD /W3 /GX /O2 /I include /D "NDEBUG" /D "SILENT" /D "GC_BUILD" /D "WIN32" /D "_WINDOWS" /D "ALL_INTERIOR_POINTERS" /D "__STDC__" /D "WIN32_THREADS" /FR /YX /c +# ADD CPP /nologo /MD /W3 /GX /O2 /I include /D "NDEBUG" /D "SILENT" /D "GC_BUILD" /D "WIN32" /D "_WINDOWS" /D "ALL_INTERIOR_POINTERS" /D "__STDC__" /D "GC_WIN32_THREADS" /FR /YX /c CPP_PROJ=/nologo /MD /W3 /GX /O2 /I include /D "NDEBUG" /D "SILENT" /D "GC_BUILD" /D\ "WIN32" /D "_WINDOWS" /D "ALL_INTERIOR_POINTERS" /D "__STDC__" /D\ - "WIN32_THREADS" /FR"$(INTDIR)/" /Fp"$(INTDIR)/gc.pch" /YX /Fo"$(INTDIR)/" /c + "GC_WIN32_THREADS" /FR"$(INTDIR)/" /Fp"$(INTDIR)/gc.pch" /YX /Fo"$(INTDIR)/" /c CPP_OBJS=.\Release/ CPP_SBRS=.\Release/ @@ -296,10 +296,10 @@ CLEAN : CPP=cl.exe # ADD BASE CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /c -# ADD CPP /nologo /MDd /W3 /Gm /GX /Zi /Od /I include /D "_DEBUG" /D "SILENT" /D "GC_BUILD" /D "WIN32" /D "_WINDOWS" /D "ALL_INTERIOR_POINTERS" /D "__STDC__" /D "WIN32_THREADS" /FR /YX /c +# ADD CPP /nologo /MDd /W3 /Gm /GX /Zi /Od /I include /D "_DEBUG" /D "SILENT" /D "GC_BUILD" /D "WIN32" /D "_WINDOWS" /D "ALL_INTERIOR_POINTERS" /D "__STDC__" /D "GC_WIN32_THREADS" /FR /YX /c CPP_PROJ=/nologo /MDd /W3 /Gm /GX /Zi /Od /I include /D "_DEBUG" /D "SILENT" /D "GC_BUILD"\ /D "WIN32" /D "_WINDOWS" /D "ALL_INTERIOR_POINTERS" /D "__STDC__" /D\ - "WIN32_THREADS" /FR"$(INTDIR)/" /Fp"$(INTDIR)/gc.pch" /YX /Fo"$(INTDIR)/"\ + "GC_WIN32_THREADS" /FR"$(INTDIR)/" /Fp"$(INTDIR)/gc.pch" /YX /Fo"$(INTDIR)/"\ /Fd"$(INTDIR)/" /c CPP_OBJS=.\Debug/ CPP_SBRS=.\Debug/ @@ -430,9 +430,9 @@ test.c : tests\test.c CPP=cl.exe # ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /c -# ADD CPP /nologo /MD /W3 /GX /O2 /I include /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "ALL_INTERIOR_POINTERS" /D "__STDC__" /D "WIN32_THREADS" /YX /c +# ADD CPP /nologo /MD /W3 /GX /O2 /I include /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "ALL_INTERIOR_POINTERS" /D "__STDC__" /D "GC_WIN32_THREADS" /YX /c CPP_PROJ=/nologo /MD /W3 /GX /O2 /I include /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D\ - "ALL_INTERIOR_POINTERS" /D "__STDC__" /D "WIN32_THREADS"\ + "ALL_INTERIOR_POINTERS" /D "__STDC__" /D "GC_WIN32_THREADS"\ /Fp"$(INTDIR)/gctest.pch" /YX /Fo"$(INTDIR)/" /c CPP_OBJS=.\gctest\Release/ CPP_SBRS=.\. @@ -516,9 +516,9 @@ CLEAN : CPP=cl.exe # ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /c -# ADD CPP /nologo /MDd /W3 /Gm /GX /Zi /Od /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "ALL_INTERIOR_POINTERS" /D "__STDC__" /D "WIN32_THREADS" /FR /YX /c +# ADD CPP /nologo /MDd /W3 /Gm /GX /Zi /Od /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "ALL_INTERIOR_POINTERS" /D "__STDC__" /D "GC_WIN32_THREADS" /FR /YX /c CPP_PROJ=/nologo /MDd /W3 /Gm /GX /Zi /Od /I include /D "_DEBUG" /D "WIN32" /D "_WINDOWS"\ - /D "ALL_INTERIOR_POINTERS" /D "__STDC__" /D "WIN32_THREADS" /FR"$(INTDIR)/"\ + /D "ALL_INTERIOR_POINTERS" /D "__STDC__" /D "GC_WIN32_THREADS" /FR"$(INTDIR)/"\ /Fp"$(INTDIR)/gctest.pch" /YX /Fo"$(INTDIR)/" /Fd"$(INTDIR)/" /c CPP_OBJS=.\gctest\Debug/ CPP_SBRS=.\gctest\Debug/ diff --git a/allchblk.c b/allchblk.c index 76296721..06582ec7 100644 --- a/allchblk.c +++ b/allchblk.c @@ -774,6 +774,7 @@ signed_word size; if (HBLK_IS_FREE(hhdr)) { GC_printf1("Duplicate large block deallocation of 0x%lx\n", (unsigned long) hbp); + ABORT("Duplicate large block deallocation"); } GC_ASSERT(IS_MAPPED(hhdr)); diff --git a/configure b/configure index 1146ce66..602a5351 100755 --- a/configure +++ b/configure @@ -2366,6 +2366,9 @@ EOF #define SUNOS53_SHARED_LIB 1 EOF + ;; + ia64-*-hpux*) + machdep="mach_dep.lo ia64_save_regs_in_stack.lo" ;; esac if test x"$machdep" = x; then diff --git a/configure.in b/configure.in index fa3f81ac..fcc0c710 100644 --- a/configure.in +++ b/configure.in @@ -96,7 +96,7 @@ case "$THREADS" in ;; *-*-freebsd*) AC_MSG_WARN("FreeBSD does not yet fully support threads with Boehm GC.") - AC_DEFINE(FREEBSD_THREADS) + AC_DEFINE(GC_FREEBSD_THREADS) INCLUDES="$INCLUDES -pthread" THREADLIBS=-pthread ;; @@ -157,6 +157,12 @@ case "$host" in # alpha*-*-*) # machdep="alpha_mach_dep.lo" # ;; + alpha-*-openbsd*) + if test x"${ac_cv_lib_dl_dlopen}" != xyes ; then + AC_MSG_WARN(OpenBSD/Alpha without dlopen(). Shared library support is disabled) + AM_DISABLE_SHARED + fi + ;; mipstx39-*-elf*) machdep="mips_ultrix_mach_dep.lo" AC_DEFINE(STACKBASE, __stackbase) @@ -172,6 +178,9 @@ case "$host" in sparc-sun-solaris2.3*) AC_DEFINE(SUNOS53_SHARED_LIB) ;; + ia64-*-hpux*) + machdep="mach_dep.lo ia64_save_regs_in_stack.lo" + ;; esac if test x"$machdep" = x; then machdep="mach_dep.lo" diff --git a/dbg_mlc.c b/dbg_mlc.c index be3da8e2..af55032f 100644 --- a/dbg_mlc.c +++ b/dbg_mlc.c @@ -40,7 +40,7 @@ ptr_t p; register word sz = GC_size((ptr_t) ohdr); if (HBLKPTR((ptr_t)ohdr) != HBLKPTR((ptr_t)body) - || sz < sizeof (oh)) { + || sz < DEBUG_BYTES + EXTRA_BYTES) { return(FALSE); } if (ohdr -> oh_sz == sz) { @@ -861,6 +861,28 @@ struct closure { (*(cl -> cl_fn))((GC_PTR)((char *)obj + sizeof(oh)), cl -> cl_data); } +/* Set ofn and ocd to reflect the values we got back. */ +static void store_old (obj, my_old_fn, my_old_cd, ofn, ocd) +GC_PTR obj; +GC_finalization_proc my_old_fn; +struct closure * my_old_cd; +GC_finalization_proc *ofn; +GC_PTR *ocd; +{ + if (0 != my_old_fn) { + if (my_old_fn != GC_debug_invoke_finalizer) { + GC_err_printf1("Debuggable object at 0x%lx had non-debug finalizer.\n", + obj); + /* This should probably be fatal. */ + } else { + if (ofn) *ofn = my_old_cd -> cl_fn; + if (ocd) *ocd = my_old_cd -> cl_data; + } + } else { + if (ofn) *ofn = 0; + if (ocd) *ocd = 0; + } +} # ifdef __STDC__ void GC_debug_register_finalizer(GC_PTR obj, GC_finalization_proc fn, @@ -875,14 +897,21 @@ struct closure { GC_PTR *ocd; # endif { + GC_finalization_proc my_old_fn; + GC_PTR my_old_cd; ptr_t base = GC_base(obj); if (0 == base || (ptr_t)obj - base != sizeof(oh)) { GC_err_printf1( "GC_register_finalizer called with non-base-pointer 0x%lx\n", obj); } - GC_register_finalizer(base, GC_debug_invoke_finalizer, - GC_make_closure(fn,cd), ofn, ocd); + if (0 == fn) { + GC_register_finalizer(base, 0, 0, &my_old_fn, &my_old_cd); + } else { + GC_register_finalizer(base, GC_debug_invoke_finalizer, + GC_make_closure(fn,cd), &my_old_fn, &my_old_cd); + } + store_old(obj, my_old_fn, (struct closure *)my_old_cd, ofn, ocd); } # ifdef __STDC__ @@ -900,14 +929,22 @@ struct closure { GC_PTR *ocd; # endif { + GC_finalization_proc my_old_fn; + GC_PTR my_old_cd; ptr_t base = GC_base(obj); if (0 == base || (ptr_t)obj - base != sizeof(oh)) { GC_err_printf1( "GC_register_finalizer_no_order called with non-base-pointer 0x%lx\n", obj); } - GC_register_finalizer_no_order(base, GC_debug_invoke_finalizer, - GC_make_closure(fn,cd), ofn, ocd); + if (0 == fn) { + GC_register_finalizer_no_order(base, 0, 0, &my_old_fn, &my_old_cd); + } else { + GC_register_finalizer_no_order(base, GC_debug_invoke_finalizer, + GC_make_closure(fn,cd), &my_old_fn, + &my_old_cd); + } + store_old(obj, my_old_fn, (struct closure *)my_old_cd, ofn, ocd); } # ifdef __STDC__ @@ -925,14 +962,22 @@ struct closure { GC_PTR *ocd; # endif { + GC_finalization_proc my_old_fn; + GC_PTR my_old_cd; ptr_t base = GC_base(obj); if (0 == base || (ptr_t)obj - base != sizeof(oh)) { GC_err_printf1( "GC_register_finalizer_ignore_self called with non-base-pointer 0x%lx\n", obj); } - GC_register_finalizer_ignore_self(base, GC_debug_invoke_finalizer, - GC_make_closure(fn,cd), ofn, ocd); + if (0 == fn) { + GC_register_finalizer_ignore_self(base, 0, 0, &my_old_fn, &my_old_cd); + } else { + GC_register_finalizer_ignore_self(base, GC_debug_invoke_finalizer, + GC_make_closure(fn,cd), &my_old_fn, + &my_old_cd); + } + store_old(obj, my_old_fn, (struct closure *)my_old_cd, ofn, ocd); } #ifdef GC_ADD_CALLER diff --git a/doc/README b/doc/README index c6b48c3b..b161ccf4 100644 --- a/doc/README +++ b/doc/README @@ -27,7 +27,7 @@ are GPL'ed, but with an exception that should cover all uses in the collector. (If you are concerned about such things, I recommend you look at the notice in config.guess or ltmain.sh.) -This is version 6.0 of a conservative garbage collector for C and C++. +This is version 6.1alpha1 of a conservative garbage collector for C and C++. You might find a more recent version of this at diff --git a/doc/README.changes b/doc/README.changes index c018c8b6..8c00e938 100644 --- a/doc/README.changes +++ b/doc/README.changes @@ -1360,7 +1360,7 @@ Since 6.0alpha8: it on untested platforms. - Integrated initial GNU HURD port. (Thanks to Chris Lingard and Igor Khavkine.) - - A few more fixes for Digital Mars compiler. + - A few more fixes for Digital Mars compiler (Walter Bright). - Fixed gcc version recognition. Renamed OPERATOR_NEW_ARRAY to GC_OPERATOR_NEW_ARRAY. Changed GC_OPERATOR_NEW_ARRAY to be the default. It can be overridden with -DGC_NO_OPERATOR_NEW_ARRAY. (Thanks to @@ -1378,16 +1378,47 @@ Since 6.0alpha9: - Fixed a stack clearing problem that resulted in SIGILL with a misaligned stack pointer for multithreaded SPARC builds. - Integrated another HURD patch (thanks to Igor Khavkine). + +Since 6.0: + - Non-debug, atomic allocations could result in bogus smashed object + reports with debugging on. (Thanks to Patrick Doyle for the small + test case.) + - Fixed GC_get_register_stack_base (Itanium only) to work around a glibc + 2.2.4 bug. + - Initial port to HP/UX on Itanium. Thread support and both 32 and 64 + bit ABIs appear to work. Parallel mark support doesn't yet, due to + some inline assembly code issues. Thread local allocation does appear + to work. + - ifdef'ed out glibc2.1/Itanium workaround. I suspect nobody is using + that combination anymore. + - Added a patch to make new_gc_alloc.h usable with gcc3.0. (Thanks to + Dimitris Vyzovitis for the patch.) + - Debugged 64-bit support on HP/UX PA-RISC. + - Turned on dynamic loading support for FreeBSD/ELF. (Thanks to Peter + Housel.) + - Unregistering of finalizers with debugging allocation was broken. + (Thanks to Jani Kajala for the test case.) + - Old finalizers were not returned correctly from GC_debug_register_finalizer. + - Disabled MPROTECT_VDB for Linux/M68K based on a report that it doesn't work. + - Cleaned up some statistics gathering code in reclaim.c (Thanks to Walter + Bright.) + - Added some support for OpenBSD/ELF/Linux. (Thanks to Suzuki Toshiya.) + - Added Jakub Jelinek's patch to use dl_iterate_phdr for dynamic library + traversal to dyn_load.c. Changed it to weakly reference dl_iterate_phdr, + so that the old code is stilll used with old versions of glibc. + - Cleaned up feature test macros for various threads packages and + integrated (partially functional) FreeBSD threads code from Loren Rittle. + It's likely that the cleanup broke something, since it touched lots of + code. It's also likelly that it fixed some unreported bugs in the + less common thread implementations, since some of the original code + didn't stand up to close scrutiny. Support for the next pthreads + implementation should be easier to add. To do: - There seem to be outstanding issues on Solaris/X86, possibly with finding the data segment starting address. Information/patches would - ne appreciated. - - New_gc_alloc.h is apparently no longer compatible with the latest C++ - standard library in gcc3.0. (This isn't technically a bug, since it only - claimed compatibility with the SGI STL. But we may need a new C++ STL - allocator interface.) + be appreciated. - Very large root set sizes (> 16 MB or so) could cause the collector to abort with an unexpected mark stack overflow. (Thanks again to Peter Chubb.) NOT YET FIXED. Workaround is to increase the initial diff --git a/dyn_load.c b/dyn_load.c index 5a86cf6c..c970fa5a 100644 --- a/dyn_load.c +++ b/dyn_load.c @@ -26,15 +26,18 @@ * None of this is safe with dlclose and incremental collection. * But then not much of anything is safe in the presence of dlclose. */ +#if defined(__linux__) && !defined(_GNU_SOURCE) + /* Can't test LINUX, since this must be define before other includes */ +# define _GNU_SOURCE +#endif #if !defined(MACOS) && !defined(_WIN32_WCE) # include #endif #include "private/gc_priv.h" -/* BTL: avoid circular redefinition of dlopen if SOLARIS_THREADS defined */ -# if (defined(LINUX_THREADS) || defined(SOLARIS_THREADS) \ - || defined(HPUX_THREADS) || defined(IRIX_THREADS)) && defined(dlopen) \ - && !defined(GC_USE_LD_WRAP) +/* BTL: avoid circular redefinition of dlopen if GC_SOLARIS_THREADS defined */ +# if (defined(GC_PTHREADS) || defined(GC_SOLARIS_THREADS)) \ + && defined(dlopen) && !defined(GC_USE_LD_WRAP) /* To support threads in Solaris, gc.h interposes on dlopen by */ /* defining "dlopen" to be "GC_dlopen", which is implemented below. */ /* However, both GC_FirstDLOpenedLinkMap() and GC_dlopen() use the */ @@ -53,6 +56,7 @@ !(defined(ALPHA) && defined(OSF1)) && \ !defined(HPUX) && !(defined(LINUX) && defined(__ELF__)) && \ !defined(RS6000) && !defined(SCO_ELF) && \ + !(defined(FREEBSD) && defined(__ELF__)) && \ !(defined(NETBSD) && defined(__ELF__)) && !defined(HURD) --> We only know how to find data segments of dynamic libraries for the --> above. Additional SVR4 variants might not be too @@ -124,7 +128,7 @@ GC_FirstDLOpenedLinkMap() #endif /* SUNOS5DL ... */ -/* BTL: added to fix circular dlopen definition if SOLARIS_THREADS defined */ +/* BTL: added to fix circular dlopen definition if GC_SOLARIS_THREADS defined */ # if defined(GC_must_restore_redefined_dlopen) # define dlopen GC_dlopen # endif @@ -171,7 +175,7 @@ static ptr_t GC_first_common() # if defined(SUNOS4) || defined(SUNOS5DL) /* Add dynamic library data sections to the root set. */ -# if !defined(PCR) && !defined(SOLARIS_THREADS) && defined(THREADS) +# if !defined(PCR) && !defined(GC_SOLARIS_THREADS) && defined(THREADS) # ifndef SRC_M3 --> fix mutual exclusion with dlopen # endif /* We assume M3 programs don't call dlopen for now */ @@ -243,6 +247,7 @@ void GC_register_dynamic_libraries() # endif /* SUNOS */ #if defined(LINUX) && defined(__ELF__) || defined(SCO_ELF) || \ + (defined(FREEBSD) && defined(__ELF__)) || \ (defined(NETBSD) && defined(__ELF__)) || defined(HURD) @@ -417,13 +422,91 @@ static char *parse_map_entry(char *buf_ptr, word *start, word *end, return buf_ptr; } -#else /* !USE_PROC_FOR_LIBRARIES */ +#endif /* USE_PROC_FOR_LIBRARIES */ + +#if !defined(USE_PROC_FOR_LIBRARIES) +/* The following is the preferred way to walk dynamic libraries */ +/* For glibc 2.2.4+. Unfortunately, it doesn't work for older */ +/* versions. Thanks to Jakub Jelinek for most of the code. */ + +#include +#include +#include + +# if defined(LINUX) /* Are others OK here, too? */ \ + && (__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 2) \ + || (__GLIBC__ == 2 && __GLIBC_MINOR__ == 2 && defined(DT_CONFIG))) + +/* We have the header files for a glibc that includes dl_iterate_phdr. */ +/* It may still not be available in the library on the target system. */ +/* Thus we also treat it as a weak symbol. */ +#define HAVE_DL_ITERATE_PHDR + +static int GC_register_dynlib_callback(info, size, ptr) + struct dl_phdr_info * info; + size_t size; + void * ptr; +{ + const ElfW(Phdr) * p; + char * start; + register int i; + + /* Make sure struct dl_phdr_info is at least as big as we need. */ + if (size < offsetof (struct dl_phdr_info, dlpi_phnum) + + sizeof (info->dlpi_phnum)) + return -1; + + /* Skip the first object - it is the main program. */ + if (*(int *)ptr == 0) + { + *(int *)ptr = 1; + return 0; + } + + p = info->dlpi_phdr; + for( i = 0; i < (int)(info->dlpi_phnum); ((i++),(p++)) ) { + switch( p->p_type ) { + case PT_LOAD: + { + if( !(p->p_flags & PF_W) ) break; + start = ((char *)(p->p_vaddr)) + info->dlpi_addr; + GC_add_roots_inner(start, start + p->p_memsz, TRUE); + } + break; + default: + break; + } + } + + return 0; +} + +/* Return TRUE if we succeed, FALSE if dl_iterate_phdr wasn't there. */ + +#pragma weak dl_iterate_phdr + +GC_bool GC_register_dynamic_libraries_dl_iterate_phdr() +{ + int tmp = 0; + + if (dl_iterate_phdr) { + dl_iterate_phdr(GC_register_dynlib_callback, &tmp); + return TRUE; + } else { + return FALSE; + } +} + +# else /* !LINUX || version(glibc) < 2.2.4 */ /* Dynamic loading code for Linux running ELF. Somewhat tested on * Linux/x86, untested but hopefully should work on Linux/Alpha. * This code was derived from the Solaris/ELF support. Thanks to * whatever kind soul wrote that. - Patrick Bridges */ +/* This doesn't necessarily work in all cases, e.g. with preloaded + * dynamic libraries. */ + #if defined(NETBSD) # include #else @@ -431,6 +514,8 @@ static char *parse_map_entry(char *buf_ptr, word *start, word *end, #endif #include +# endif + /* Newer versions of Linux/Alpha and Linux/x86 define this macro. We * define it for those older versions that don't. */ # ifndef ElfW @@ -472,9 +557,15 @@ GC_FirstDLOpenedLinkMap() void GC_register_dynamic_libraries() { - struct link_map *lm = GC_FirstDLOpenedLinkMap(); + struct link_map *lm; +# ifdef HAVE_DL_ITERATE_PHDR + if (GC_register_dynamic_libraries_dl_iterate_phdr()) { + return; + } +# endif + lm = GC_FirstDLOpenedLinkMap(); for (lm = GC_FirstDLOpenedLinkMap(); lm != (struct link_map *) 0; lm = lm->l_next) { @@ -649,7 +740,7 @@ void GC_register_dynamic_libraries() extern GC_bool GC_is_heap_base (ptr_t p); -# ifdef WIN32_THREADS +# ifdef GC_WIN32_THREADS extern void GC_get_next_stack(char *start, char **lo, char **hi); void GC_cond_add_roots(char *base, char * limit) { @@ -864,7 +955,7 @@ void GC_register_dynamic_libraries() /* Check if this is the end of the list or if some error occured */ if (status != 0) { -# ifdef HPUX_THREADS +# ifdef GC_HPUX_THREADS /* I've seen errno values of 0. The man page is not clear */ /* as to whether errno should get set on a -1 return. */ break; diff --git a/finalize.c b/finalize.c index 229d8286..d69ba6f1 100644 --- a/finalize.c +++ b/finalize.c @@ -207,7 +207,7 @@ signed_word * log_size_ptr; UNLOCK(); ENABLE_SIGNALS(); # endif - new_dl == GC_oom_fn(sizeof(struct disappearing_link)); + new_dl = GC_oom_fn(sizeof(struct disappearing_link)); if (0 == new_dl) { GC_finalization_failures++; return(0); @@ -433,7 +433,7 @@ finalization_mark_proc * mp; UNLOCK(); ENABLE_SIGNALS(); # endif - new_fo == GC_oom_fn(sizeof(struct finalizable_object)); + new_fo = GC_oom_fn(sizeof(struct finalizable_object)); if (0 == new_fo) { GC_finalization_failures++; return; diff --git a/gc.mak b/gc.mak index c90584ec..5f0b5462 100644 --- a/gc.mak +++ b/gc.mak @@ -114,10 +114,10 @@ CLEAN : CPP=cl.exe # ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /c -# ADD CPP /nologo /MD /W3 /GX /O2 /I include /D "NDEBUG" /D "SILENT" /D "GC_BUILD" /D "WIN32" /D "_WINDOWS" /D "ALL_INTERIOR_POINTERS" /D "__STDC__" /D "WIN32_THREADS" /FR /YX /c +# ADD CPP /nologo /MD /W3 /GX /O2 /I include /D "NDEBUG" /D "SILENT" /D "GC_BUILD" /D "WIN32" /D "_WINDOWS" /D "ALL_INTERIOR_POINTERS" /D "__STDC__" /D "GC_WIN32_THREADS" /FR /YX /c CPP_PROJ=/nologo /MD /W3 /GX /O2 /I include /D "NDEBUG" /D "SILENT" /D "GC_BUILD" /D\ "WIN32" /D "_WINDOWS" /D "ALL_INTERIOR_POINTERS" /D "__STDC__" /D\ - "WIN32_THREADS" /FR"$(INTDIR)/" /Fp"$(INTDIR)/gc.pch" /YX /Fo"$(INTDIR)/" /c + "GC_WIN32_THREADS" /FR"$(INTDIR)/" /Fp"$(INTDIR)/gc.pch" /YX /Fo"$(INTDIR)/" /c CPP_OBJS=.\Release/ CPP_SBRS=.\Release/ @@ -296,10 +296,10 @@ CLEAN : CPP=cl.exe # ADD BASE CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /c -# ADD CPP /nologo /MDd /W3 /Gm /GX /Zi /Od /I include /D "_DEBUG" /D "SILENT" /D "GC_BUILD" /D "WIN32" /D "_WINDOWS" /D "ALL_INTERIOR_POINTERS" /D "__STDC__" /D "WIN32_THREADS" /FR /YX /c +# ADD CPP /nologo /MDd /W3 /Gm /GX /Zi /Od /I include /D "_DEBUG" /D "SILENT" /D "GC_BUILD" /D "WIN32" /D "_WINDOWS" /D "ALL_INTERIOR_POINTERS" /D "__STDC__" /D "GC_WIN32_THREADS" /FR /YX /c CPP_PROJ=/nologo /MDd /W3 /Gm /GX /Zi /Od /I include /D "_DEBUG" /D "SILENT" /D "GC_BUILD"\ /D "WIN32" /D "_WINDOWS" /D "ALL_INTERIOR_POINTERS" /D "__STDC__" /D\ - "WIN32_THREADS" /FR"$(INTDIR)/" /Fp"$(INTDIR)/gc.pch" /YX /Fo"$(INTDIR)/"\ + "GC_WIN32_THREADS" /FR"$(INTDIR)/" /Fp"$(INTDIR)/gc.pch" /YX /Fo"$(INTDIR)/"\ /Fd"$(INTDIR)/" /c CPP_OBJS=.\Debug/ CPP_SBRS=.\Debug/ @@ -430,9 +430,9 @@ test.c : tests\test.c CPP=cl.exe # ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /c -# ADD CPP /nologo /MD /W3 /GX /O2 /I include /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "ALL_INTERIOR_POINTERS" /D "__STDC__" /D "WIN32_THREADS" /YX /c +# ADD CPP /nologo /MD /W3 /GX /O2 /I include /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "ALL_INTERIOR_POINTERS" /D "__STDC__" /D "GC_WIN32_THREADS" /YX /c CPP_PROJ=/nologo /MD /W3 /GX /O2 /I include /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D\ - "ALL_INTERIOR_POINTERS" /D "__STDC__" /D "WIN32_THREADS"\ + "ALL_INTERIOR_POINTERS" /D "__STDC__" /D "GC_WIN32_THREADS"\ /Fp"$(INTDIR)/gctest.pch" /YX /Fo"$(INTDIR)/" /c CPP_OBJS=.\gctest\Release/ CPP_SBRS=.\. @@ -516,9 +516,9 @@ CLEAN : CPP=cl.exe # ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /c -# ADD CPP /nologo /MDd /W3 /Gm /GX /Zi /Od /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "ALL_INTERIOR_POINTERS" /D "__STDC__" /D "WIN32_THREADS" /FR /YX /c +# ADD CPP /nologo /MDd /W3 /Gm /GX /Zi /Od /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "ALL_INTERIOR_POINTERS" /D "__STDC__" /D "GC_WIN32_THREADS" /FR /YX /c CPP_PROJ=/nologo /MDd /W3 /Gm /GX /Zi /Od /I include /D "_DEBUG" /D "WIN32" /D "_WINDOWS"\ - /D "ALL_INTERIOR_POINTERS" /D "__STDC__" /D "WIN32_THREADS" /FR"$(INTDIR)/"\ + /D "ALL_INTERIOR_POINTERS" /D "__STDC__" /D "GC_WIN32_THREADS" /FR"$(INTDIR)/"\ /Fp"$(INTDIR)/gctest.pch" /YX /Fo"$(INTDIR)/" /Fd"$(INTDIR)/" /c CPP_OBJS=.\gctest\Debug/ CPP_SBRS=.\gctest\Debug/ diff --git a/gc_dlopen.c b/gc_dlopen.c index 943c4b0c..eafaa2b1 100644 --- a/gc_dlopen.c +++ b/gc_dlopen.c @@ -24,8 +24,7 @@ #include "private/gc_priv.h" -# if defined(LINUX_THREADS) || defined(SOLARIS_THREADS) \ - || defined(HPUX_THREADS) || defined(IRIX_THREADS) +# if defined(GC_PTHREADS) || defined(GC_SOLARIS_THREADS) # if defined(dlopen) && !defined(GC_USE_LD_WRAP) /* To support various threads pkgs, gc.h interposes on dlopen by */ @@ -90,7 +89,7 @@ # endif return(result); } -# endif /* LINUX_THREADS || SOLARIS_THREADS || ... */ +# endif /* GC_PTHREADS || GC_SOLARIS_THREADS ... */ diff --git a/ia64_save_regs_in_stack.s b/ia64_save_regs_in_stack.s new file mode 100644 index 00000000..3b18c084 --- /dev/null +++ b/ia64_save_regs_in_stack.s @@ -0,0 +1,12 @@ + .text + .align 16 + .global GC_save_regs_in_stack + .proc GC_save_regs_in_stack +GC_save_regs_in_stack: + .body + flushrs + ;; + mov r8=ar.bsp + br.ret.sptk.few rp + .endp GC_save_regs_in_stack + diff --git a/include/gc.h b/include/gc.h index aaf29ee3..8ac709b9 100644 --- a/include/gc.h +++ b/include/gc.h @@ -30,13 +30,9 @@ # define _GC_H -#if defined(_SOLARIS_PTHREADS) && !defined(SOLARIS_THREADS) -# define SOLARIS_THREADS -#endif - /* * Some tests for old macros. These violate our namespace rules and will - * disappear shortly. + * disappear shortly. Use the GC_ names. */ #if defined(SOLARIS_THREADS) || defined(_SOLARIS_THREADS) # define GC_SOLARIS_THREADS @@ -72,6 +68,16 @@ /* depend on this were previously included. */ #endif +#if defined(GC_SOLARIS_PTHREADS) && !defined(GC_SOLARIS_THREADS) +# define GC_SOLARIS_THREADS +#endif + +# if defined(GC_SOLARIS_PTHREADS) || defined(GC_FREEBSD_THREADS) || \ + defined(GC_IRIX_THREADS) || defined(GC_LINUX_THREADS) || \ + defined(GC_HPUX_THREADS) || defined(GC_OSF1_THREADS) +# define GC_PTHREADS +# endif + # define __GC # include # ifdef _WIN32_WCE @@ -80,7 +86,7 @@ typedef long ptrdiff_t; /* ptrdiff_t is not defined */ # endif -#if defined(__MINGW32__) && defined(WIN32_THREADS) +#if defined(__MINGW32__) && defined(GC_WIN32_THREADS) # ifdef GC_BUILD # define GC_API __declspec(dllexport) # else @@ -815,16 +821,12 @@ GC_API void (*GC_is_visible_print_proc) /* thread library calls. We do that here by macro defining them. */ #if !defined(GC_USE_LD_WRAP) && \ - (defined(GC_LINUX_THREADS) || defined(GC_HPUX_THREADS) || \ - defined(GC_IRIX_THREADS) || defined(GC_SOLARIS_PTHREADS) || \ - defined(GC_SOLARIS_THREADS) || defined(GC_OSF1_THREADS)) + (defined(GC_PTHREADS) || defined(GC_SOLARIS_THREADS)) # include "gc_pthread_redirects.h" #endif # if defined(PCR) || defined(GC_SOLARIS_THREADS) || \ - defined(GC_SOLARIS_PTHREADS) || defined(GC_WIN32_THREADS) || \ - defined(GC_IRIX_THREADS) || defined(GC_LINUX_THREADS) || \ - defined(GC_HPUX_THREADS) + defined(GC_PTHREADS) || defined(GC_WIN32_THREADS) /* Any flavor of threads except SRC_M3. */ /* This returns a list of objects, linked through their first */ /* word. Its use can greatly reduce lock contention problems, since */ @@ -839,7 +841,7 @@ extern void GC_thr_init(); /* Needed for Solaris/X86 */ #endif /* THREADS && !SRC_M3 */ -#if defined(WIN32_THREADS) && defined(_WIN32_WCE) +#if defined(GC_WIN32_THREADS) && defined(_WIN32_WCE) # include /* diff --git a/include/gc_gcj.h b/include/gc_gcj.h index 9123a28b..5e932afe 100644 --- a/include/gc_gcj.h +++ b/include/gc_gcj.h @@ -47,8 +47,6 @@ /* The following allocators signal an out of memory condition with */ /* return GC_oom_fn(bytes); */ -extern void * (*GC_oom_action)(void); - /* The following function must be called before the gcj allocators */ /* can be invoked. */ /* mp_index and mp are the index and mark_proc (see gc_mark.h) */ diff --git a/include/new_gc_alloc.h b/include/new_gc_alloc.h index 1187f0b6..aad94465 100644 --- a/include/new_gc_alloc.h +++ b/include/new_gc_alloc.h @@ -50,7 +50,20 @@ #ifndef GC_ALLOC_H #include "gc.h" -#include // A more portable way to get stl_alloc.h . + +#if (__GNUC__ < 3) +# include // A more portable way to get stl_alloc.h . +#else +# include +# ifndef __STL_BEGIN_NAMESPACE +# define __STL_BEGIN_NAMESPACE namespace std { +# define __STL_END_NAMESPACE }; +# endif +#ifndef __STL_USE_STD_ALLOCATORS +#define __STL_USE_STD_ALLOCATORS +#endif +#endif + #define GC_ALLOC_H diff --git a/include/private/gc_locks.h b/include/private/gc_locks.h index eed9f105..5ea1e543 100644 --- a/include/private/gc_locks.h +++ b/include/private/gc_locks.h @@ -76,7 +76,7 @@ # define LOCK() RT0u__inCritical++ # define UNLOCK() RT0u__inCritical-- # endif -# ifdef SOLARIS_THREADS +# ifdef GC_SOLARIS_THREADS # include # include extern mutex_t GC_allocate_ml; @@ -261,8 +261,8 @@ # define USE_PTHREAD_LOCKS # endif -# if defined(LINUX_THREADS) || defined(OSF1_THREADS) \ - || defined(HPUX_THREADS) +# if defined(GC_PTHREADS) && !defined(GC_SOLARIS_THREADS) \ + && !defined(GC_IRIX_THREADS) # define NO_THREAD (pthread_t)(-1) # include # if defined(PARALLEL_MARK) @@ -412,8 +412,8 @@ # ifdef GC_ASSERTIONS extern pthread_t GC_mark_lock_holder; # endif -# endif /* LINUX_THREADS || OSF1_THREADS || HPUX_THREADS */ -# if defined(IRIX_THREADS) +# endif /* GC_PTHREADS with linux_threads.c implementation */ +# if defined(GC_IRIX_THREADS) # include /* This probably should never be included, but I can't test */ /* on Irix anymore. */ @@ -439,8 +439,8 @@ GC_collecting = 1; \ } # define EXIT_GC() GC_collecting = 0; -# endif /* IRIX_THREADS */ -# ifdef WIN32_THREADS +# endif /* GC_IRIX_THREADS */ +# ifdef GC_WIN32_THREADS # include GC_API CRITICAL_SECTION GC_allocate_ml; # define LOCK() EnterCriticalSection(&GC_allocate_ml); diff --git a/include/private/gc_priv.h b/include/private/gc_priv.h index 5135e3e9..ad204e99 100644 --- a/include/private/gc_priv.h +++ b/include/private/gc_priv.h @@ -443,18 +443,21 @@ struct hblk; /* See below. */ /* clear on that point). Standard malloc implementations are usually */ /* neither interruptable nor thread-safe, and thus correspond to */ /* empty definitions. */ +/* It probably doesn't make any sense to declare these to be nonempty */ +/* if the code is being optimized, since signal safety relies on some */ +/* ordering constraints that are typically not obeyed by optimizing */ +/* compilers. */ # ifdef PCR # define DISABLE_SIGNALS() \ PCR_Th_SetSigMask(PCR_allSigsBlocked,&GC_old_sig_mask) # define ENABLE_SIGNALS() \ PCR_Th_SetSigMask(&GC_old_sig_mask, NIL) # else -# if defined(SRC_M3) || defined(AMIGA) || defined(SOLARIS_THREADS) \ +# if defined(THREADS) || defined(AMIGA) \ || defined(MSWIN32) || defined(MSWINCE) || defined(MACOS) \ - || defined(DJGPP) || defined(NO_SIGNALS) || defined(IRIX_THREADS) \ - || defined(LINUX_THREADS) + || defined(DJGPP) || defined(NO_SIGNALS) /* Also useful for debugging. */ - /* Should probably use thr_sigsetmask for SOLARIS_THREADS. */ + /* Should probably use thr_sigsetmask for GC_SOLARIS_THREADS. */ # define DISABLE_SIGNALS() # define ENABLE_SIGNALS() # else @@ -479,9 +482,8 @@ struct hblk; /* See below. */ PCR_allSigsBlocked, \ PCR_waitForever); # else -# if defined(SOLARIS_THREADS) || defined(WIN32_THREADS) \ - || defined(IRIX_THREADS) || defined(LINUX_THREADS) \ - || defined(HPUX_THREADS) +# if defined(GC_SOLARIS_THREADS) || defined(GC_WIN32_THREADS) \ + || defined(GC_PTHREADS) void GC_stop_world(); void GC_start_world(); # define STOP_WORLD() GC_stop_world() @@ -566,7 +568,8 @@ extern GC_warn_proc GC_current_warn_proc; # ifdef SMALL_CONFIG # define CPP_LOG_HBLKSIZE 10 # else -# if CPP_WORDSZ == 32 +# if (CPP_WORDSZ == 32) || (defined(HPUX) && defined(HP_PA)) + /* HPUX/PA seems to use 4K pages with the 64 bit ABI */ # define CPP_LOG_HBLKSIZE 12 # else # define CPP_LOG_HBLKSIZE 13 @@ -1903,8 +1906,7 @@ void GC_err_puts GC_PROTO((GC_CONST char *s)); /* some other reason. */ # endif /* PARALLEL_MARK */ -# if defined(LINUX_THREADS) || defined(IRIX_THREADS) \ - || defined(HPUX_THREADS) || defined(OSF1_THREADS) +# if defined(GC_PTHREADS) && !defined(GC_SOLARIS_THREADS) /* We define the thread suspension signal here, so that we can refer */ /* to it in the dirty bit implementation, if necessary. Ideally we */ /* would allocate a (real-time ?) signal using the standard mechanism.*/ @@ -1912,16 +1914,16 @@ void GC_err_puts GC_PROTO((GC_CONST char *s)); /* in Linux glibc, but it's not exported.) Thus we continue to use */ /* the same hard-coded signals we've always used. */ # if !defined(SIG_SUSPEND) -# if defined(LINUX_THREADS) +# if defined(GC_LINUX_THREADS) # if defined(SPARC) && !defined(SIGPWR) /* SPARC/Linux doesn't properly define SIGPWR in . * It is aliased to SIGLOST in asm/signal.h, though. */ # define SIG_SUSPEND SIGLOST # else - /* Linuxthreads uses SIGUSR1 and SIGUSR2. */ + /* Linuxthreads itself uses SIGUSR1 and SIGUSR2. */ # define SIG_SUSPEND SIGPWR # endif -# else /* !LINUX_THREADS */ +# else /* !GC_LINUX_THREADS */ # define SIG_SUSPEND _SIGRTMIN + 6 # endif # endif /* !SIG_SUSPEND */ diff --git a/include/private/gcconfig.h b/include/private/gcconfig.h index a0d12c84..6f25d305 100644 --- a/include/private/gcconfig.h +++ b/include/private/gcconfig.h @@ -33,6 +33,11 @@ # define NETBSD # endif +/* And one for OpenBSD: */ +# if defined(__OpenBSD__) +# define OPENBSD +# endif + /* Determine the machine type: */ # if defined(sun) && defined(mc68000) # define M68K @@ -44,25 +49,23 @@ # define HP # define mach_type_known # endif -# if defined(__OpenBSD__) && defined(m68k) +# if defined(OPENBSD) && defined(m68k) # define M68K -# define OPENBSD # define mach_type_known # endif -# if defined(__OpenBSD__) && defined(__sparc__) +# if defined(OPENBSD) && defined(__sparc__) # define SPARC -# define OPENBSD # define mach_type_known # endif -# if defined(__NetBSD__) && defined(m68k) +# if defined(NETBSD) && defined(m68k) # define M68K # define mach_type_known # endif -# if defined(__NetBSD__) && defined(__powerpc__) +# if defined(NETBSD) && defined(__powerpc__) # define POWERPC # define mach_type_known # endif -# if defined(__NetBSD__) && defined(__arm32__) +# if defined(NETBSD) && defined(__arm32__) # define ARM32 # define mach_type_known # endif @@ -161,6 +164,11 @@ # endif # define mach_type_known # endif +# if defined(__ia64) && defined(_HPUX_SOURCE) +# define IA64 +# define HPUX +# define mach_type_known +# endif # if defined(__BEOS__) && defined(_X86_) # define I386 # define BEOS @@ -196,7 +204,7 @@ # endif # if defined(__alpha) || defined(__alpha__) # define ALPHA -# if !defined(LINUX) && !defined(NETBSD) +# if !defined(LINUX) && !defined(NETBSD) && !defined(OPENBSD) # define OSF1 /* a.k.a Digital Unix */ # endif # define mach_type_known @@ -386,7 +394,7 @@ /* RS6000 ==> IBM RS/6000 AIX3.X */ /* RT ==> IBM PC/RT */ /* HP_PA ==> HP9000/700 & /800 */ - /* HP/UX, LINUX */ + /* HP/UX, LINUX */ /* SPARC ==> SPARC v7/v8/v9 */ /* (SUNOS4, SUNOS5, LINUX, */ /* DRSNX variants) */ @@ -398,8 +406,11 @@ /* running Amdahl UTS4 */ /* or a 390 running LINUX */ /* ARM32 ==> Intel StrongARM */ - /* IA64 ==> Intel IA64 */ + /* IA64 ==> Intel IPF */ /* (e.g. Itanium) */ + /* (LINUX and HPUX) */ + /* IA64_32 ==> IA64 w/32 bit ABI */ + /* (HPUX) */ /* SH ==> Hitachi SuperH */ /* (LINUX & MSWINCE) */ @@ -533,7 +544,7 @@ # ifdef LINUX # define OS_TYPE "LINUX" # define STACKBOTTOM ((ptr_t)0xf0000000) -# define MPROTECT_VDB +/* # define MPROTECT_VDB - Reported to not work 9/17/01 */ # ifdef __ELF__ # define DYNAMIC_LOADING # include @@ -888,7 +899,7 @@ /* with 2GB physical memory will usually move the user */ /* address space limit, and hence initial SP to 0x80000000. */ # endif -# if !defined(LINUX_THREADS) || !defined(REDIRECT_MALLOC) +# if !defined(GC_LINUX_THREADS) || !defined(REDIRECT_MALLOC) # define MPROTECT_VDB # else /* We seem to get random errors in incremental mode, */ @@ -1005,6 +1016,9 @@ # define OS_TYPE "FREEBSD" # define MPROTECT_VDB # define FREEBSD_STACKBOTTOM +# ifdef __ELF__ +# define DYNAMIC_LOADING +# endif # endif # ifdef NETBSD # define OS_TYPE "NETBSD" @@ -1161,7 +1175,6 @@ # ifdef HP_PA # define MACH_TYPE "HP_PA" -# define OS_TYPE "HPUX" # ifdef __LP64__ # define CPP_WORDSZ 64 # define ALIGNMENT 8 @@ -1170,8 +1183,7 @@ # define ALIGNMENT 4 # define ALIGN_DOUBLE # endif -# if !defined(GC_HPUX_THREADS) && !defined(HPUX_THREADS) \ - && !defined(GC_LINUX_THREADS) && !defined(LINUX_THREADS) +# if !defined(GC_HPUX_THREADS) && !defined(GC_LINUX_THREADS) # ifndef LINUX /* For now. */ # define MPROTECT_VDB # endif @@ -1186,6 +1198,7 @@ # endif # define STACK_GROWS_UP # ifdef HPUX +# define OS_TYPE "HPUX" extern int __data_start; # define DATASTART ((ptr_t)(&__data_start)) # if 0 @@ -1242,6 +1255,19 @@ # define CPP_WORDSZ 64 # define DYNAMIC_LOADING # endif +# ifdef OPENBSD +# define OS_TYPE "OPENBSD" +# define HEURISTIC2 +# define CPP_WORDSZ 64 +# ifdef __ELF__ /* since OpenBSD/Alpha 2.9 */ +# define DATASTART GC_data_start +# define ELFCLASS32 32 +# define ELFCLASS64 64 +# define ELF_CLASS ELFCLASS64 +# else /* ECOFF, until OpenBSD/Alpha 2.7 */ +# define DATASTART ((ptr_t) 0x140000000) +# endif +# endif # ifdef OSF1 # define OS_TYPE "OSF1" # define DATASTART ((ptr_t) 0x140000000) @@ -1284,9 +1310,6 @@ # ifdef IA64 # define MACH_TYPE "IA64" -# define ALIGN_DOUBLE - /* Requires 16 byte alignment for malloc */ -# define ALIGNMENT 8 # define USE_GENERIC_PUSH_REGS /* We need to get preserved registers in addition to register */ /* windows. That's easiest to do with setjmp. */ @@ -1296,11 +1319,47 @@ /* setting mark bits. */ # endif # ifdef HPUX - --> needs work +# ifdef _ILP32 +# define CPP_WORDSZ 32 +# define ALIGN_DOUBLE + /* Requires 8 byte alignment for malloc */ +# define ALIGNMENT 4 +# else +# ifndef _LP64 + ---> unknown ABI +# endif +# define CPP_WORDSZ 64 +# define ALIGN_DOUBLE + /* Requires 16 byte alignment for malloc */ +# define ALIGNMENT 8 +# endif +# define OS_TYPE "HPUX" + extern int __data_start; +# define DATASTART ((ptr_t)(&__data_start)) + /* Gustavo Rodriguez-Rivera suggested changing HEURISTIC2 */ + /* to this. Note that the GC must be initialized before the */ + /* first putenv call. */ + extern char ** environ; +# define STACKBOTTOM ((ptr_t)environ) +# define DYNAMIC_LOADING +# include +# define GETPAGESIZE() sysconf(_SC_PAGE_SIZE) + /* The following was empirically determined, and is probably */ + /* not very robust. */ + /* Note that the backing store base seems to be at a nice */ + /* address minus one page. */ +# define BACKING_STORE_DISPLACEMENT 0x1000000 +# define BACKING_STORE_ALIGNMENT 0x1000 +# define BACKING_STORE_BASE \ + (ptr_t)(((word)GC_stackbottom - BACKING_STORE_DISPLACEMENT - 1) \ + & ~(BACKING_STORE_ALIGNMENT - 1)) # endif # ifdef LINUX +# define CPP_WORDSZ 64 +# define ALIGN_DOUBLE + /* Requires 16 byte alignment for malloc */ +# define ALIGNMENT 8 # define OS_TYPE "LINUX" -# define CPP_WORDSZ 64 /* The following works on NUE and older kernels: */ /* # define STACKBOTTOM ((ptr_t) 0xa000000000000000l) */ /* This does not work on NUE: */ @@ -1581,57 +1640,33 @@ ((word*)x)[1] = 0; # endif /* CLEAR_DOUBLE */ -/* Internally to the collector we test only the XXX_THREADS macros */ -/* not the GC_XXX_THREADS versions. Here we make sure the latter */ -/* are treated as equivalent. */ -#if defined(GC_SOLARIS_THREADS) && !defined(_SOLARIS_THREADS) -# define _SOLARIS_THREADS -#endif -#if defined(GC_SOLARIS_THREADS) && !defined(_SOLARIS_PTHREADS) -# define _SOLARIS_PTHREADS -#endif -#if defined(GC_IRIX_THREADS) && !defined(IRIX_THREADS) -# define IRIX_THREADS -#endif -#if defined(GC_LINUX_THREADS) && !defined(LINUX_THREADS) -# define LINUX_THREADS -#endif -#if defined(GC_WIN32_THREADS) && !defined(WIN32_THREADS) -# define WIN32_THREADS -#endif -#if defined(GC_HPUX_THREADS) && !defined(HPUX_THREADS) -# define HPUX_THREADS -#endif -#if defined(GC_OSF1_THREADS) && !defined(OSF1_THREADS) -# define OSF1_THREADS -#endif - -/* Internally we use SOLARIS_THREADS to test for either old or pthreads. */ -# if defined(_SOLARIS_PTHREADS) && !defined(SOLARIS_THREADS) -# define SOLARIS_THREADS +/* Internally we use GC_SOLARIS_THREADS to test for either old or pthreads. */ +# if defined(GC_SOLARIS_PTHREADS) && !defined(GC_SOLARIS_THREADS) +# define GC_SOLARIS_THREADS # endif -# if defined(IRIX_THREADS) && !defined(IRIX5) + +# if defined(GC_IRIX_THREADS) && !defined(IRIX5) --> inconsistent configuration # endif -# if defined(LINUX_THREADS) && !defined(LINUX) +# if defined(GC_LINUX_THREADS) && !defined(LINUX) --> inconsistent configuration # endif -# if defined(SOLARIS_THREADS) && !defined(SUNOS5) +# if defined(GC_SOLARIS_THREADS) && !defined(SUNOS5) --> inconsistent configuration # endif -# if defined(HPUX_THREADS) && !defined(HPUX) +# if defined(GC_HPUX_THREADS) && !defined(HPUX) --> inconsistent configuration # endif -# if defined(WIN32_THREADS) && !defined(MSWIN32) - /* Ideally CYGWIN32 should work, in addition to MSWIN32. I suspect the necessary code */ - /* is mostly there, but nobody has actually made sure the right combination of pieces is */ - /* compiled in, etc. */ +# if defined(GC_WIN32_THREADS) && !defined(MSWIN32) + /* Ideally CYGWIN32 should work, in addition to MSWIN32. I suspect */ + /* the necessary code is mostly there, but nobody has actually made */ + /* sure the right combination of pieces is compiled in, etc. */ --> inconsistent configuration # endif + # if defined(PCR) || defined(SRC_M3) || \ - defined(SOLARIS_THREADS) || defined(WIN32_THREADS) || \ - defined(IRIX_THREADS) || defined(LINUX_THREADS) || \ - defined(HPUX_THREADS) || defined(OSF1_THREADS) + defined(GC_SOLARIS_THREADS) || defined(GC_WIN32_THREADS) || \ + defined(GC_PTHREADS) # define THREADS # endif diff --git a/irix_threads.c b/irix_threads.c index 12aba546..c894a310 100644 --- a/irix_threads.c +++ b/irix_threads.c @@ -21,11 +21,11 @@ * HP/UX 11. * * Note that there is a lot of code duplication between linux_threads.c - * and hpux_irix_threads.c; any changes made here may need to be reflected + * and irix_threads.c; any changes made here may need to be reflected * there too. */ -# if defined(GC_IRIX_THREADS) || defined(IRIX_THREADS) +# if defined(GC_IRIX_THREADS) # include "private/gc_priv.h" # include @@ -725,5 +725,5 @@ yield: int GC_no_Irix_threads; #endif -# endif /* IRIX_THREADS */ +# endif /* GC_IRIX_THREADS */ diff --git a/linux_threads.c b/linux_threads.c index 074be891..7958ed9b 100644 --- a/linux_threads.c +++ b/linux_threads.c @@ -50,13 +50,14 @@ /* ANSI C requires that a compilation unit contains something */ -# if defined(GC_LINUX_THREADS) || defined(LINUX_THREADS) \ - || defined(GC_HPUX_THREADS) || defined(HPUX_THREADS) \ - || defined(GC_OSF1_THREADS) || defined(OSF1_THREADS) \ +# include "gc.h" + +# if defined(GC_PTHREADS) && !defined(GC_SOLARIS_THREADS) \ + && !defined(GC_IRIX_THREADS) # include "private/gc_priv.h" -# if defined(HPUX_THREADS) && !defined(USE_PTHREAD_SPECIFIC) \ +# if defined(GC_HPUX_THREADS) && !defined(USE_PTHREAD_SPECIFIC) \ && !defined(USE_HPUX_TLS) # define USE_HPUX_TLS # endif @@ -449,7 +450,7 @@ GC_PTR GC_local_gcj_malloc(size_t bytes, */ #ifndef SIG_THR_RESTART -# if defined(HPUX_THREADS) || defined(GC_OSF1_THREADS) +# if defined(GC_HPUX_THREADS) || defined(GC_OSF1_THREADS) # define SIG_THR_RESTART _SIGRTMIN + 5 # else # define SIG_THR_RESTART SIGXCPU @@ -458,16 +459,19 @@ GC_PTR GC_local_gcj_malloc(size_t bytes, sem_t GC_suspend_ack_sem; -#if !defined(HPUX_THREADS) && !defined(GC_OSF1_THREADS) +#if 0 /* To make sure that we're using LinuxThreads and not some other thread package, we generate a dummy reference to `pthread_kill_other_threads_np' (was `__pthread_initial_thread_bos' but that disappeared), which is a symbol defined in LinuxThreads, but (hopefully) not in other thread packages. + +We no longer do this, since this code is now portable enough that it might +actually work for something else. */ void (*dummy_var_to_force_linux_threads)() = pthread_kill_other_threads_np; -#endif /* !HPUX_THREADS */ +#endif /* 0 */ #if defined(SPARC) || defined(IA64) extern word GC_save_regs_in_stack(); @@ -530,6 +534,24 @@ static void start_mark_threads() if (0 != pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED)) ABORT("pthread_attr_setdetachstate failed"); + +# ifdef HPUX + /* Default stack size is usually too small: fix it. */ + /* Otherwise marker threads or GC may run out of */ + /* space. */ +# define MIN_STACK_SIZE (8*HBLKSIZE*sizeof(word)) + { + size_t old_size; + int code; + + if (pthread_attr_getstacksize(&attr, &old_size) != 0) + ABORT("pthread_attr_getstacksize failed\n"); + if (old_size < MIN_STACK_SIZE) { + if (pthread_attr_setstacksize(&attr, MIN_STACK_SIZE) != 0) + ABORT("pthread_attr_getstacksize failed\n"); + } + } +# endif /* HPUX */ # ifdef CONDPRINT if (GC_print_stats) { GC_printf1("Starting %ld marker threads\n", GC_markers - 1); @@ -969,7 +991,7 @@ int GC_segment_is_thread_stack(ptr_t lo, ptr_t hi) } #endif /* USE_PROC_FOR_LIBRARIES */ -#ifdef LINUX_THREADS +#ifdef GC_LINUX_THREADS /* Return the number of processors, or i<= 0 if it can't be determined. */ int GC_get_nprocs() { @@ -1005,7 +1027,7 @@ int GC_get_nprocs() } return result; } -#endif /* LINUX_THREADS */ +#endif /* GC_LINUX_THREADS */ /* We hold the allocation lock. */ void GC_thr_init() @@ -1063,13 +1085,13 @@ void GC_thr_init() if (nprocs_string != NULL) GC_nprocs = atoi(nprocs_string); } if (GC_nprocs <= 0) { -# if defined(HPUX_THREADS) +# if defined(GC_HPUX_THREADS) GC_nprocs = pthread_num_processors_np(); # endif -# if defined(OSF1_THREADS) +# if defined(GC_OSF1_THREADS) || defined(GC_FREEBSD_THREADS) GC_nprocs = 1; # endif -# ifdef LINUX_THREADS +# if defined(GC_LINUX_THREADS) GC_nprocs = GC_get_nprocs(); # endif } @@ -1584,7 +1606,7 @@ void GC_lock() pthread_t GC_mark_lock_holder = NO_THREAD; #endif -#ifdef IA64 +#if 0 /* Ugly workaround for a linux threads bug in the final versions */ /* of glibc2.1. Pthread_mutex_trylock sets the mutex owner */ /* field even when it fails to acquire the mutex. This causes */ @@ -1691,5 +1713,5 @@ void GC_notify_all_marker() #endif /* PARALLEL_MARK */ -# endif /* LINUX_THREADS */ +# endif /* GC_LINUX_THREADS and friends */ diff --git a/mach_dep.c b/mach_dep.c index 776bf690..35e9264b 100644 --- a/mach_dep.c +++ b/mach_dep.c @@ -492,8 +492,9 @@ ptr_t cold_gc_frame; /* On IA64, we also need to flush register windows. But they end */ /* up on the other side of the stack segment. */ /* Returns the backing store pointer for the register stack. */ +/* We implement this as a separate file in HP/UX. */ # ifdef IA64 -# ifdef __GNUC__ +# ifdef LINUX asm(" .text"); asm(" .psr abi64"); asm(" .psr lsb"); @@ -510,12 +511,25 @@ ptr_t cold_gc_frame; asm(" mov r8=ar.bsp"); asm(" br.ret.sptk.few rp"); asm(" .endp GC_save_regs_in_stack"); -# else - void GC_save_regs_in_stack() { - asm(" flushrs"); - asm(" ;;"); - asm(" mov r8=ar.bsp"); - asm(" br.ret.sptk.few rp"); +# endif /* LINUX */ +# if 0 /* Other alternatives that don't work on HP/UX */ + word GC_save_regs_in_stack() { +# if USE_BUILTINS + __builtin_ia64_flushrs(); + return __builtin_ia64_bsp(); +# else +# ifdef HPUX + _asm(" flushrs"); + _asm(" ;;"); + _asm(" mov r8=ar.bsp"); + _asm(" br.ret.sptk.few rp"); +# else + asm(" flushrs"); + asm(" ;;"); + asm(" mov r8=ar.bsp"); + asm(" br.ret.sptk.few rp"); +# endif +# endif } # endif # endif diff --git a/malloc.c b/malloc.c index 0bbb96ab..943f27d3 100644 --- a/malloc.c +++ b/malloc.c @@ -315,7 +315,7 @@ DCL_LOCK_STATE; /* It might help to manually inline the GC_malloc call here. */ /* But any decent compiler should reduce the extra procedure call */ /* to at most a jump instruction in this case. */ -# if defined(I386) && defined(SOLARIS_THREADS) +# if defined(I386) && defined(GC_SOLARIS_THREADS) /* * Thread initialisation can call malloc before * we're ready for it. @@ -324,7 +324,7 @@ DCL_LOCK_STATE; * inopportune times. */ if (!GC_is_initialized) return sbrk(lb); -# endif /* I386 && SOLARIS_THREADS */ +# endif /* I386 && GC_SOLARIS_THREADS */ return((GC_PTR)REDIRECT_MALLOC(lb)); } @@ -360,7 +360,7 @@ DCL_LOCK_STATE; h = HBLKPTR(p); hhdr = HDR(h); # if defined(REDIRECT_MALLOC) && \ - (defined(SOLARIS_THREADS) || defined(LINUX_THREADS) \ + (defined(GC_SOLARIS_THREADS) || defined(GC_LINUX_THREADS) \ || defined(__MINGW32__)) /* Should this be MSWIN32 in general? */ /* For Solaris, we have to redirect malloc calls during */ /* initialization. For the others, this seems to happen */ diff --git a/mark_rts.c b/mark_rts.c index 251a0d14..a082e2b2 100644 --- a/mark_rts.c +++ b/mark_rts.c @@ -568,11 +568,11 @@ ptr_t cold_gc_frame; */ # if !defined(USE_GENERIC_PUSH_REGS) GC_push_current_stack(cold_gc_frame); - /* IN the threads case, this only pushes collector frames. */ + /* In the threads case, this only pushes collector frames. */ /* In the USE_GENERIC_PUSH_REGS case, this is done inside */ /* GC_push_regs, so that we catch callee-save registers saved */ /* inside the GC_push_regs frame. */ - /* In the case of linux threads on Ia64, the hot section of */ + /* In the case of linux threads on IA64, the hot section of */ /* the main stack is marked here, but the register stack */ /* backing store is handled in the threads-specific code. */ # endif diff --git a/misc.c b/misc.c index 94ef15d3..2bb93f3d 100644 --- a/misc.c +++ b/misc.c @@ -22,7 +22,7 @@ #define I_HIDE_POINTERS /* To make GC_call_with_alloc_lock visible */ #include "private/gc_pmark.h" -#ifdef SOLARIS_THREADS +#ifdef GC_SOLARIS_THREADS # include #endif #if defined(MSWIN32) || defined(MSWINCE) @@ -41,29 +41,27 @@ /* Critical section counter is defined in the M3 runtime */ /* That's all we use. */ # else -# ifdef SOLARIS_THREADS +# ifdef GC_SOLARIS_THREADS mutex_t GC_allocate_ml; /* Implicitly initialized. */ # else -# ifdef WIN32_THREADS +# ifdef GC_WIN32_THREADS # if !defined(GC_NOT_DLL) && (defined(_DLL) || defined(GC_DLL)) __declspec(dllexport) CRITICAL_SECTION GC_allocate_ml; # else CRITICAL_SECTION GC_allocate_ml; # endif # else -# if defined(IRIX_THREADS) \ - || (defined(LINUX_THREADS) && defined(USE_SPIN_LOCK)) - pthread_t GC_lock_holder = NO_THREAD; -# else -# if defined(HPUX_THREADS) \ - || defined(LINUX_THREADS) && !defined(USE_SPIN_LOCK) +# if defined(GC_PTHREADS) && !defined(GC_SOLARIS_THREADS) +# if defined(USE_SPIN_LOCK) + pthread_t GC_lock_holder = NO_THREAD; +# else pthread_mutex_t GC_allocate_ml = PTHREAD_MUTEX_INITIALIZER; pthread_t GC_lock_holder = NO_THREAD; /* Used only for assertions, and to prevent */ /* recursive reentry in the system call wrapper. */ -# else +# endif +# else --> declare allocator lock here -# endif # endif # endif # endif @@ -524,20 +522,18 @@ void GC_init_inner() # if defined(SEARCH_FOR_DATA_START) GC_init_linux_data_start(); # endif -# if defined(NETBSD) && defined(__ELF__) +# if (defined(NETBSD) || defined(OPENBSD)) && defined(__ELF__) GC_init_netbsd_elf(); # endif -# if defined(IRIX_THREADS) || defined(LINUX_THREADS) \ - || defined(HPUX_THREADS) || defined(SOLARIS_THREADS) +# if defined(GC_PTHREADS) || defined(GC_SOLARIS_THREADS) GC_thr_init(); # endif -# ifdef SOLARIS_THREADS +# ifdef GC_SOLARIS_THREADS /* We need dirty bits in order to find live stack sections. */ GC_dirty_init(); # endif -# if !defined(THREADS) || defined(SOLARIS_THREADS) || defined(WIN32_THREADS) \ - || defined(IRIX_THREADS) || defined(LINUX_THREADS) \ - || defined(HPUX_THREADS) +# if !defined(THREADS) || defined(GC_PTHREADS) || defined(GC_WIN32_THREADS) \ + || defined(GC_SOLARIS_THREADS) if (GC_stackbottom == 0) { GC_stackbottom = GC_get_stack_base(); # if defined(LINUX) && defined(IA64) @@ -652,7 +648,7 @@ void GC_enable_incremental GC_PROTO(()) if (GC_is_win32s()) goto out; } # endif /* MSWIN32 */ -# ifndef SOLARIS_THREADS +# ifndef GC_SOLARIS_THREADS GC_dirty_init(); # endif if (!GC_is_initialized) { @@ -753,7 +749,7 @@ size_t len; register int result; while (bytes_written < len) { -# ifdef SOLARIS_THREADS +# ifdef GC_SOLARIS_THREADS result = syscall(SYS_write, fd, buf + bytes_written, len - bytes_written); # else diff --git a/new_hblk.c b/new_hblk.c index d904aedc..1aa2c7a1 100644 --- a/new_hblk.c +++ b/new_hblk.c @@ -247,6 +247,7 @@ int kind; ABORT("HBLK SZ inconsistency"); } # endif + if (GC_debugging_started) clear = TRUE; /* Allocate a new heap block */ h = GC_allochblk(sz, kind, 0); diff --git a/os_dep.c b/os_dep.c index 79bed4c7..f8fee923 100644 --- a/os_dep.c +++ b/os_dep.c @@ -71,10 +71,6 @@ # define NEED_FIND_LIMIT # endif -# if defined(IRIX_THREADS) || defined(HPUX_THREADS) -# define NEED_FIND_LIMIT -# endif - # if (defined(SUNOS4) && defined(DYNAMIC_LOADING)) && !defined(PCR) # define NEED_FIND_LIMIT # endif @@ -219,7 +215,7 @@ static void *tiny_sbrk(ptrdiff_t increment) #define sbrk tiny_sbrk # endif /* ECOS */ -#if defined(NETBSD) && defined(__ELF__) +#if (defined(NETBSD) || defined(OPENBSD)) && defined(__ELF__) ptr_t GC_data_start; void GC_init_netbsd_elf() @@ -561,7 +557,7 @@ ptr_t GC_get_stack_base() /* signal mask. */ (void) sigemptyset(&act.sa_mask); -# ifdef IRIX_THREADS +# ifdef GC_IRIX_THREADS /* Older versions have a bug related to retrieving and */ /* and setting a handler at the same time. */ (void) sigaction(SIGSEGV, 0, &old_segv_act); @@ -575,7 +571,7 @@ ptr_t GC_get_stack_base() /* don't have to worry in the threads case. */ (void) sigaction(SIGBUS, &act, &old_bus_act); # endif -# endif /* IRIX_THREADS */ +# endif /* GC_IRIX_THREADS */ # else old_segv_handler = signal(SIGSEGV, h); # ifdef SIGBUS @@ -670,7 +666,12 @@ ptr_t GC_get_stack_base() ptr_t GC_get_register_stack_base(void) { - if (0 != &__libc_ia64_register_backing_store_base) { + if (0 != &__libc_ia64_register_backing_store_base + && 0 != __libc_ia64_register_backing_store_base) { + /* Glibc 2.2.4 has a bug such that for dynamically linked */ + /* executables __libc_ia64_register_backing_store_base is */ + /* defined but ininitialized during constructor calls. */ + /* Hence we check for both nonzero address and value. */ return __libc_ia64_register_backing_store_base; } else { word result = (word)GC_stackbottom - BACKING_STORE_DISPLACEMENT; @@ -1079,7 +1080,7 @@ void GC_register_data_segments() { # if !defined(PCR) && !defined(SRC_M3) && !defined(NEXT) && !defined(MACOS) \ && !defined(MACOSX) -# if defined(REDIRECT_MALLOC) && defined(SOLARIS_THREADS) +# if defined(REDIRECT_MALLOC) && defined(GC_SOLARIS_THREADS) /* As of Solaris 2.3, the Solaris threads implementation */ /* allocates the data structure for the initial thread with */ /* sbrk at process startup. It needs to be scanned, so that */ @@ -1640,9 +1641,8 @@ void GC_default_push_other_roots GC_PROTO((void)) # endif /* SRC_M3 */ -# if defined(SOLARIS_THREADS) || defined(WIN32_THREADS) \ - || defined(IRIX_THREADS) || defined(LINUX_THREADS) \ - || defined(HPUX_THREADS) +# if defined(GC_SOLARIS_THREADS) || defined(GC_PTHREADS) || \ + defined(GC_WIN32_THREADS) extern void GC_push_all_stacks(); @@ -1651,11 +1651,11 @@ void GC_default_push_other_roots GC_PROTO((void)) GC_push_all_stacks(); } -# endif /* SOLARIS_THREADS || ... */ +# endif /* GC_SOLARIS_THREADS || GC_PTHREADS */ void (*GC_push_other_roots) GC_PROTO((void)) = GC_default_push_other_roots; -#endif +#endif /* THREADS */ /* * Routines for accessing dirty bits on virtual pages. @@ -2399,7 +2399,7 @@ void GC_dirty_init() # if defined(SUNOS5SIGS) || defined(IRIX5) || defined(LINUX) \ || defined(OSF1) || defined(HURD) /* SUNOS5SIGS includes HPUX */ -# if defined(IRIX_THREADS) +# if defined(GC_IRIX_THREADS) sigaction(SIGSEGV, 0, &oldact); sigaction(SIGSEGV, &act, 0); # else @@ -2537,7 +2537,7 @@ word len; ((ptr_t)end_block - (ptr_t)start_block) + HBLKSIZE); } -#if !defined(MSWIN32) && !defined(MSWINCE) && !defined(LINUX_THREADS) \ +#if !defined(MSWIN32) && !defined(MSWINCE) && !defined(GC_LINUX_THREADS) \ && !defined(GC_USE_LD_WRAP) /* Replacement for UNIX system call. */ /* Other calls that write to the heap */ @@ -2561,7 +2561,7 @@ word len; GC_begin_syscall(); GC_unprotect_range(buf, (word)nbyte); -# if defined(IRIX5) || defined(LINUX_THREADS) +# if defined(IRIX5) || defined(GC_LINUX_THREADS) /* Indirect system call may not always be easily available. */ /* We could call _read, but that would interfere with the */ /* libpthread interception of read. */ @@ -2587,7 +2587,7 @@ word len; GC_end_syscall(); return(result); } -#endif /* !MSWIN32 && !MSWINCE && !LINUX_THREADS */ +#endif /* !MSWIN32 && !MSWINCE && !GC_LINUX_THREADS */ #ifdef GC_USE_LD_WRAP /* We use the GNU ld call wrapping facility. */ @@ -2660,7 +2660,7 @@ word n; word GC_proc_buf_size = INITIAL_BUF_SZ; char *GC_proc_buf; -#ifdef SOLARIS_THREADS +#ifdef GC_SOLARIS_THREADS /* We don't have exact sp values for threads. So we count on */ /* occasionally declaring stack pages to be fresh. Thus we */ /* need a real implementation of GC_is_fresh. We can't clear */ @@ -2715,7 +2715,7 @@ void GC_dirty_init() ABORT("/proc ioctl failed"); } GC_proc_buf = GC_scratch_alloc(GC_proc_buf_size); -# ifdef SOLARIS_THREADS +# ifdef GC_SOLARIS_THREADS GC_fresh_pages = (struct hblk **) GC_scratch_alloc(MAX_FRESH_PAGES * sizeof (struct hblk *)); if (GC_fresh_pages == 0) { @@ -2733,7 +2733,7 @@ struct hblk *h; { } -#ifdef SOLARIS_THREADS +#ifdef GC_SOLARIS_THREADS # define READ(fd,buf,nbytes) syscall(SYS_read, fd, buf, nbytes) #else # define READ(fd,buf,nbytes) read(fd, buf, nbytes) @@ -2772,7 +2772,7 @@ int dummy; /* Punt: */ memset(GC_grungy_pages, 0xff, sizeof (page_hash_table)); memset(GC_written_pages, 0xff, sizeof(page_hash_table)); -# ifdef SOLARIS_THREADS +# ifdef GC_SOLARIS_THREADS BZERO(GC_fresh_pages, MAX_FRESH_PAGES * sizeof (struct hblk *)); # endif @@ -2802,7 +2802,7 @@ int dummy; register word index = PHT_HASH(h); set_pht_entry_from_index(GC_grungy_pages, index); -# ifdef SOLARIS_THREADS +# ifdef GC_SOLARIS_THREADS { register int slot = FRESH_PAGE_SLOT(h); @@ -2820,7 +2820,7 @@ int dummy; } /* Update GC_written_pages. */ GC_or_pages(GC_written_pages, GC_grungy_pages); -# ifdef SOLARIS_THREADS +# ifdef GC_SOLARIS_THREADS /* Make sure that old stacks are considered completely clean */ /* unless written again. */ GC_old_stacks_are_fresh(); @@ -2836,7 +2836,7 @@ struct hblk *h; register GC_bool result; result = get_pht_entry_from_index(GC_grungy_pages, index); -# ifdef SOLARIS_THREADS +# ifdef GC_SOLARIS_THREADS if (result && PAGE_IS_FRESH(h)) result = FALSE; /* This happens only if page was declared fresh since */ /* the read_dirty call, e.g. because it's in an unused */ @@ -2854,7 +2854,7 @@ struct hblk *h; register GC_bool result; result = get_pht_entry_from_index(GC_written_pages, index); -# ifdef SOLARIS_THREADS +# ifdef GC_SOLARIS_THREADS if (result && PAGE_IS_FRESH(h)) result = FALSE; # endif return(result); @@ -2868,7 +2868,7 @@ word n; register word index; -# ifdef SOLARIS_THREADS +# ifdef GC_SOLARIS_THREADS register word i; if (GC_fresh_pages != 0) { diff --git a/reclaim.c b/reclaim.c index 78995f39..48db1e29 100644 --- a/reclaim.c +++ b/reclaim.c @@ -702,7 +702,8 @@ COUNT_DECL if (report_if_found) { GC_reclaim_check(hbp, hhdr, sz); } else { - *flh = GC_reclaim_generic(hbp, hhdr, sz, ok -> ok_init, + *flh = GC_reclaim_generic(hbp, hhdr, sz, + (ok -> ok_init || GC_debugging_started), *flh MEM_FOUND_ADDR); } } @@ -774,8 +775,12 @@ COUNT_DECL /* Routines to gather and print heap block info */ /* intended for debugging. Otherwise should be called */ /* with lock. */ -static size_t number_of_blocks; -static size_t total_bytes; + +struct Print_stats +{ + size_t number_of_blocks; + size_t total_bytes; +}; #ifdef USE_MARK_BYTES @@ -834,25 +839,30 @@ hdr * hhdr; { register hdr * hhdr = HDR(h); register size_t bytes = WORDS_TO_BYTES(hhdr -> hb_sz); + struct Print_stats *ps; GC_printf3("(%lu:%lu,%lu)", (unsigned long)(hhdr -> hb_obj_kind), (unsigned long)bytes, (unsigned long)(GC_n_set_marks(hhdr))); bytes += HBLKSIZE-1; bytes &= ~(HBLKSIZE-1); - total_bytes += bytes; - number_of_blocks++; + + ps = (struct Print_stats *)dummy; + ps->total_bytes += bytes; + ps->number_of_blocks++; } void GC_print_block_list() { + struct Print_stats pstats; + GC_printf0("(kind(0=ptrfree,1=normal,2=unc.,3=stubborn):size_in_bytes, #_marks_set)\n"); - number_of_blocks = 0; - total_bytes = 0; - GC_apply_to_all_blocks(GC_print_block_descr, (word)0); + pstats.number_of_blocks = 0; + pstats.total_bytes = 0; + GC_apply_to_all_blocks(GC_print_block_descr, (word)&pstats); GC_printf2("\nblocks = %lu, bytes = %lu\n", - (unsigned long)number_of_blocks, - (unsigned long)total_bytes); + (unsigned long)pstats.number_of_blocks, + (unsigned long)pstats.total_bytes); } #endif /* NO_DEBUGGING */ diff --git a/solaris_pthreads.c b/solaris_pthreads.c index 02c33801..e00e00b3 100644 --- a/solaris_pthreads.c +++ b/solaris_pthreads.c @@ -18,7 +18,7 @@ /* Boehm, September 14, 1994 4:44 pm PDT */ /* $Id: solaris_pthreads.c,v 1.10 1997/05/13 23:09:09 peterc Exp $ */ -# if defined(GC_SOLARIS_PTHREADS) || defined(_SOLARIS_PTHREADS) +# if defined(GC_SOLARIS_PTHREADS) # include "private/gc_priv.h" # include # include @@ -176,5 +176,5 @@ GC_pthread_create(pthread_t *new_thread, int GC_no_sunOS_pthreads; #endif -# endif /* SOLARIS_THREADS */ +# endif /* GC_SOLARIS_PTHREADS */ diff --git a/solaris_threads.c b/solaris_threads.c index 8cc6319c..365c6b12 100644 --- a/solaris_threads.c +++ b/solaris_threads.c @@ -16,7 +16,7 @@ */ /* Boehm, September 14, 1994 4:44 pm PDT */ -# if defined(GC_SOLARIS_THREADS) || defined(SOLARIS_THREADS) +# if defined(GC_SOLARIS_THREADS) # include "private/gc_priv.h" # include "private/solaris_threads.h" @@ -938,7 +938,7 @@ GC_thr_create(void *stack_base, size_t stack_size, return(result); } -# else /* SOLARIS_THREADS */ +# else /* !GC_SOLARIS_THREADS */ #ifndef LINT int GC_no_sunOS_threads; diff --git a/specific.c b/specific.c index 5afd10b7..48b53ac9 100644 --- a/specific.c +++ b/specific.c @@ -11,7 +11,7 @@ * modified is included with the above copyright notice. */ -#if defined(LINUX_THREADS) || defined(GC_LINUX_THREADS) +#if defined(GC_LINUX_THREADS) #include "private/gc_priv.h" /* For GC_compare_and_exchange, GC_memory_barrier */ #include "private/specific.h" @@ -105,4 +105,4 @@ void * PREFIXED(slow_getspecific) (tsd * key, unsigned long qtid, return entry -> value; } -#endif /* LINUX_THREADS */ +#endif /* GC_LINUX_THREADS */ diff --git a/tests/test.c b/tests/test.c index 1bd98d64..35cb1357 100644 --- a/tests/test.c +++ b/tests/test.c @@ -59,16 +59,16 @@ # define GC_printf1 printf # endif -# ifdef SOLARIS_THREADS +# if defined(GC_SOLARIS_THREADS) && !defined(GC_SOLARIS_PTHREADS) # include # include # endif -# if defined(IRIX_THREADS) || defined(LINUX_THREADS) || defined(HPUX_THREADS) +# if defined(GC_PTHREADS) # include # endif -# ifdef WIN32_THREADS +# ifdef GC_WIN32_THREADS # ifndef MSWINCE # include # define GC_CreateThread(a,b,c,d,e,f) ((HANDLE) _beginthreadex(a,b,c,d,e,f)) @@ -447,7 +447,7 @@ struct { */ #ifdef THREADS -# ifdef WIN32_THREADS +# ifdef GC_WIN32_THREADS unsigned __stdcall tiny_reverse_test(void * arg) # else void * tiny_reverse_test(void * arg) @@ -457,8 +457,7 @@ struct { return 0; } -# if defined(IRIX_THREADS) || defined(LINUX_THREADS) \ - || defined(SOLARIS_PTHREADS) || defined(HPUX_THREADS) +# if defined(GC_PTHREADS) void fork_a_thread() { pthread_t t; @@ -475,7 +474,7 @@ struct { } } -# elif defined(WIN32_THREADS) +# elif defined(GC_WIN32_THREADS) void fork_a_thread() { unsigned thread_id; @@ -493,7 +492,7 @@ struct { } } -/* # elif defined(SOLARIS_THREADS) */ +/* # elif defined(GC_SOLARIS_THREADS) */ # else @@ -649,15 +648,15 @@ VOLATILE int dropped_something = 0; # ifdef PCR PCR_ThCrSec_EnterSys(); # endif -# ifdef SOLARIS_THREADS +# if defined(GC_SOLARIS_THREADS) && !defined(GC_SOLARIS_PTHREADS) static mutex_t incr_lock; mutex_lock(&incr_lock); # endif -# if defined(IRIX_THREADS) || defined(LINUX_THREADS) || defined(HPUX_THREADS) +# if defined(GC_PTHREADS) static pthread_mutex_t incr_lock = PTHREAD_MUTEX_INITIALIZER; pthread_mutex_lock(&incr_lock); # endif -# ifdef WIN32_THREADS +# ifdef GC_WIN32_THREADS EnterCriticalSection(&incr_cs); # endif if ((int)(GC_word)client_data != t -> level) { @@ -668,13 +667,13 @@ VOLATILE int dropped_something = 0; # ifdef PCR PCR_ThCrSec_ExitSys(); # endif -# ifdef SOLARIS_THREADS +# if defined(GC_SOLARIS_THREADS) && !defined(GC_SOLARIS_PTHREADS) mutex_unlock(&incr_lock); # endif -# if defined(IRIX_THREADS) || defined(LINUX_THREADS) || defined(HPUX_THREADS) +# if defined(GC_PTHREADS) pthread_mutex_unlock(&incr_lock); # endif -# ifdef WIN32_THREADS +# ifdef GC_WIN32_THREADS LeaveCriticalSection(&incr_cs); # endif } @@ -740,16 +739,15 @@ int n; # ifdef PCR PCR_ThCrSec_EnterSys(); # endif -# ifdef SOLARIS_THREADS +# if defined(GC_SOLARIS_THREADS) && !defined(GC_SOLARIS_PTHREADS) static mutex_t incr_lock; mutex_lock(&incr_lock); # endif -# if defined(IRIX_THREADS) || defined(LINUX_THREADS) \ - || defined(HPUX_THREADS) +# if defined(GC_PTHREADS) static pthread_mutex_t incr_lock = PTHREAD_MUTEX_INITIALIZER; pthread_mutex_lock(&incr_lock); # endif -# ifdef WIN32_THREADS +# ifdef GC_WIN32_THREADS EnterCriticalSection(&incr_cs); # endif /* Losing a count here causes erroneous report of failure. */ @@ -758,14 +756,13 @@ int n; # ifdef PCR PCR_ThCrSec_ExitSys(); # endif -# ifdef SOLARIS_THREADS +# if defined(GC_SOLARIS_THREADS) && !defined(GC_SOLARIS_PTHREADS) mutex_unlock(&incr_lock); # endif -# if defined(IRIX_THREADS) || defined(LINUX_THREADS) \ - || defined(HPUX_THREADS) +# if defined(GC_PTHREADS) pthread_mutex_unlock(&incr_lock); # endif -# ifdef WIN32_THREADS +# ifdef GC_WIN32_THREADS LeaveCriticalSection(&incr_cs); # endif } @@ -825,7 +822,7 @@ int n; chktree(t -> rchild, n-1); } -# if defined(SOLARIS_THREADS) && !defined(_SOLARIS_PTHREADS) +# if defined(GC_SOLARIS_THREADS) && !defined(GC_SOLARIS_PTHREADS) thread_key_t fl_key; void * alloc8bytes() @@ -866,9 +863,7 @@ void * alloc8bytes() #else -# if defined(GC_SOLARIS_PTHREADS) || defined(GC_IRIX_THREADS) \ - || defined(GC_LINUX_THREADS) || defined(GC_HPUX_THREADS) \ - || defined(GC_SOLARIS_THREADS) +# if defined(GC_PTHREADS) pthread_key_t fl_key; void * alloc8bytes() @@ -1319,9 +1314,8 @@ void SetMinimumStack(long minSize) #if !defined(PCR) && !defined(GC_SOLARIS_THREADS) \ - && !defined(GC_WIN32_THREADS) \ - && !defined(GC_IRIX_THREADS) && !defined(GC_LINUX_THREADS) \ - && !defined(GC_HPUX_THREADS) || defined(LINT) + && !defined(GC_WIN32_THREADS) && !defined(GC_PTHREADS) \ + || defined(LINT) #if defined(MSWIN32) && !defined(__MINGW32__) int APIENTRY WinMain(HINSTANCE instance, HINSTANCE prev, LPTSTR cmd, int n) #else @@ -1557,8 +1551,7 @@ test() } #endif -#if defined(GC_SOLARIS_THREADS) || defined(GC_IRIX_THREADS) \ - || defined(GC_HPUX_THREADS) || defined(GC_LINUX_THREADS) +#if defined(GC_SOLARIS_THREADS) || defined(GC_PTHREADS) void * thr_run_one_test(void * arg) { run_one_test(); @@ -1569,7 +1562,7 @@ void * thr_run_one_test(void * arg) # define GC_free GC_debug_free #endif -#ifdef GC_SOLARIS_THREADS +#if defined(GC_SOLARIS_THREADS) && !defined(GC_SOLARIS_PTHREADS) main() { thread_t th1; @@ -1606,6 +1599,11 @@ main() return(0); } #else /* pthreads */ + +#ifndef GC_PTHREADS + --> bad news +#endif + main() { pthread_t th1; @@ -1618,8 +1616,15 @@ main() /* Since the initial cant always grow later. */ *((volatile char *)&code - 1024*1024) = 0; /* Require 1 Mb */ # endif /* GC_IRIX_THREADS */ +# if defined(GC_HPUX_THREADS) + /* Default stack size is too small, especially with the 64 bit ABI */ + /* Increase it. */ + if (pthread_default_stacksize_np(1024*1024, 0) != 0) { + (void)GC_printf0("pthread_default_stacksize_np failed.\n"); + } +# endif /* GC_HPUX_THREADS */ pthread_attr_init(&attr); -# if defined(GC_IRIX_THREADS) || defined(GC_HPUX_THREADS) +# if defined(GC_IRIX_THREADS) pthread_attr_setstacksize(&attr, 1000000); # endif n_tests = 0; @@ -1656,5 +1661,5 @@ main() GC_printf1("Completed %d collections\n", GC_gc_no); return(0); } -#endif /* pthreads */ -#endif /* SOLARIS_THREADS || IRIX_THREADS || LINUX_THREADS || HPUX_THREADS */ +#endif /* GC_PTHREADS */ +#endif /* GC_SOLARIS_THREADS || GC_PTHREADS */ diff --git a/threadlibs.c b/threadlibs.c index 0ac54510..991647ee 100644 --- a/threadlibs.c +++ b/threadlibs.c @@ -9,20 +9,15 @@ int main() "-Wl,--wrap -Wl,pthread_detach " "-Wl,--wrap -Wl,pthread_sigmask -Wl,--wrap -Wl,sleep\n"); # endif -# if defined(LINUX_THREADS) - printf("-lpthread\n"); +# if defined(GC_LINUX_THREADS) || defined(GC_IRIX_THREADS) \ + || defined(GC_FREEBSD_THREADS) + printf("-lpthread\n"); # endif -# if defined(IRIX_THREADS) - printf("-lpthread\n"); -# endif -# if defined(HPUX_THREADS) +# if defined(GC_HPUX_THREADS) || defined(GC_OSF1_THREADS) printf("-lpthread -lrt\n"); # endif -# ifdef SOLARIS_THREADS +# if defined(GC_SOLARIS_THREADS) printf("-lthread -ldl\n"); -# endif -# ifdef GC_OSF1_THREADS - printf("-lpthread -lrt\n"); # endif return 0; } diff --git a/version.h b/version.h index 7efee18f..d4e69234 100644 --- a/version.h +++ b/version.h @@ -1,6 +1,6 @@ #define GC_VERSION_MAJOR 6 -#define GC_VERSION_MINOR 0 -#define GC_ALPHA_VERSION GC_NOT_ALPHA +#define GC_VERSION_MINOR 1 +#define GC_ALPHA_VERSION 1 # define GC_NOT_ALPHA 0xff diff --git a/win32_threads.c b/win32_threads.c index e0d19d51..533b6a4d 100755 --- a/win32_threads.c +++ b/win32_threads.c @@ -1,4 +1,4 @@ -#if defined(GC_WIN32_THREADS) || defined(WIN32_THREADS) +#if defined(GC_WIN32_THREADS) #include "private/gc_priv.h" @@ -614,4 +614,4 @@ BOOL WINAPI DllMain(HINSTANCE inst, ULONG reason, LPVOID reserved) # endif /* !MSWINCE */ -#endif /* WIN32_THREADS */ +#endif /* GC_WIN32_THREADS */ -- cgit v1.2.3