├── windows-untested ├── gc.rc ├── stdafx.c ├── gc.def ├── README ├── stdafx.h ├── vc60 │ ├── vc60crlf.cmd │ ├── all.dsp │ ├── test.dsp │ ├── test_libgc.dsp │ ├── test_gc.dsp │ ├── test_libgcmt.dsp │ ├── test_leak_libgc.dsp │ ├── test_leak_gc.dsp │ ├── test_leak_libgcmt.dsp │ └── gc.dsw ├── vc70 │ ├── all.vcproj │ └── test.vcproj ├── vc71 │ ├── all.vcproj │ └── test.vcproj └── gc.ver ├── gc_cpp.cpp ├── include ├── extra │ ├── gc.h │ └── gc_cpp.h ├── gc_alloc_ptrs.h ├── private │ ├── darwin_stop_world.h │ ├── pthread_stop_world.h │ ├── darwin_semaphore.h │ ├── msvc_dbg.h │ ├── specific.h │ └── gc_atomic_ops.h ├── include.am ├── gc_version.h ├── leak_detector.h ├── ec.h ├── gc_vector.h ├── javaxfc.h ├── gc_disclaim.h ├── gc_tiny_fl.h ├── gc_backptr.h └── gc_pthread_redirects.h ├── doc ├── README.uts ├── README.OS2 ├── README.rs6000 ├── README.symbian ├── README.hp ├── README.win64 ├── README.cmake ├── README.DGUX386 ├── doc.am ├── README.sgi ├── README.arm.cross ├── README.ews4800 ├── README.cords ├── README.autoconf └── README.solaris2 ├── .gitmodules ├── tools ├── callprocs.sh ├── if_mach.c ├── if_not_there.c └── threadlibs.c ├── extra ├── Mac_files │ ├── dataend.c │ ├── datastart.c │ └── MacOS_config.h ├── symbian │ ├── global_end.cpp │ ├── global_start.cpp │ └── init_global_static_roots.cpp ├── symbian.cpp ├── real_malloc.c ├── krait_signal_handler.c └── gc.c ├── .github └── pull_request_template.md ├── appveyor.yml ├── bdw-gc.pc.in ├── ia64_save_regs_in_stack.s ├── .gitattributes ├── tests ├── smash_test.c ├── middle.c ├── leak_test.c ├── realloc_test.c ├── trace_test.c ├── staticrootslib.c ├── CMakeLists.txt ├── staticrootstest.c ├── thread_leak_test.c ├── huge_test.c ├── test_atomic_ops.c ├── threadkey_test.c ├── initsecondarythread.c └── subthread_create.c ├── autogen.sh ├── sparc_sunos4_mach_dep.s ├── sparc_netbsd_mach_dep.s ├── cord ├── tests │ ├── de_cmds.h │ ├── de_win.rc │ └── de_win.h └── cord.am ├── PCR-Makefile ├── m4 └── gc_set_version.m4 ├── sparc_mach_dep.S ├── OS2_MAKEFILE ├── digimars.mak ├── gc_cpp.cc ├── BCC_MAKEFILE ├── heapsections.c ├── pthread_start.c ├── .gitignore ├── obj_map.c ├── fnlz_mlc.c ├── README.QUICK └── gc_dlopen.c /windows-untested/gc.rc: -------------------------------------------------------------------------------- 1 | #include "gc.ver" 2 | -------------------------------------------------------------------------------- /windows-untested/stdafx.c: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | -------------------------------------------------------------------------------- /windows-untested/gc.def: -------------------------------------------------------------------------------- 1 | EXPORTS 2 | GC_version DATA 3 | -------------------------------------------------------------------------------- /gc_cpp.cpp: -------------------------------------------------------------------------------- 1 | // Visual C++ seems to prefer a .cpp extension to .cc 2 | #include "gc_cpp.cc" 3 | -------------------------------------------------------------------------------- /include/extra/gc.h: -------------------------------------------------------------------------------- 1 | /* This file is installed for backward compatibility. */ 2 | #include 3 | -------------------------------------------------------------------------------- /doc/README.uts: -------------------------------------------------------------------------------- 1 | Alistair Crooks supplied the port. He used Lexa C version 2.1.3 with 2 | -Xa to compile. 3 | -------------------------------------------------------------------------------- /include/extra/gc_cpp.h: -------------------------------------------------------------------------------- 1 | /* This file is installed for backward compatibility. */ 2 | #include 3 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "libatomic_ops"] 2 | path = libatomic_ops 3 | url = https://github.com/Unity-Technologies/libatomic_ops.git 4 | branch = unity-release-7_4 5 | -------------------------------------------------------------------------------- /tools/callprocs.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | GC_DEBUG=1 3 | export GC_DEBUG 4 | $* 2>&1 | awk '{print "0x3e=c\""$0"\""};/^\t##PC##=/ {if ($2 != 0) {print $2"?i"}}' | adb $1 | sed "s/^ >/>/" 5 | -------------------------------------------------------------------------------- /extra/Mac_files/dataend.c: -------------------------------------------------------------------------------- 1 | /* 2 | dataend.c 3 | 4 | A hack to get the extent of global data for the Macintosh. 5 | 6 | by Patrick C. Beard. 7 | */ 8 | 9 | long __dataend; 10 | -------------------------------------------------------------------------------- /extra/Mac_files/datastart.c: -------------------------------------------------------------------------------- 1 | /* 2 | datastart.c 3 | 4 | A hack to get the extent of global data for the Macintosh. 5 | 6 | by Patrick C. Beard. 7 | */ 8 | 9 | long __datastart; 10 | -------------------------------------------------------------------------------- /extra/symbian/global_end.cpp: -------------------------------------------------------------------------------- 1 | // Symbian-specific file. 2 | 3 | // INCLUDE FILES 4 | #include "private/gcconfig.h" 5 | 6 | extern "C" { 7 | 8 | int winscw_data_end; 9 | 10 | } /* extern "C" */ 11 | -------------------------------------------------------------------------------- /extra/symbian/global_start.cpp: -------------------------------------------------------------------------------- 1 | // Symbian-specific file. 2 | 3 | // INCLUDE FILES 4 | #include "private/gcconfig.h" 5 | 6 | extern "C" { 7 | 8 | int winscw_data_start; 9 | 10 | } /* extern "C" */ 11 | -------------------------------------------------------------------------------- /windows-untested/README: -------------------------------------------------------------------------------- 1 | gc.def should probably be removed completely. 2 | 3 | I removed an apparently erroneous line for GC_CreateThread. Unfortunately 4 | gc.def is referenced in various other places I cannot easily edit. -HB 5 | -------------------------------------------------------------------------------- /.github/pull_request_template.md: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /appveyor.yml: -------------------------------------------------------------------------------- 1 | version: 7.7.0-{build} 2 | 3 | clone_depth: 50 4 | 5 | build_script: 6 | - git clone --depth=50 https://github.com/ivmai/libatomic_ops.git 7 | - cmake -Denable_gc_assertions=ON 8 | - cmake --build . --config Debug 9 | 10 | test_script: 11 | - ctest --build-config Debug -V 12 | -------------------------------------------------------------------------------- /bdw-gc.pc.in: -------------------------------------------------------------------------------- 1 | prefix=@prefix@ 2 | exec_prefix=@exec_prefix@ 3 | libdir=@libdir@ 4 | includedir=@includedir@ 5 | 6 | Name: Boehm-Demers-Weiser Conservative Garbage Collector 7 | Description: A garbage collector for C and C++ 8 | Version: @PACKAGE_VERSION@ 9 | Libs: -L${libdir} -lgc 10 | Cflags: -I${includedir} 11 | -------------------------------------------------------------------------------- /ia64_save_regs_in_stack.s: -------------------------------------------------------------------------------- 1 | .text 2 | .align 16 3 | .global GC_save_regs_in_stack 4 | .proc GC_save_regs_in_stack 5 | GC_save_regs_in_stack: 6 | .body 7 | flushrs 8 | ;; 9 | mov r8=ar.bsp 10 | br.ret.sptk.few rp 11 | .endp GC_save_regs_in_stack 12 | -------------------------------------------------------------------------------- /windows-untested/stdafx.h: -------------------------------------------------------------------------------- 1 | #define WIN32_LEAN_AND_MEAN 2 | #include 3 | 4 | #pragma warning(error: 4013) // function undefined; assuming extern returning int 5 | 6 | #ifdef _MT 7 | # define GC_THREADS 1 8 | #endif 9 | 10 | #ifdef _DEBUG 11 | # define GC_DEBUG 12 | #endif 13 | 14 | #define SAVE_CALL_CHAIN 15 | #define SAVE_CALL_COUNT 8 16 | -------------------------------------------------------------------------------- /windows-untested/vc60/vc60crlf.cmd: -------------------------------------------------------------------------------- 1 | @echo off 2 | rem This script will convert Unix-style line endings into Windows format. 3 | 4 | for %%P in (*.ds?) do call :fixline %%P 5 | goto :eof 6 | 7 | :fixline 8 | @echo on 9 | if exist "%~1.new" del "%~1.new" 10 | for /f %%S in (%1) do ( 11 | echo %%S>>"%~1.new" 12 | ) 13 | ren %1 "%~1.bak" 14 | ren "%~1.new" %1 15 | goto :eof 16 | -------------------------------------------------------------------------------- /doc/README.OS2: -------------------------------------------------------------------------------- 1 | The code assumes static linking, and a single thread. The editor de has 2 | not been ported. The cord test program has. The supplied OS2_MAKEFILE 3 | assumes the IBM C Set/2 environment, but the code shouldn't. 4 | 5 | Since we haven't figured out hoe to do perform partial links or to build static 6 | libraries, clients currently need to link against a long list of executables. 7 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Git repo attributes. 2 | 3 | # need LF enforced to make cygwin work 4 | *.sh text eol=lf 5 | *.ac text eol=lf 6 | *.am text eol=lf 7 | *.m4 text eol=lf 8 | 9 | # Ensure all text files have normalized (LF) line endings in the repository. 10 | * text=auto 11 | 12 | # These files should use CR/LF line ending: 13 | /BCC_MAKEFILE -text 14 | /digimars.mak -text 15 | 16 | # Note: "core.eol" configuration variable controls which line endings to use 17 | # for the normalized files in the working directory (the default is native). 18 | 19 | -------------------------------------------------------------------------------- /tests/smash_test.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Test that overwrite error detection works reasonably. 3 | */ 4 | #define GC_DEBUG 5 | #include "gc.h" 6 | 7 | #include 8 | 9 | #define COUNT 7000 10 | #define SIZE 40 11 | 12 | char * A[COUNT]; 13 | 14 | int main(void) 15 | { 16 | int i; 17 | char *p; 18 | 19 | GC_INIT(); 20 | 21 | for (i = 0; i < COUNT; ++i) { 22 | A[i] = p = (char*)GC_MALLOC(SIZE); 23 | 24 | if (i%3000 == 0) GC_gcollect(); 25 | if (i%5678 == 0 && p != 0) p[SIZE + i/2000] = 42; 26 | } 27 | return 0; 28 | } 29 | -------------------------------------------------------------------------------- /doc/README.rs6000: -------------------------------------------------------------------------------- 1 | We have so far failed to find a good way to determine the stack base. 2 | It is highly recommended that GC_stackbottom be set explicitly on program 3 | startup. The supplied value sometimes causes failure under AIX 4.1, though 4 | it appears to work under 3.X. HEURISTIC2 seems to work under 4.1, but 5 | involves a substantial performance penalty, and will fail if there is 6 | no limit on stack size. 7 | 8 | There is no thread support. (I assume recent versions of AIX provide 9 | pthreads? I no longer have access to a machine ...) 10 | -------------------------------------------------------------------------------- /tests/middle.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Test at the boundary between small and large objects. 3 | * Inspired by a test case from Zoltan Varga. 4 | */ 5 | #include "gc.h" 6 | #include 7 | 8 | int main (void) 9 | { 10 | int i; 11 | 12 | GC_set_all_interior_pointers(0); 13 | GC_INIT(); 14 | 15 | for (i = 0; i < 20000; ++i) { 16 | (void)GC_malloc_atomic(4096); 17 | (void)GC_malloc(4096); 18 | } 19 | for (i = 0; i < 20000; ++i) { 20 | (void)GC_malloc_atomic(2048); 21 | (void)GC_malloc(2048); 22 | } 23 | printf("Final heap size is %lu\n", (unsigned long)GC_get_heap_size()); 24 | return 0; 25 | } 26 | -------------------------------------------------------------------------------- /doc/README.symbian: -------------------------------------------------------------------------------- 1 | Instructions for Symbian: 2 | 1. base version: libgc 7.1 3 | 2. Build: use libgc.mmp 4 | 3. Limitations 5 | 3.1.No multi-threaded support 6 | 7 | 3.2. Be careful with limitation that emulator introduces: Static roots are not 8 | dynamically accessible (there are Symbian APIs for this purpose but are just 9 | stubs, returning irrelevant values). 10 | Consequently, on emulator, you can only use dlls or exe, and retrieve static 11 | roots by calling global_init_static_root per dll (or exe). 12 | On target, only libs are supported, because static roots are retrieved by 13 | linker flags, by calling global_init_static_root in main exe. 14 | -------------------------------------------------------------------------------- /extra/symbian/init_global_static_roots.cpp: -------------------------------------------------------------------------------- 1 | // Symbian-specific file. 2 | 3 | // INCLUDE FILES 4 | #include 5 | 6 | #include "private/gcconfig.h" 7 | #include "gc.h" 8 | 9 | extern "C" { 10 | 11 | void GC_init_global_static_roots() 12 | { 13 | ptr_t dataStart = NULL; 14 | ptr_t dataEnd = NULL; 15 | # if defined (__WINS__) 16 | extern int winscw_data_start, winscw_data_end; 17 | dataStart = ((ptr_t)&winscw_data_start); 18 | dataEnd = ((ptr_t)&winscw_data_end); 19 | # else 20 | extern int Image$$RW$$Limit[], Image$$RW$$Base[]; 21 | dataStart = ((ptr_t)Image$$RW$$Base); 22 | dataEnd = ((ptr_t)Image$$RW$$Limit); 23 | # endif 24 | 25 | GC_add_roots(dataStart, dataEnd); 26 | } 27 | 28 | } /* extern "C" */ 29 | -------------------------------------------------------------------------------- /autogen.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | 4 | # This script creates (or regenerates) configure (as well as aclocal.m4, 5 | # config.h.in, Makefile.in, etc.) missing in the source repository. 6 | # 7 | # If you compile from a distribution tarball, you can skip this. Otherwise, 8 | # make sure that you have Autoconf, Automake, Libtool, and pkg-config 9 | # installed on your system, and that the corresponding *.m4 files are visible 10 | # to the aclocal. The latter can be achieved by using packages shipped by 11 | # your OS, or by installing custom versions of all four packages to the same 12 | # prefix. Otherwise, you may need to invoke autoreconf with the appropriate 13 | # -I options to locate the required *.m4 files. 14 | 15 | autoreconf -i 16 | 17 | echo 18 | echo "Ready to run './configure'." 19 | -------------------------------------------------------------------------------- /tests/leak_test.c: -------------------------------------------------------------------------------- 1 | #include "leak_detector.h" 2 | 3 | int main(void) { 4 | int *p[10]; 5 | int i; 6 | GC_set_find_leak(1); /* for new collect versions not compiled */ 7 | /* with -DFIND_LEAK. */ 8 | 9 | GC_INIT(); /* Needed if thread-local allocation is enabled. */ 10 | /* FIXME: This is not ideal. */ 11 | for (i = 0; i < 10; ++i) { 12 | p[i] = (int*)malloc(sizeof(int)+i); 13 | } 14 | CHECK_LEAKS(); 15 | for (i = 1; i < 10; ++i) { 16 | free(p[i]); 17 | } 18 | for (i = 0; i < 9; ++i) { 19 | p[i] = (int*)malloc(sizeof(int)+i); 20 | } 21 | CHECK_LEAKS(); 22 | CHECK_LEAKS(); 23 | CHECK_LEAKS(); 24 | return 0; 25 | } 26 | -------------------------------------------------------------------------------- /tests/realloc_test.c: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | #include "gc.h" 5 | 6 | #define COUNT 10000000 7 | 8 | int main(void) { 9 | int i; 10 | unsigned long last_heap_size = 0; 11 | 12 | GC_INIT(); 13 | 14 | for (i = 0; i < COUNT; i++) { 15 | int **p = GC_NEW(int *); 16 | int *q = (int*)GC_MALLOC_ATOMIC(sizeof(int)); 17 | 18 | if (p == 0 || *p != 0) { 19 | fprintf(stderr, "GC_malloc returned garbage (or NULL)\n"); 20 | exit(1); 21 | } 22 | 23 | *p = (int*)GC_REALLOC(q, 2 * sizeof(int)); 24 | 25 | if (i % 10 == 0) { 26 | unsigned long heap_size = (unsigned long)GC_get_heap_size(); 27 | if (heap_size != last_heap_size) { 28 | printf("Heap size: %lu\n", heap_size); 29 | last_heap_size = heap_size; 30 | } 31 | } 32 | } 33 | return 0; 34 | } 35 | -------------------------------------------------------------------------------- /doc/README.hp: -------------------------------------------------------------------------------- 1 | Dynamic loading support requires that executables be linked with -ldld. 2 | The alternative is to build the collector without defining DYNAMIC_LOADING 3 | in gcconfig.h and ensuring that all garbage collectible objects are 4 | accessible without considering statically allocated variables in dynamic 5 | libraries. 6 | 7 | The collector should compile with either plain cc or cc -Ae. Cc -Aa 8 | fails to define _HPUX_SOURCE and thus will not configure the collector 9 | correctly. 10 | 11 | Incremental collection support was added recently, and should now work. 12 | 13 | In spite of past claims, pthread support under HP/UX 11 should now work. 14 | Define GC_THREADS macro for the build. Incremental collection still does not 15 | work in combination with it. 16 | 17 | The stack finding code can be confused by putenv calls before collector 18 | initialization. Call GC_malloc or GC_init before any putenv calls. 19 | -------------------------------------------------------------------------------- /extra/Mac_files/MacOS_config.h: -------------------------------------------------------------------------------- 1 | /* 2 | MacOS_config.h 3 | 4 | Configuration flags for Macintosh development systems. 5 | 6 | 7 | 8 | 11/16/95 pcb Updated compilation flags to reflect latest 4.6 Makefile. 9 | 10 | by Patrick C. Beard. 11 | */ 12 | /* Boehm, November 17, 1995 12:10 pm PST */ 13 | 14 | #ifdef __MWERKS__ 15 | /* for CodeWarrior Pro with Metrowerks Standard Library (MSL). */ 16 | /* #define MSL_USE_PRECOMPILED_HEADERS 0 */ 17 | #include 18 | #endif /* __MWERKS__ */ 19 | 20 | /* these are defined again in gc_priv.h. */ 21 | #undef TRUE 22 | #undef FALSE 23 | 24 | #define ALL_INTERIOR_POINTERS /* follows interior pointers. */ 25 | /* #define DONT_ADD_BYTE_AT_END */ /* no padding. */ 26 | /* #define SMALL_CONFIG */ /* whether to use a smaller heap. */ 27 | #define USE_TEMPORARY_MEMORY /* use Macintosh temporary memory. */ 28 | -------------------------------------------------------------------------------- /sparc_sunos4_mach_dep.s: -------------------------------------------------------------------------------- 1 | ! SPARCompiler 3.0 and later apparently no longer handles 2 | ! asm outside functions. So we need a separate .s file 3 | ! This is only set up for SunOS 4. 4 | ! Assumes this is called before the stack contents are 5 | ! examined. 6 | 7 | .seg "text" 8 | .globl _GC_save_regs_in_stack 9 | .globl _GC_push_regs 10 | _GC_save_regs_in_stack: 11 | _GC_push_regs: 12 | ta 0x3 ! ST_FLUSH_WINDOWS 13 | mov %sp,%o0 14 | retl 15 | nop 16 | 17 | .globl _GC_clear_stack_inner 18 | _GC_clear_stack_inner: 19 | mov %sp,%o2 ! Save sp 20 | add %sp,-8,%o3 ! p = sp-8 21 | clr %g1 ! [g0,g1] = 0 22 | add %o1,-0x60,%sp ! Move sp out of the way, 23 | ! so that traps still work. 24 | ! Includes some extra words 25 | ! so we can be sloppy below. 26 | loop: 27 | std %g0,[%o3] ! *(long long *)p = 0 28 | cmp %o3,%o1 29 | bgu loop ! if (p > limit) goto loop 30 | add %o3,-8,%o3 ! p -= 8 (delay slot) 31 | retl 32 | mov %o2,%sp ! Restore sp., delay slot 33 | -------------------------------------------------------------------------------- /tests/trace_test.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #ifndef GC_DEBUG 5 | # define GC_DEBUG 6 | #endif 7 | 8 | #include "gc.h" 9 | #include "gc_backptr.h" 10 | 11 | struct treenode { 12 | struct treenode *x; 13 | struct treenode *y; 14 | } * root[10]; 15 | 16 | struct treenode * mktree(int i) { 17 | struct treenode * r = GC_NEW(struct treenode); 18 | if (0 == i) 19 | return 0; 20 | if (1 == i) 21 | r = (struct treenode *)GC_MALLOC_ATOMIC(sizeof(struct treenode)); 22 | if (r == NULL) { 23 | fprintf(stderr, "Out of memory\n"); 24 | exit(1); 25 | } 26 | r -> x = mktree(i-1); 27 | r -> y = mktree(i-1); 28 | return r; 29 | } 30 | 31 | int main(void) 32 | { 33 | int i; 34 | GC_INIT(); 35 | for (i = 0; i < 10; ++i) { 36 | root[i] = mktree(12); 37 | } 38 | GC_generate_random_backtrace(); 39 | GC_generate_random_backtrace(); 40 | GC_generate_random_backtrace(); 41 | GC_generate_random_backtrace(); 42 | return 0; 43 | } 44 | -------------------------------------------------------------------------------- /sparc_netbsd_mach_dep.s: -------------------------------------------------------------------------------- 1 | ! SPARCompiler 3.0 and later apparently no longer handles 2 | ! asm outside functions. So we need a separate .s file 3 | ! This is only set up for SunOS 4. 4 | ! Assumes this is called before the stack contents are 5 | ! examined. 6 | 7 | #include "machine/asm.h" 8 | 9 | .seg "text" 10 | .globl _C_LABEL(GC_save_regs_in_stack) 11 | .globl _C_LABEL(GC_push_regs) 12 | _C_LABEL(GC_save_regs_in_stack): 13 | _C_LABEL(GC_push_regs): 14 | ta 0x3 ! ST_FLUSH_WINDOWS 15 | mov %sp,%o0 16 | retl 17 | nop 18 | 19 | .globl _C_LABEL(GC_clear_stack_inner) 20 | _C_LABEL(GC_clear_stack_inner): 21 | mov %sp,%o2 ! Save sp 22 | add %sp,-8,%o3 ! p = sp-8 23 | clr %g1 ! [g0,g1] = 0 24 | add %o1,-0x60,%sp ! Move sp out of the way, 25 | ! so that traps still work. 26 | ! Includes some extra words 27 | ! so we can be sloppy below. 28 | loop: 29 | std %g0,[%o3] ! *(long long *)p = 0 30 | cmp %o3,%o1 31 | bgu loop ! if (p > limit) goto loop 32 | add %o3,-8,%o3 ! p -= 8 (delay slot) 33 | retl 34 | mov %o2,%sp ! Restore sp., delay slot 35 | -------------------------------------------------------------------------------- /cord/tests/de_cmds.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1994 by Xerox Corporation. All rights reserved. 3 | * 4 | * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED 5 | * OR IMPLIED. ANY USE IS AT YOUR OWN RISK. 6 | * 7 | * Permission is hereby granted to use or copy this program 8 | * for any purpose, provided the above notices are retained on all copies. 9 | * Permission to modify the code and to distribute modified code is granted, 10 | * provided the above notices are retained, and a notice that the code was 11 | * modified is included with the above copyright notice. 12 | */ 13 | 14 | #ifndef DE_CMDS_H 15 | 16 | # define DE_CMDS_H 17 | 18 | # define UP 16 /* ^P */ 19 | # define DOWN 14 /* ^N */ 20 | # define LEFT 2 /* ^B */ 21 | # define RIGHT 6 /* ^F */ 22 | # define DEL 127 /* ^? */ 23 | # define BS 8 /* ^H */ 24 | # define UNDO 21 /* ^U */ 25 | # define WRITE 23 /* ^W */ 26 | # define QUIT 4 /* ^D */ 27 | # define REPEAT 18 /* ^R */ 28 | # define LOCATE 12 /* ^L */ 29 | # define TOP 20 /* ^T */ 30 | 31 | #endif 32 | -------------------------------------------------------------------------------- /tools/if_mach.c: -------------------------------------------------------------------------------- 1 | /* Conditionally execute a command based on machine and OS from gcconfig.h */ 2 | 3 | # include "private/gc_priv.h" 4 | # include 5 | # include 6 | # include 7 | 8 | #ifdef __cplusplus 9 | # define EXECV_ARGV_T char** 10 | #else 11 | /* The 2nd argument of execvp() prototype may be either char**, or */ 12 | /* char* const*, or const char* const*. */ 13 | # define EXECV_ARGV_T void* 14 | #endif 15 | 16 | int main(int argc, char **argv) 17 | { 18 | if (argc < 4) goto Usage; 19 | if (strcmp(MACH_TYPE, argv[1]) != 0) return(0); 20 | if (strlen(OS_TYPE) > 0 && strlen(argv[2]) > 0 21 | && strcmp(OS_TYPE, argv[2]) != 0) return(0); 22 | fprintf(stderr, "^^^^Starting command^^^^\n"); 23 | fflush(stdout); 24 | execvp(TRUSTED_STRING(argv[3]), (EXECV_ARGV_T)(argv + 3)); 25 | perror("Couldn't execute"); 26 | 27 | Usage: 28 | fprintf(stderr, "Usage: %s mach_type os_type command\n", argv[0]); 29 | fprintf(stderr, "Currently mach_type = %s, os_type = %s\n", 30 | MACH_TYPE, OS_TYPE); 31 | return(1); 32 | } 33 | -------------------------------------------------------------------------------- /cord/cord.am: -------------------------------------------------------------------------------- 1 | ## This file is processed with automake. 2 | 3 | # Info (current:revision:age) for the Libtool versioning system. 4 | # These numbers should be updated at most once just before the release, 5 | # and, optionally, at most once during the development (after the release). 6 | LIBCORD_VER_INFO = 4:0:3 7 | 8 | noinst_LTLIBRARIES += libcord.la 9 | 10 | libcord_la_LIBADD = $(top_builddir)/libgc.la 11 | libcord_la_LDFLAGS = -version-info $(LIBCORD_VER_INFO) -no-undefined 12 | libcord_la_CPPFLAGS = $(AM_CPPFLAGS) 13 | 14 | libcord_la_SOURCES = \ 15 | cord/cordbscs.c \ 16 | cord/cordprnt.c \ 17 | cord/cordxtra.c 18 | 19 | TESTS += cordtest$(EXEEXT) 20 | check_PROGRAMS += cordtest 21 | cordtest_SOURCES = cord/tests/cordtest.c 22 | cordtest_LDADD = $(top_builddir)/libgc.la $(top_builddir)/libcord.la 23 | 24 | EXTRA_DIST += \ 25 | cord/tests/de.c \ 26 | cord/tests/de_cmds.h \ 27 | cord/tests/de_win.c \ 28 | cord/tests/de_win.h \ 29 | cord/tests/de_win.rc 30 | 31 | pkginclude_HEADERS += \ 32 | include/cord.h \ 33 | include/cord_pos.h \ 34 | include/ec.h 35 | -------------------------------------------------------------------------------- /extra/symbian.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | extern "C" { 10 | 11 | int GC_get_main_symbian_stack_base() 12 | { 13 | TThreadStackInfo aInfo; 14 | TInt err = RThread().StackInfo(aInfo); 15 | if ( !err ) 16 | { 17 | return aInfo.iBase; 18 | } 19 | else 20 | { 21 | return 0; 22 | } 23 | } 24 | 25 | char* GC_get_private_path_and_zero_file() 26 | { 27 | // always on c: drive 28 | RFs fs; 29 | fs.Connect(); 30 | fs.CreatePrivatePath( EDriveC ); 31 | TFileName path; 32 | fs.PrivatePath( path ); 33 | fs.Close(); 34 | _LIT( KCDrive, "c:" ); 35 | path.Insert( 0, KCDrive ); 36 | 37 | 38 | //convert to char*, assume ascii 39 | TBuf8 path8; 40 | path8.Copy( path ); 41 | _LIT8( KZero8, "zero" ); 42 | path8.Append( KZero8 ); 43 | 44 | size_t size = path8.Length() + 1; 45 | char* copyChar = (char*) malloc( size ); 46 | if (copyChar) 47 | memcpy( copyChar, path8.PtrZ(), size ); 48 | 49 | return copyChar; // ownership passed 50 | } 51 | 52 | } /* extern "C" */ 53 | -------------------------------------------------------------------------------- /extra/real_malloc.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 1988, 1989 Hans-J. Boehm, Alan J. Demers 3 | * Copyright (c) 1991-1994 by Xerox Corporation. All rights reserved. 4 | * 5 | * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED 6 | * OR IMPLIED. ANY USE IS AT YOUR OWN RISK. 7 | * 8 | * Permission is hereby granted to use or copy this program 9 | * for any purpose, provided the above notices are retained on all copies. 10 | * Permission to modify the code and to distribute modified code is granted, 11 | * provided the above notices are retained, and a notice that the code was 12 | * modified is included with the above copyright notice. 13 | */ 14 | 15 | # ifdef HAVE_CONFIG_H 16 | # include "config.h" 17 | # endif 18 | 19 | # ifdef PCR 20 | /* 21 | * This definition should go in its own file that includes no other 22 | * header files. Otherwise, we risk not getting the underlying system 23 | * malloc. 24 | */ 25 | # define PCR_NO_RENAME 26 | # include 27 | 28 | void * real_malloc(size_t size) 29 | { 30 | return(malloc(size)); 31 | } 32 | 33 | # else 34 | 35 | extern int GC_quiet; 36 | /* ANSI C doesn't allow translation units to be empty. */ 37 | /* So we guarantee this one is nonempty. */ 38 | 39 | #endif /* PCR */ 40 | -------------------------------------------------------------------------------- /include/gc_alloc_ptrs.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1996-1998 by Silicon Graphics. All rights reserved. 3 | * 4 | * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED 5 | * OR IMPLIED. ANY USE IS AT YOUR OWN RISK. 6 | * 7 | * Permission is hereby granted to use or copy this program 8 | * for any purpose, provided the above notices are retained on all copies. 9 | * Permission to modify the code and to distribute modified code is granted, 10 | * provided the above notices are retained, and a notice that the code was 11 | * modified is included with the above copyright notice. 12 | */ 13 | 14 | /* This file should never be included by clients directly. */ 15 | 16 | #ifndef GC_ALLOC_PTRS_H 17 | #define GC_ALLOC_PTRS_H 18 | 19 | #include "gc.h" 20 | 21 | #ifdef __cplusplus 22 | extern "C" { 23 | #endif 24 | 25 | GC_API void ** const GC_objfreelist_ptr; 26 | GC_API void ** const GC_aobjfreelist_ptr; 27 | GC_API void ** const GC_uobjfreelist_ptr; 28 | 29 | #ifdef GC_ATOMIC_UNCOLLECTABLE 30 | GC_API void ** const GC_auobjfreelist_ptr; 31 | #endif 32 | 33 | GC_API void GC_CALL GC_incr_bytes_allocd(size_t bytes); 34 | GC_API void GC_CALL GC_incr_bytes_freed(size_t bytes); 35 | 36 | #ifdef __cplusplus 37 | } /* extern "C" */ 38 | #endif 39 | 40 | #endif /* GC_ALLOC_PTRS_H */ 41 | -------------------------------------------------------------------------------- /doc/README.win64: -------------------------------------------------------------------------------- 1 | 64-bit Windows on AMD64/Intel EM64T is somewhat supported in the 7.0 2 | and later release. A collector can be built with Microsoft Visual C++ 2005 3 | or with mingw-w64 gcc. 4 | More testing would clearly be helpful. 5 | 6 | NT_MAKEFILE has been used in this environment. Uncomment the corresponding 7 | definitions of CPU and CVTRES_CPU variables (commenting out the ones for X86), 8 | and then type "nmake -f NT_MAKEFILE" in a Visual C++ command line window to 9 | build the dynamic library with threads support and the usual test programs. 10 | To verify that the collector is at least somewhat functional, run gctest.exe. 11 | This should create gctest.gc.log after a few seconds. 12 | 13 | Test_cpp.exe might not run correctly in case of dynamic GC linking. (It seems 14 | that we're getting wrong instances of operator new/delete in some cases.) 15 | 16 | This process is completely analogous to NT_MAKEFILE usage 17 | for the 32-bit library version. 18 | 19 | A similar procedure using NT_MAKEFILE should be usable to 20 | build the static library (see comments for CFLAGS_SPECIFIC and LINK_GC 21 | variables in NT_MAKEFILE). 22 | 23 | Note that some warnings have been explicitly turned off in the makefile. 24 | 25 | VC++ note: to suppress warnings -D_CRT_SECURE_NO_DEPRECATE is used. 26 | 27 | gcc note: -fno-strict-aliasing should be used if optimizing. 28 | -------------------------------------------------------------------------------- /doc/README.cmake: -------------------------------------------------------------------------------- 1 | 2 | CMAKE 3 | ----- 4 | 5 | Win32 binaries (both 32- and 64-bit) can be built using CMake. CMake is an 6 | open-source tool like automake - it generates makefiles. 7 | 8 | Some preliminary work has been done to make this work on other platforms, but 9 | the support is not yet complete. 10 | 11 | CMake will generate: 12 | 13 | Borland Makefiles 14 | MSYS Makefiles 15 | MinGW Makefiles 16 | NMake Makefiles 17 | Unix Makefiles 18 | . Visual Studio project files 19 | Visual Studio 6 20 | Visual Studio 7 21 | Visual Studio 7 .NET 2003 22 | Visual Studio 8 2005 23 | Visual Studio 8 2005 Win64 24 | Visual Studio 9 2008 25 | Visual Studio 9 2008 Win64 26 | Watcom WMake 27 | 28 | 29 | BUILD PROCESS 30 | ------------- 31 | 32 | . install cmake (cmake.org) 33 | . add directory containing cmake.exe to %PATH% 34 | . run cmake from the gc root directory, passing the target with -G: 35 | e.g., 36 | > cmake -G "Visual Studio 8 2005" 37 | use the gc.sln file generated by cmake to build gc 38 | . you can also run cmake from a build directory to build outside of 39 | the source tree. Just specify the path to the source tree: 40 | e.g., 41 | > mkdir build 42 | > cd build 43 | > cmake .. -G "Visual Studio 8 2005" 44 | 45 | 46 | INPUT 47 | ----- 48 | 49 | The main input to cmake are the CMakeLists.txt files in each directory. For 50 | help, goto cmake.org. 51 | -------------------------------------------------------------------------------- /PCR-Makefile: -------------------------------------------------------------------------------- 1 | # 2 | # Default target 3 | # 4 | 5 | default: gc.o 6 | 7 | include ../config/common.mk 8 | 9 | # 10 | # compilation flags, etc. 11 | # 12 | 13 | CPPFLAGS = $(INCLUDE) $(CONFIG_CPPFLAGS) \ 14 | -DPCR_NO_RENAME -DPCR_NO_HOSTDEP_ERR 15 | #CFLAGS = -DPCR $(CONFIG_CFLAGS) 16 | CFLAGS = -DPCR -DENABLE_DISCLAIM $(CONFIG_CFLAGS) 17 | SPECIALCFLAGS = # For code involving asm's 18 | 19 | ASPPFLAGS = $(INCLUDE) $(CONFIG_ASPPFLAGS) \ 20 | -DPCR_NO_RENAME -DPCR_NO_HOSTDEP_ERR -DASM 21 | 22 | ASFLAGS = $(CONFIG_ASFLAGS) 23 | 24 | LDRFLAGS = $(CONFIG_LDRFLAGS) 25 | 26 | LDFLAGS = $(CONFIG_LDFLAGS) 27 | 28 | # 29 | # BEGIN PACKAGE-SPECIFIC PART 30 | # 31 | 32 | # Fix to point to local pcr installation directory. 33 | PCRDIR= .. 34 | 35 | COBJ= alloc.o reclaim.o allchblk.o misc.o os_dep.o mark_rts.o headers.o mark.o obj_map.o blacklst.o finalize.o new_hblk.o extra/pcr_interface.o extra/real_malloc.o dyn_load.o dbg_mlc.o fnlz_mlc.o malloc.o checksums.o typd_mlc.o ptr_chck.o mallocx.o 36 | 37 | CSRC= reclaim.c allchblk.c misc.c alloc.c mach_dep.c os_dep.c mark_rts.c headers.c mark.c obj_map.c blacklst.c finalize.c new_hblk.c extra/pcr_interface.c extra/real_malloc.c dyn_load.c dbg_mlc.c fnlz_mlc.c malloc.c checksums.c typd_mlc.c ptr_chck.c mallocx.c 38 | 39 | SHELL= /bin/sh 40 | 41 | default: gc.o 42 | 43 | gc.o: $(COBJ) mach_dep.o 44 | $(LDR) $(CONFIG_LDRFLAGS) -o gc.o $(COBJ) mach_dep.o 45 | 46 | mach_dep.o: mach_dep.c 47 | $(CC) -c $(SPECIALCFLAGS) mach_dep.c 48 | -------------------------------------------------------------------------------- /doc/README.DGUX386: -------------------------------------------------------------------------------- 1 | Garbage Collector (parallel version) for x86 DG/UX Release R4.20MU07 2 | 3 | 4 | *READ* the file README.QUICK. 5 | 6 | You need the GCC-3.0.3 rev (DG/UX) compiler to build this tree. 7 | This compiler has the new "dgux386" threads package implemented. 8 | It also supports the switch "-pthread" needed to link correctly 9 | the DG/UX's -lrte -lthread with -lgcc and the system's -lc. 10 | Finally, we support parallel mark for the SMP DG/UX machines. 11 | To build the garbage collector do: 12 | 13 | ./configure 14 | make 15 | make gctest 16 | 17 | Before you run "gctest" you need to set your LD_LIBRARY_PATH 18 | correctly so that "gctest" can find the shared library libgc. 19 | Alternatively you can do a configuration 20 | 21 | ./configure --disable-shared 22 | 23 | to build only the static version of libgc. 24 | 25 | To enable debugging messages please do: 26 | 1) Add the "--enable-gc-debug" flag during configuration. 27 | 2) Pass "CFLAGS=-DDEBUG_THREADS" to "make". 28 | 29 | In a machine with 4 CPUs (my own machine), parallel mark makes 30 | a BIG difference. 31 | 32 | Takis Psarogiannakopoulos 33 | 34 | Note (HB): 35 | The integration of this patch is currently not complete. 36 | The following patches against 6.1alpha3 where hard to move 37 | to alpha4, and are not integrated. There may also be minor 38 | problems with stylistic corrections made by me. 39 | [The diff for ltconfig and ltmain.sh was removed from this file on 2011-08-22] 40 | -------------------------------------------------------------------------------- /tools/if_not_there.c: -------------------------------------------------------------------------------- 1 | /* Conditionally execute the command argv[2] based if the file argv[1] */ 2 | /* does not exist. If the command is omitted (and the file does not */ 3 | /* exist) then just exit with a non-zero code. */ 4 | 5 | # include "private/gc_priv.h" 6 | # include 7 | # include 8 | # include 9 | #ifdef __DJGPP__ 10 | #include 11 | #endif /* __DJGPP__ */ 12 | 13 | #ifdef __cplusplus 14 | # define EXECV_ARGV_T char** 15 | #else 16 | # define EXECV_ARGV_T void* /* see the comment in if_mach.c */ 17 | #endif 18 | 19 | int main(int argc, char **argv) 20 | { 21 | FILE * f; 22 | #ifdef __DJGPP__ 23 | DIR * d; 24 | #endif /* __DJGPP__ */ 25 | char *fname; 26 | 27 | if (argc < 2 || argc > 3) 28 | goto Usage; 29 | 30 | fname = TRUSTED_STRING(argv[1]); 31 | f = fopen(fname, "rb"); 32 | if (f != NULL) { 33 | fclose(f); 34 | return(0); 35 | } 36 | f = fopen(fname, "r"); 37 | if (f != NULL) { 38 | fclose(f); 39 | return(0); 40 | } 41 | #ifdef __DJGPP__ 42 | if ((d = opendir(fname)) != 0) { 43 | closedir(d); 44 | return(0); 45 | } 46 | #endif 47 | printf("^^^^Starting command^^^^\n"); 48 | fflush(stdout); 49 | if (argc == 2) 50 | return(2); /* the file does not exist but no command is given */ 51 | 52 | execvp(TRUSTED_STRING(argv[2]), (EXECV_ARGV_T)(argv + 2)); 53 | exit(1); 54 | 55 | Usage: 56 | fprintf(stderr, "Usage: %s file_name [command]\n", argv[0]); 57 | return(1); 58 | } 59 | -------------------------------------------------------------------------------- /windows-untested/vc70/all.vcproj: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 12 | 13 | 14 | 20 | 22 | 24 | 26 | 28 | 29 | 35 | 37 | 39 | 41 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /windows-untested/vc70/test.vcproj: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 12 | 13 | 14 | 20 | 22 | 24 | 26 | 28 | 29 | 35 | 37 | 39 | 41 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /tests/staticrootslib.c: -------------------------------------------------------------------------------- 1 | 2 | /* This test file is intended to be compiled into a DLL. */ 3 | 4 | #ifndef GC_DEBUG 5 | # define GC_DEBUG 6 | #endif 7 | 8 | #include "gc.h" 9 | 10 | #ifndef GC_TEST_EXPORT_API 11 | # if defined(GC_VISIBILITY_HIDDEN_SET) \ 12 | && !defined(__CEGCC__) && !defined(__CYGWIN__) && !defined(__MINGW32__) 13 | # define GC_TEST_EXPORT_API \ 14 | extern __attribute__((__visibility__("default"))) 15 | # else 16 | # define GC_TEST_EXPORT_API extern 17 | # endif 18 | #endif 19 | 20 | struct treenode { 21 | struct treenode *x; 22 | struct treenode *y; 23 | }; 24 | 25 | static struct treenode *root[10] = { 0 }; 26 | static struct treenode *root_nz[10] = { (struct treenode *)(GC_word)2 }; 27 | 28 | #ifdef STATICROOTSLIB2 29 | # define libsrl_getpelem libsrl_getpelem2 30 | #else 31 | 32 | GC_TEST_EXPORT_API struct treenode * libsrl_mktree(int i) 33 | { 34 | struct treenode * r = GC_NEW(struct treenode); 35 | if (0 == i) 36 | return 0; 37 | if (1 == i) 38 | r = (struct treenode *)GC_MALLOC_ATOMIC(sizeof(struct treenode)); 39 | if (r) { 40 | r -> x = libsrl_mktree(i-1); 41 | r -> y = libsrl_mktree(i-1); 42 | } 43 | return r; 44 | } 45 | 46 | GC_TEST_EXPORT_API void * libsrl_init(void) 47 | { 48 | # ifndef STATICROOTSLIB_INIT_IN_MAIN 49 | GC_INIT(); 50 | # endif 51 | return GC_MALLOC(sizeof(struct treenode)); 52 | } 53 | 54 | #endif /* !STATICROOTSLIB2 */ 55 | 56 | GC_TEST_EXPORT_API struct treenode ** libsrl_getpelem(int i, int j) 57 | { 58 | return &((j & 1) != 0 ? root_nz : root)[i]; 59 | } 60 | -------------------------------------------------------------------------------- /doc/doc.am: -------------------------------------------------------------------------------- 1 | # 2 | # THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED 3 | # OR IMPLIED. ANY USE IS AT YOUR OWN RISK. 4 | # 5 | # Permission is hereby granted to use or copy this program 6 | # for any purpose, provided the above notices are retained on all copies. 7 | # Permission to modify the code and to distribute modified code is granted, 8 | # provided the above notices are retained, and a notice that the code was 9 | # modified is included with the above copyright notice. 10 | 11 | ## Process this file with automake to produce Makefile.in. 12 | 13 | # installed documentation 14 | if ENABLE_DOCS 15 | dist_doc_DATA = \ 16 | AUTHORS \ 17 | README.md \ 18 | doc/README.DGUX386 \ 19 | doc/README.Mac \ 20 | doc/README.OS2 \ 21 | doc/README.amiga \ 22 | doc/README.arm.cross \ 23 | doc/README.autoconf \ 24 | doc/README.cmake \ 25 | doc/README.cords \ 26 | doc/README.darwin \ 27 | doc/README.environment \ 28 | doc/README.ews4800 \ 29 | doc/README.hp \ 30 | doc/README.linux \ 31 | doc/README.macros \ 32 | doc/README.rs6000 \ 33 | doc/README.sgi \ 34 | doc/README.solaris2 \ 35 | doc/README.symbian \ 36 | doc/README.uts \ 37 | doc/README.win32 \ 38 | doc/README.win64 \ 39 | doc/debugging.md \ 40 | doc/finalization.md \ 41 | doc/gcdescr.md \ 42 | doc/gcinterface.md \ 43 | doc/leak.md \ 44 | doc/overview.md \ 45 | doc/porting.md \ 46 | doc/scale.md \ 47 | doc/simple_example.md \ 48 | doc/tree.md 49 | 50 | dist_man3_MANS = doc/gc.man 51 | endif 52 | -------------------------------------------------------------------------------- /include/private/darwin_stop_world.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1994 by Xerox Corporation. All rights reserved. 3 | * Copyright (c) 1996 by Silicon Graphics. All rights reserved. 4 | * Copyright (c) 1998 by Fergus Henderson. All rights reserved. 5 | * Copyright (c) 2000-2009 by Hewlett-Packard Development Company. 6 | * All rights reserved. 7 | * 8 | * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED 9 | * OR IMPLIED. ANY USE IS AT YOUR OWN RISK. 10 | * 11 | * Permission is hereby granted to use or copy this program 12 | * for any purpose, provided the above notices are retained on all copies. 13 | * Permission to modify the code and to distribute modified code is granted, 14 | * provided the above notices are retained, and a notice that the code was 15 | * modified is included with the above copyright notice. 16 | */ 17 | 18 | #ifndef GC_DARWIN_STOP_WORLD_H 19 | #define GC_DARWIN_STOP_WORLD_H 20 | 21 | #if !defined(GC_DARWIN_THREADS) 22 | # error darwin_stop_world.h included without GC_DARWIN_THREADS defined 23 | #endif 24 | 25 | #include 26 | #include 27 | 28 | EXTERN_C_BEGIN 29 | 30 | struct thread_stop_info { 31 | mach_port_t mach_thread; 32 | ptr_t stack_ptr; /* Valid only when thread is in a "blocked" state. */ 33 | }; 34 | 35 | #ifndef DARWIN_DONT_PARSE_STACK 36 | GC_INNER ptr_t GC_FindTopOfStack(unsigned long); 37 | #endif 38 | 39 | #ifdef MPROTECT_VDB 40 | GC_INNER void GC_mprotect_stop(void); 41 | GC_INNER void GC_mprotect_resume(void); 42 | # ifndef GC_NO_THREADS_DISCOVERY 43 | GC_INNER void GC_darwin_register_mach_handler_thread(mach_port_t thread); 44 | # endif 45 | #endif 46 | 47 | #if defined(PARALLEL_MARK) && !defined(GC_NO_THREADS_DISCOVERY) 48 | GC_INNER GC_bool GC_is_mach_marker(thread_act_t); 49 | #endif 50 | 51 | EXTERN_C_END 52 | 53 | #endif 54 | -------------------------------------------------------------------------------- /tests/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (c) 1994 by Xerox Corporation. All rights reserved. 3 | # Copyright (c) 1996 by Silicon Graphics. All rights reserved. 4 | # Copyright (c) 1998 by Fergus Henderson. All rights reserved. 5 | # Copyright (c) 2000-2010 by Hewlett-Packard Company. All rights reserved. 6 | ## 7 | # THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED 8 | # OR IMPLIED. ANY USE IS AT YOUR OWN RISK. 9 | ## 10 | # Permission is hereby granted to use or copy this program 11 | # for any purpose, provided the above notices are retained on all copies. 12 | # Permission to modify the code and to distribute modified code is granted, 13 | # provided the above notices are retained, and a notice that the code was 14 | # modified is included with the above copyright notice. 15 | ## 16 | 17 | ADD_DEFINITIONS(-DGC_NOT_DLL) 18 | 19 | # Compile some tests as C++ to test extern "C" in header files. 20 | SET_SOURCE_FILES_PROPERTIES( 21 | leak_test.c 22 | test.c 23 | PROPERTIES LANGUAGE CXX) 24 | 25 | ADD_EXECUTABLE(gctest WIN32 test.c) 26 | TARGET_LINK_LIBRARIES(gctest gc-lib) 27 | ADD_TEST(NAME gctest COMMAND gctest) 28 | 29 | ADD_EXECUTABLE(hugetest huge_test.c) 30 | TARGET_LINK_LIBRARIES(hugetest gc-lib) 31 | ADD_TEST(NAME hugetest COMMAND hugetest) 32 | 33 | ADD_EXECUTABLE(leaktest leak_test.c) 34 | TARGET_LINK_LIBRARIES(leaktest gc-lib) 35 | ADD_TEST(NAME leaktest COMMAND leaktest) 36 | 37 | ADD_EXECUTABLE(middletest middle.c) 38 | TARGET_LINK_LIBRARIES(middletest gc-lib) 39 | ADD_TEST(NAME middletest COMMAND middletest) 40 | 41 | ADD_EXECUTABLE(realloc_test realloc_test.c) 42 | TARGET_LINK_LIBRARIES(realloc_test gc-lib) 43 | ADD_TEST(NAME realloc_test COMMAND realloc_test) 44 | 45 | ADD_EXECUTABLE(smashtest smash_test.c) 46 | TARGET_LINK_LIBRARIES(smashtest gc-lib) 47 | ADD_TEST(NAME smashtest COMMAND smashtest) 48 | -------------------------------------------------------------------------------- /m4/gc_set_version.m4: -------------------------------------------------------------------------------- 1 | # 2 | # THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED 3 | # OR IMPLIED. ANY USE IS AT YOUR OWN RISK. 4 | # 5 | # Permission is hereby granted to use or copy this program 6 | # for any purpose, provided the above notices are retained on all copies. 7 | # Permission to modify the code and to distribute modified code is granted, 8 | # provided the above notices are retained, and a notice that the code was 9 | # modified is included with the above copyright notice. 10 | 11 | # GC_SET_VERSION 12 | # sets and AC_DEFINEs GC_VERSION_MAJOR, GC_VERSION_MINOR and GC_VERSION_MICRO 13 | # based on the contents of PACKAGE_VERSION; PACKAGE_VERSION must conform to 14 | # [0-9]+[.][0-9]+[.][0-9]+ 15 | # 16 | AC_DEFUN([GC_SET_VERSION], [ 17 | AC_MSG_CHECKING(GC version numbers) 18 | GC_VERSION_MAJOR=`echo $PACKAGE_VERSION | sed 's/^\([[0-9]][[0-9]]*\)[[.]].*$/\1/g'` 19 | GC_VERSION_MINOR=`echo $PACKAGE_VERSION | sed 's/^[[^.]]*[[.]]\([[0-9]][[0-9]]*\).*$/\1/g'` 20 | GC_VERSION_MICRO=`echo $PACKAGE_VERSION | sed 's/^[[^.]]*[[.]][[^.]]*[[.]]\([[0-9]][[0-9]]*\)$/\1/g'` 21 | 22 | if test :$GC_VERSION_MAJOR: = :: \ 23 | -o :$GC_VERSION_MINOR: = :: \ 24 | -o :$GC_VERSION_MICRO: = :: ; 25 | then 26 | AC_MSG_RESULT(invalid) 27 | AC_MSG_ERROR([nonconforming PACKAGE_VERSION='$PACKAGE_VERSION']) 28 | fi 29 | 30 | AC_DEFINE_UNQUOTED([GC_VERSION_MAJOR], $GC_VERSION_MAJOR, 31 | [The major version number of this GC release.]) 32 | AC_DEFINE_UNQUOTED([GC_VERSION_MINOR], $GC_VERSION_MINOR, 33 | [The minor version number of this GC release.]) 34 | AC_DEFINE_UNQUOTED([GC_VERSION_MICRO], $GC_VERSION_MICRO, 35 | [The micro version number of this GC release.]) 36 | AC_MSG_RESULT(major=$GC_VERSION_MAJOR minor=$GC_VERSION_MINOR \ 37 | micro=$GC_VERSION_MICRO) 38 | ]) 39 | 40 | sinclude(libtool.m4) 41 | -------------------------------------------------------------------------------- /windows-untested/vc71/all.vcproj: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 12 | 13 | 14 | 21 | 23 | 27 | 29 | 31 | 32 | 39 | 41 | 45 | 47 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | -------------------------------------------------------------------------------- /windows-untested/vc71/test.vcproj: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 12 | 13 | 14 | 21 | 23 | 27 | 29 | 31 | 32 | 39 | 41 | 45 | 47 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | -------------------------------------------------------------------------------- /doc/README.sgi: -------------------------------------------------------------------------------- 1 | Performance of the incremental collector can be greatly enhanced with 2 | -DNO_EXECUTE_PERMISSION. 3 | 4 | The collector should run with all of the -32, -n32 and -64 ABIs. Remember to 5 | define the AS macro in the Makefile to be "as -64", or "as -n32". 6 | 7 | If you use -DREDIRECT_MALLOC=GC_malloc with C++ code, your code should make 8 | at least one explicit call to malloc instead of new to ensure that the proper 9 | version of malloc is linked in. 10 | 11 | Sproc threads are not supported in this version, though there may exist other 12 | ports. 13 | 14 | Pthreads support is provided. This requires that: 15 | 16 | 1) You compile the collector with -DGC_THREADS specified in the Makefile. 17 | 18 | 2) You have the latest pthreads patches installed. 19 | 20 | (Though the collector makes only documented pthread calls, 21 | it relies on signal/threads interactions working just right in ways 22 | that are not required by the standard. It is unlikely that this code 23 | will run on other pthreads platforms. But please tell me if it does.) 24 | 25 | 3) Every file that makes thread calls should define GC_THREADS and then 26 | include gc.h. Gc.h redefines some of the pthread primitives as macros which 27 | also provide the collector with information it requires. 28 | 29 | 4) pthread_cond_wait and pthread_cond_timedwait should be prepared for 30 | premature wakeups. (I believe the pthreads and related standards require this 31 | anyway. Irix pthreads often terminate a wait if a signal arrives. 32 | The garbage collector uses signals to stop threads.) 33 | 34 | 5) It is expensive to stop a thread waiting in IO at the time the request is 35 | initiated. Applications with many such threads may not exhibit acceptable 36 | performance with the collector. (Increasing the heap size may help.) 37 | 38 | 6) The collector should not be compiled with -DREDIRECT_MALLOC. This 39 | confuses some library calls made by the pthreads implementation, which 40 | expect the standard malloc. 41 | -------------------------------------------------------------------------------- /windows-untested/vc60/all.dsp: -------------------------------------------------------------------------------- 1 | # Microsoft Developer Studio Project File - Name="all" - Package Owner=<4> 2 | # Microsoft Developer Studio Generated Build File, Format Version 6.00 3 | # ** DO NOT EDIT ** 4 | 5 | # TARGTYPE "Win32 (x86) Generic Project" 0x010a 6 | 7 | CFG=all - Win32 Debug 8 | !MESSAGE This is not a valid makefile. To build this project using NMAKE, 9 | !MESSAGE use the Export Makefile command and run 10 | !MESSAGE 11 | !MESSAGE NMAKE /f "all.mak". 12 | !MESSAGE 13 | !MESSAGE You can specify a configuration when running NMAKE 14 | !MESSAGE by defining the macro CFG on the command line. For example: 15 | !MESSAGE 16 | !MESSAGE NMAKE /f "all.mak" CFG="all - Win32 Debug" 17 | !MESSAGE 18 | !MESSAGE Possible choices for configuration are: 19 | !MESSAGE 20 | !MESSAGE "all - Win32 Release" (based on "Win32 (x86) Generic Project") 21 | !MESSAGE "all - Win32 Debug" (based on "Win32 (x86) Generic Project") 22 | !MESSAGE 23 | 24 | # Begin Project 25 | # PROP AllowPerConfigDependencies 0 26 | # PROP Scc_ProjName "" 27 | # PROP Scc_LocalPath "" 28 | MTL=midl.exe 29 | 30 | !IF "$(CFG)" == "all - Win32 Release" 31 | 32 | # PROP BASE Use_MFC 0 33 | # PROP BASE Use_Debug_Libraries 0 34 | # PROP BASE Output_Dir "Release" 35 | # PROP BASE Intermediate_Dir "Release" 36 | # PROP BASE Target_Dir "" 37 | # PROP Use_MFC 0 38 | # PROP Use_Debug_Libraries 0 39 | # PROP Output_Dir "..\..\..\bin" 40 | # PROP Intermediate_Dir "..\..\..\obj\Release" 41 | # PROP Target_Dir "" 42 | 43 | !ELSEIF "$(CFG)" == "all - Win32 Debug" 44 | 45 | # PROP BASE Use_MFC 0 46 | # PROP BASE Use_Debug_Libraries 1 47 | # PROP BASE Output_Dir "Debug" 48 | # PROP BASE Intermediate_Dir "Debug" 49 | # PROP BASE Target_Dir "" 50 | # PROP Use_MFC 0 51 | # PROP Use_Debug_Libraries 1 52 | # PROP Output_Dir "..\..\..\bin" 53 | # PROP Intermediate_Dir "..\..\..\obj\Debug" 54 | # PROP Target_Dir "" 55 | 56 | !ENDIF 57 | 58 | # Begin Target 59 | 60 | # Name "all - Win32 Release" 61 | # Name "all - Win32 Debug" 62 | # End Target 63 | # End Project 64 | -------------------------------------------------------------------------------- /windows-untested/vc60/test.dsp: -------------------------------------------------------------------------------- 1 | # Microsoft Developer Studio Project File - Name="test" - Package Owner=<4> 2 | # Microsoft Developer Studio Generated Build File, Format Version 6.00 3 | # ** DO NOT EDIT ** 4 | 5 | # TARGTYPE "Win32 (x86) Generic Project" 0x010a 6 | 7 | CFG=test - Win32 Debug 8 | !MESSAGE This is not a valid makefile. To build this project using NMAKE, 9 | !MESSAGE use the Export Makefile command and run 10 | !MESSAGE 11 | !MESSAGE NMAKE /f "test.mak". 12 | !MESSAGE 13 | !MESSAGE You can specify a configuration when running NMAKE 14 | !MESSAGE by defining the macro CFG on the command line. For example: 15 | !MESSAGE 16 | !MESSAGE NMAKE /f "test.mak" CFG="test - Win32 Debug" 17 | !MESSAGE 18 | !MESSAGE Possible choices for configuration are: 19 | !MESSAGE 20 | !MESSAGE "test - Win32 Release" (based on "Win32 (x86) Generic Project") 21 | !MESSAGE "test - Win32 Debug" (based on "Win32 (x86) Generic Project") 22 | !MESSAGE 23 | 24 | # Begin Project 25 | # PROP testowPerConfigDependencies 0 26 | # PROP Scc_ProjName "" 27 | # PROP Scc_LocalPath "" 28 | MTL=midl.exe 29 | 30 | !IF "$(CFG)" == "test - Win32 Release" 31 | 32 | # PROP BASE Use_MFC 0 33 | # PROP BASE Use_Debug_Libraries 0 34 | # PROP BASE Output_Dir "Release" 35 | # PROP BASE Intermediate_Dir "Release" 36 | # PROP BASE Target_Dir "" 37 | # PROP Use_MFC 0 38 | # PROP Use_Debug_Libraries 0 39 | # PROP Output_Dir "..\..\..\bin" 40 | # PROP Intermediate_Dir "..\..\..\obj\Release" 41 | # PROP Target_Dir "" 42 | 43 | !ELSEIF "$(CFG)" == "test - Win32 Debug" 44 | 45 | # PROP BASE Use_MFC 0 46 | # PROP BASE Use_Debug_Libraries 1 47 | # PROP BASE Output_Dir "Debug" 48 | # PROP BASE Intermediate_Dir "Debug" 49 | # PROP BASE Target_Dir "" 50 | # PROP Use_MFC 0 51 | # PROP Use_Debug_Libraries 1 52 | # PROP Output_Dir "..\..\..\bin" 53 | # PROP Intermediate_Dir "..\..\..\obj\Debug" 54 | # PROP Target_Dir "" 55 | 56 | !ENDIF 57 | 58 | # Begin Target 59 | 60 | # Name "test - Win32 Release" 61 | # Name "test - Win32 Debug" 62 | # End Target 63 | # End Project 64 | -------------------------------------------------------------------------------- /include/include.am: -------------------------------------------------------------------------------- 1 | # 2 | # THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED 3 | # OR IMPLIED. ANY USE IS AT YOUR OWN RISK. 4 | # 5 | # Permission is hereby granted to use or copy this program 6 | # for any purpose, provided the above notices are retained on all copies. 7 | # Permission to modify the code and to distribute modified code is granted, 8 | # provided the above notices are retained, and a notice that the code was 9 | # modified is included with the above copyright notice. 10 | 11 | ## Process this file with automake to produce part of Makefile.in. 12 | 13 | # installed headers 14 | # 15 | pkginclude_HEADERS += \ 16 | include/gc.h \ 17 | include/gc_allocator.h \ 18 | include/gc_backptr.h \ 19 | include/gc_config_macros.h \ 20 | include/gc_disclaim.h \ 21 | include/gc_gcj.h \ 22 | include/gc_inline.h \ 23 | include/gc_mark.h \ 24 | include/gc_pthread_redirects.h \ 25 | include/gc_tiny_fl.h \ 26 | include/gc_typed.h \ 27 | include/gc_version.h \ 28 | include/javaxfc.h \ 29 | include/leak_detector.h \ 30 | include/weakpointer.h 31 | 32 | # headers which are not installed 33 | # 34 | dist_noinst_HEADERS += \ 35 | include/cord.h \ 36 | include/cord_pos.h \ 37 | include/ec.h \ 38 | include/gc_alloc_ptrs.h \ 39 | include/new_gc_alloc.h \ 40 | include/private/darwin_semaphore.h \ 41 | include/private/darwin_stop_world.h \ 42 | include/private/dbg_mlc.h \ 43 | include/private/gc_atomic_ops.h \ 44 | include/private/gc_hdrs.h \ 45 | include/private/gc_locks.h \ 46 | include/private/gc_pmark.h \ 47 | include/private/gc_priv.h \ 48 | include/private/gcconfig.h \ 49 | include/private/msvc_dbg.h \ 50 | include/private/pthread_stop_world.h \ 51 | include/private/pthread_support.h \ 52 | include/private/specific.h \ 53 | include/private/thread_local_alloc.h 54 | 55 | # unprefixed header 56 | include_HEADERS += \ 57 | include/extra/gc.h 58 | -------------------------------------------------------------------------------- /doc/README.arm.cross: -------------------------------------------------------------------------------- 1 | From: Margaret Fleck 2 | 3 | Here's the key details of what worked for me, in case anyone else needs them. 4 | There may well be better ways to do some of this, but .... 5 | -- Margaret 6 | 7 | 8 | The badge4 has a StrongArm-1110 processor and a StrongArm-1111 coprocessor. 9 | 10 | Assume that the garbage collector distribution is unpacked into /home/arm/gc6.0, 11 | which is visible to both the ARM machine and a linux desktop (e.g. via NFS mounting). 12 | 13 | Assume that you have a file /home/arm/config.site with contents something like the 14 | example attached below. Notice that our local ARM toolchain lives in 15 | /skiff/local. 16 | 17 | Go to /home/arm/gc6.0 directory. Do 18 | CONFIG_SITE=/home/arm/config.site ./configure --target=arm-linux 19 | --prefix=/home/arm/gc6.0 20 | 21 | On your desktop, do: 22 | make 23 | make install 24 | The main garbage collector library should now be in ../gc6.0/lib/libgc.so. 25 | 26 | To test the garbage collector, first do the following on your desktop 27 | make gctest 28 | ./gctest 29 | Then do the following on the ARM machine 30 | cd .libs 31 | ./lt-gctest 32 | 33 | Do not try to do "make test" (the usual way of running the test 34 | program). This does not work and seems to erase some of the important 35 | files. 36 | 37 | The gctest program claims to have succeeded. Haven't run any further tests 38 | with it, though I'll be doing so in the near future. 39 | 40 | ------------------------------- 41 | # config.site for configure 42 | 43 | HOSTCC=gcc 44 | 45 | # Names of the cross-compilers 46 | CC=/skiff/local/bin/arm-linux-gcc 47 | CXX=/skiff/local/bin/arm-linux-gcc 48 | 49 | # The cross compiler specific options 50 | CFLAGS="-O2 -fno-exceptions" 51 | CXXFLAGS="-O2 -fno-exceptions" 52 | CPPFLAGS="-O2 -fno-exceptions" 53 | LDFLAGS="" 54 | 55 | # Some other programs 56 | AR=/skiff/local/bin/arm-linux-ar 57 | RANLIB=/skiff/local/bin/arm-linux-ranlib 58 | NM=/skiff/local/bin/arm-linux-nm 59 | ac_cv_path_NM=/skiff/local/bin/arm-linux-nm 60 | ac_cv_func_setpgrp_void=yes 61 | x_includes=/skiff/local/arm-linux/include/X11 62 | x_libraries=/skiff/local/arm-linux/lib/X11 63 | -------------------------------------------------------------------------------- /cord/tests/de_win.rc: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1991-1994 by Xerox Corporation. All rights reserved. 3 | * 4 | * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED 5 | * OR IMPLIED. ANY USE IS AT YOUR OWN RISK. 6 | * 7 | * Permission is hereby granted to copy this garbage collector for any purpose, 8 | * provided the above notices are retained on all copies. 9 | */ 10 | 11 | #include "windows.h" 12 | #include "de_cmds.h" 13 | #include "de_win.h" 14 | 15 | ABOUTBOX DIALOG 19, 21, 163, 47 16 | STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU 17 | CAPTION "About Demonstration Text Editor" 18 | BEGIN 19 | LTEXT "Demonstration Text Editor", -1, 44, 8, 118, 8, WS_CHILD | WS_VISIBLE | WS_GROUP 20 | PUSHBUTTON "OK", IDOK, 118, 27, 24, 14, WS_CHILD | WS_VISIBLE | WS_TABSTOP 21 | END 22 | 23 | DE MENU 24 | BEGIN 25 | POPUP "&File" 26 | BEGIN 27 | MENUITEM "&Save\t^W", IDM_FILESAVE 28 | MENUITEM "E&xit\t^D", IDM_FILEEXIT 29 | END 30 | 31 | POPUP "&Edit" 32 | BEGIN 33 | MENUITEM "Page &Down\t^R^N", IDM_EDITPDOWN 34 | MENUITEM "Page &Up\t^R^P", IDM_EDITPUP 35 | MENUITEM "U&ndo\t^U", IDM_EDITUNDO 36 | MENUITEM "&Locate\t^L ... ^L", IDM_EDITLOCATE 37 | MENUITEM "D&own\t^N", IDM_EDITDOWN 38 | MENUITEM "U&p\t^P", IDM_EDITUP 39 | MENUITEM "Le&ft\t^B", IDM_EDITLEFT 40 | MENUITEM "&Right\t^F", IDM_EDITRIGHT 41 | MENUITEM "Delete &Backward\tBS", IDM_EDITBS 42 | MENUITEM "Delete F&orward\tDEL", IDM_EDITDEL 43 | MENUITEM "&Top\t^T", IDM_EDITTOP 44 | END 45 | 46 | POPUP "&Help" 47 | BEGIN 48 | MENUITEM "&Contents", IDM_HELPCONTENTS 49 | MENUITEM "&About...", IDM_HELPABOUT 50 | END 51 | 52 | MENUITEM "Page_&Down", IDM_EDITPDOWN 53 | MENUITEM "Page_&Up", IDM_EDITPUP 54 | END 55 | 56 | DE ACCELERATORS 57 | BEGIN 58 | "^R", IDM_EDITREPEAT 59 | "^N", IDM_EDITDOWN 60 | "^P", IDM_EDITUP 61 | "^L", IDM_EDITLOCATE 62 | "^B", IDM_EDITLEFT 63 | "^F", IDM_EDITRIGHT 64 | "^T", IDM_EDITTOP 65 | VK_DELETE, IDM_EDITDEL, VIRTKEY 66 | VK_BACK, IDM_EDITBS, VIRTKEY 67 | END 68 | -------------------------------------------------------------------------------- /sparc_mach_dep.S: -------------------------------------------------------------------------------- 1 | ! SPARCompiler 3.0 and later apparently no longer handles 2 | ! asm outside functions. So we need a separate .s file 3 | ! This is only set up for SunOS 5, not SunOS 4. 4 | ! Assumes this is called before the stack contents are 5 | ! examined. 6 | 7 | .seg "text" 8 | .globl GC_save_regs_in_stack 9 | GC_save_regs_in_stack: 10 | #if defined(__arch64__) || defined(__sparcv9) 11 | save %sp,-128,%sp 12 | flushw 13 | ret 14 | restore %sp,2047+128,%o0 15 | #else /* 32 bit SPARC */ 16 | ta 0x3 ! ST_FLUSH_WINDOWS 17 | mov %sp,%o0 18 | retl 19 | nop 20 | #endif /* 32 bit SPARC */ 21 | .GC_save_regs_in_stack_end: 22 | .size GC_save_regs_in_stack,.GC_save_regs_in_stack_end-GC_save_regs_in_stack 23 | 24 | ! GC_clear_stack_inner(arg, limit) clears stack area up to limit and 25 | ! returns arg. Stack clearing is crucial on SPARC, so we supply 26 | ! an assembly version that s more careful. Assumes limit is hotter 27 | ! than sp, and limit is 8 byte aligned. 28 | .globl GC_clear_stack_inner 29 | GC_clear_stack_inner: 30 | #if defined(__arch64__) || defined(__sparcv9) 31 | mov %sp,%o2 ! Save sp 32 | add %sp,2047-8,%o3 ! p = sp+bias-8 33 | add %o1,-2047-192,%sp ! Move sp out of the way, 34 | ! so that traps still work. 35 | ! Includes some extra words 36 | ! so we can be sloppy below. 37 | loop: 38 | stx %g0,[%o3] ! *(long *)p = 0 39 | cmp %o3,%o1 40 | bgu,pt %xcc, loop ! if (p > limit) goto loop 41 | add %o3,-8,%o3 ! p -= 8 (delay slot) 42 | retl 43 | mov %o2,%sp ! Restore sp., delay slot 44 | #else /* 32 bit SPARC */ 45 | mov %sp,%o2 ! Save sp 46 | add %sp,-8,%o3 ! p = sp-8 47 | clr %g1 ! [g0,g1] = 0 48 | add %o1,-0x60,%sp ! Move sp out of the way, 49 | ! so that traps still work. 50 | ! Includes some extra words 51 | ! so we can be sloppy below. 52 | loop: 53 | std %g0,[%o3] ! *(long long *)p = 0 54 | cmp %o3,%o1 55 | bgu loop ! if (p > limit) goto loop 56 | add %o3,-8,%o3 ! p -= 8 (delay slot) 57 | retl 58 | mov %o2,%sp ! Restore sp., delay slot 59 | #endif /* 32 bit SPARC */ 60 | .GC_clear_stack_inner_end: 61 | .size GC_clear_stack_inner,.GC_clear_stack_inner_end-GC_clear_stack_inner 62 | -------------------------------------------------------------------------------- /OS2_MAKEFILE: -------------------------------------------------------------------------------- 1 | # Makefile for OS/2. Assumes IBM's compiler, static linking, and a single thread. 2 | # Adding dynamic linking support seems easy, but takes a little bit of work. 3 | # Adding thread support may be nontrivial, since we haven't yet figured out how to 4 | # look at another thread's registers. 5 | 6 | # Significantly revised for GC version 4.4 by Mark Boulter (Jan 1994). 7 | 8 | OBJS= alloc.obj reclaim.obj allchblk.obj misc.obj mach_dep.obj os_dep.obj mark_rts.obj headers.obj mark.obj obj_map.obj blacklst.obj finalize.obj new_hblk.obj dbg_mlc.obj fnlz_mlc.obj malloc.obj typd_mlc.obj ptr_chck.obj mallocx.obj 9 | 10 | CORDOBJS= cord\cordbscs.obj cord\cordxtra.obj cord\cordprnt.obj 11 | 12 | CC= icc 13 | CFLAGS= /O /Q /DSMALL_CONFIG /DALL_INTERIOR_POINTERS /DENABLE_DISCLAIM 14 | # Use /Ti instead of /O for debugging 15 | # Setjmp_test may yield overly optimistic results when compiled 16 | # without optimization. 17 | 18 | all: $(OBJS) gctest.exe cord\cordtest.exe 19 | 20 | $(OBJS) test.obj: include\private\gc_priv.h include\private\gc_hdrs.h include\gc.h include\private\gcconfig.h 21 | 22 | ## ERASE THE LIB FIRST - if it is already there then this command will fail 23 | ## (make sure its there or erase will fail!) 24 | gc.lib: $(OBJS) 25 | echo . > gc.lib 26 | erase gc.lib 27 | LIB gc.lib $(OBJS), gc.lst 28 | 29 | mach_dep.obj: mach_dep.c 30 | $(CC) $(CFLAGS) /C mach_dep.c 31 | 32 | gctest.exe: test.obj gc.lib 33 | $(CC) $(CFLAGS) /B"/STACK:524288" /Fegctest test.obj gc.lib 34 | 35 | cord\cordbscs.obj: cord\cordbscs.c include\cord.h include\cord_pos.h 36 | $(CC) $(CFLAGS) /C /Focord\cordbscs cord\cordbscs.c 37 | 38 | cord\cordxtra.obj: cord\cordxtra.c include\cord.h include\cord_pos.h include\ec.h 39 | $(CC) $(CFLAGS) /C /Focord\cordxtra cord\cordxtra.c 40 | 41 | cord\cordprnt.obj: cord\cordprnt.c include\cord.h include\cord_pos.h include\ec.h 42 | $(CC) $(CFLAGS) /C /Focord\cordprnt cord\cordprnt.c 43 | 44 | cord\cordtest.exe: cord\tests\cordtest.c include\cord.h include\cord_pos.h include\ec.h $(CORDOBJS) gc.lib 45 | $(CC) $(CFLAGS) /B"/STACK:65536" /Fecord\cordtest cord\tests\cordtest.c gc.lib $(CORDOBJS) 46 | -------------------------------------------------------------------------------- /include/gc_version.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1994 by Xerox Corporation. All rights reserved. 3 | * Copyright (c) 1996 by Silicon Graphics. All rights reserved. 4 | * Copyright (c) 1998 by Fergus Henderson. All rights reserved. 5 | * Copyright (c) 2000-2009 by Hewlett-Packard Development Company. 6 | * All rights reserved. 7 | * 8 | * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED 9 | * OR IMPLIED. ANY USE IS AT YOUR OWN RISK. 10 | * 11 | * Permission is hereby granted to use or copy this program 12 | * for any purpose, provided the above notices are retained on all copies. 13 | * Permission to modify the code and to distribute modified code is granted, 14 | * provided the above notices are retained, and a notice that the code was 15 | * modified is included with the above copyright notice. 16 | */ 17 | 18 | /* This should never be included directly; it is included only from gc.h. */ 19 | #if defined(GC_H) 20 | 21 | /* The policy regarding version numbers: development code has odd */ 22 | /* "minor" number (and "micro" part is 0); when development is finished */ 23 | /* and a release is prepared, "minor" number is incremented (keeping */ 24 | /* "micro" number still zero), whenever a defect is fixed a new release */ 25 | /* is prepared incrementing "micro" part to odd value (the most stable */ 26 | /* release has the biggest "micro" number). */ 27 | 28 | /* The version here should match that in configure/configure.ac */ 29 | /* Eventually this one may become unnecessary. For now we need */ 30 | /* it to keep the old-style build process working. */ 31 | #define GC_TMP_VERSION_MAJOR 7 32 | #define GC_TMP_VERSION_MINOR 7 33 | #define GC_TMP_VERSION_MICRO 0 /* 7.7.0 */ 34 | 35 | #ifdef GC_VERSION_MAJOR 36 | # if GC_TMP_VERSION_MAJOR != GC_VERSION_MAJOR \ 37 | || GC_TMP_VERSION_MINOR != GC_VERSION_MINOR \ 38 | || GC_TMP_VERSION_MICRO != GC_VERSION_MICRO 39 | # error Inconsistent version info. Check README.md, include/gc_version.h and configure.ac. 40 | # endif 41 | #else 42 | # define GC_VERSION_MAJOR GC_TMP_VERSION_MAJOR 43 | # define GC_VERSION_MINOR GC_TMP_VERSION_MINOR 44 | # define GC_VERSION_MICRO GC_TMP_VERSION_MICRO 45 | #endif /* !GC_VERSION_MAJOR */ 46 | 47 | #endif 48 | -------------------------------------------------------------------------------- /tests/staticrootstest.c: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | 5 | #ifndef GC_DEBUG 6 | # define GC_DEBUG 7 | #endif 8 | 9 | #include "gc.h" 10 | #include "gc_backptr.h" 11 | 12 | #ifndef GC_TEST_IMPORT_API 13 | # define GC_TEST_IMPORT_API extern 14 | #endif 15 | 16 | /* Should match that in staticrootslib.c. */ 17 | struct treenode { 18 | struct treenode *x; 19 | struct treenode *y; 20 | }; 21 | 22 | struct treenode *root[10] = { NULL }; 23 | 24 | /* Same as "root" variable but initialized to some non-zero value (to */ 25 | /* be placed to .data section instead of .bss). */ 26 | struct treenode *root_nz[10] = { (struct treenode *)(GC_word)1 }; 27 | 28 | static char *staticroot; /* intentionally static */ 29 | 30 | GC_TEST_IMPORT_API struct treenode * libsrl_mktree(int i); 31 | GC_TEST_IMPORT_API void * libsrl_init(void); 32 | GC_TEST_IMPORT_API struct treenode ** libsrl_getpelem(int i, int j); 33 | 34 | GC_TEST_IMPORT_API struct treenode ** libsrl_getpelem2(int i, int j); 35 | 36 | void init_staticroot(void) 37 | { 38 | /* Intentionally put staticroot initialization in a function other */ 39 | /* than main to prevent CSA warning that staticroot variable can be */ 40 | /* changed to be a local one). */ 41 | staticroot = (char *)libsrl_init(); 42 | } 43 | 44 | int main(void) 45 | { 46 | int i, j; 47 | 48 | # ifdef STATICROOTSLIB_INIT_IN_MAIN 49 | GC_INIT(); 50 | # endif 51 | init_staticroot(); 52 | if (NULL == staticroot) { 53 | fprintf(stderr, "GC_malloc returned NULL\n"); 54 | return 2; 55 | } 56 | memset(staticroot, 0x42, sizeof(struct treenode)); 57 | GC_gcollect(); 58 | for (j = 0; j < 4; j++) { 59 | for (i = 0; i < (int)(sizeof(root) / sizeof(root[0])); ++i) { 60 | # ifdef STATICROOTSLIB2 61 | *libsrl_getpelem2(i, j) = libsrl_mktree(12); 62 | # endif 63 | *libsrl_getpelem(i, j) = libsrl_mktree(12); 64 | ((j & 1) != 0 ? root_nz : root)[i] = libsrl_mktree(12); 65 | GC_gcollect(); 66 | } 67 | for (i = 0; i < (int)sizeof(struct treenode); ++i) { 68 | if (staticroot[i] != 0x42) { 69 | fprintf(stderr, "Memory check failed\n"); 70 | return -1; 71 | } 72 | } 73 | } 74 | return 0; 75 | } 76 | -------------------------------------------------------------------------------- /include/leak_detector.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2000-2011 by Hewlett-Packard Development Company. 3 | * All rights reserved. 4 | * 5 | * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED 6 | * OR IMPLIED. ANY USE IS AT YOUR OWN RISK. 7 | * 8 | * Permission is hereby granted to use or copy this program 9 | * for any purpose, provided the above notices are retained on all copies. 10 | * Permission to modify the code and to distribute modified code is granted, 11 | * provided the above notices are retained, and a notice that the code was 12 | * modified is included with the above copyright notice. 13 | */ 14 | 15 | #ifndef GC_LEAK_DETECTOR_H 16 | #define GC_LEAK_DETECTOR_H 17 | 18 | /* Include leak_detector.h (e.g., via GCC --include directive) */ 19 | /* to turn BoehmGC into a Leak Detector. */ 20 | 21 | #ifndef GC_DEBUG 22 | # define GC_DEBUG 23 | #endif 24 | #include "gc.h" 25 | 26 | #ifndef GC_DONT_INCLUDE_STDLIB 27 | /* We ensure stdlib.h and string.h are included before */ 28 | /* redirecting malloc() and the accompanying functions. */ 29 | # include 30 | # include 31 | #endif 32 | 33 | #undef malloc 34 | #define malloc(n) GC_MALLOC(n) 35 | #undef calloc 36 | #define calloc(m,n) GC_MALLOC((m)*(n)) 37 | #undef free 38 | #define free(p) GC_FREE(p) 39 | #undef realloc 40 | #define realloc(p,n) GC_REALLOC(p,n) 41 | 42 | #undef strdup 43 | #define strdup(s) GC_STRDUP(s) 44 | #undef strndup 45 | #define strndup(s,n) GC_STRNDUP(s,n) 46 | 47 | #ifdef GC_REQUIRE_WCSDUP 48 | /* The collector should be built with GC_REQUIRE_WCSDUP */ 49 | /* defined as well to redirect wcsdup(). */ 50 | # include 51 | # undef wcsdup 52 | # define wcsdup(s) GC_WCSDUP(s) 53 | #endif 54 | 55 | #undef memalign 56 | #define memalign(a,n) GC_memalign(a,n) 57 | #undef posix_memalign 58 | #define posix_memalign(p,a,n) GC_posix_memalign(p,a,n) 59 | 60 | #ifndef CHECK_LEAKS 61 | # define CHECK_LEAKS() GC_gcollect() 62 | /* Note 1: CHECK_LEAKS does not have GC prefix (preserved for */ 63 | /* backward compatibility). */ 64 | /* Note 2: GC_gcollect() is also called automatically in the */ 65 | /* leak-finding mode at program exit. */ 66 | #endif 67 | 68 | #endif /* GC_LEAK_DETECTOR_H */ 69 | -------------------------------------------------------------------------------- /tests/thread_leak_test.c: -------------------------------------------------------------------------------- 1 | 2 | #ifdef HAVE_CONFIG_H 3 | # include "config.h" 4 | #endif 5 | 6 | #ifndef GC_THREADS 7 | # define GC_THREADS 8 | #endif 9 | 10 | #undef GC_NO_THREAD_REDIRECTS 11 | #include "leak_detector.h" 12 | 13 | #ifdef GC_PTHREADS 14 | # include 15 | #else 16 | # include 17 | #endif 18 | 19 | #include 20 | 21 | #ifdef GC_PTHREADS 22 | void * test(void * arg) 23 | #else 24 | DWORD WINAPI test(LPVOID arg) 25 | #endif 26 | { 27 | int *p[10]; 28 | int i; 29 | for (i = 0; i < 10; ++i) { 30 | p[i] = (int *)malloc(sizeof(int) + i); 31 | } 32 | CHECK_LEAKS(); 33 | for (i = 1; i < 10; ++i) { 34 | free(p[i]); 35 | } 36 | # ifdef GC_PTHREADS 37 | return arg; 38 | # else 39 | return (DWORD)(GC_word)arg; 40 | # endif 41 | } 42 | 43 | #ifndef NTHREADS 44 | # define NTHREADS 5 45 | #endif 46 | 47 | int main(void) { 48 | # if NTHREADS > 0 49 | int i; 50 | # ifdef GC_PTHREADS 51 | pthread_t t[NTHREADS]; 52 | # else 53 | HANDLE t[NTHREADS]; 54 | DWORD thread_id; 55 | # endif 56 | int code; 57 | # endif 58 | 59 | GC_set_find_leak(1); /* for new collect versions not compiled */ 60 | /* with -DFIND_LEAK. */ 61 | GC_INIT(); 62 | 63 | # if NTHREADS > 0 64 | for (i = 0; i < NTHREADS; ++i) { 65 | # ifdef GC_PTHREADS 66 | code = pthread_create(t + i, 0, test, 0); 67 | # else 68 | t[i] = CreateThread(NULL, 0, test, 0, 0, &thread_id); 69 | code = t[i] != NULL ? 0 : (int)GetLastError(); 70 | # endif 71 | if (code != 0) { 72 | fprintf(stderr, "Thread creation failed %d\n", code); 73 | exit(2); 74 | } 75 | } 76 | 77 | for (i = 0; i < NTHREADS; ++i) { 78 | # ifdef GC_PTHREADS 79 | code = pthread_join(t[i], 0); 80 | # else 81 | code = WaitForSingleObject(t[i], INFINITE) == WAIT_OBJECT_0 ? 0 : 82 | (int)GetLastError(); 83 | # endif 84 | if (code != 0) { 85 | fprintf(stderr, "Thread join failed %d\n", code); 86 | exit(2); 87 | } 88 | } 89 | # endif 90 | 91 | CHECK_LEAKS(); 92 | CHECK_LEAKS(); 93 | CHECK_LEAKS(); 94 | return 0; 95 | } 96 | -------------------------------------------------------------------------------- /digimars.mak: -------------------------------------------------------------------------------- 1 | # Makefile to build Hans Boehm garbage collector using the Digital Mars 2 | # compiler from www.digitalmars.com 3 | # Written by Walter Bright 4 | 5 | 6 | DEFINES=-DNDEBUG -D_WINDOWS -DGC_DLL -DALL_INTERIOR_POINTERS -DENABLE_DISCLAIM -DWIN32_THREADS 7 | CFLAGS=-Iinclude $(DEFINES) -wx -g 8 | LFLAGS=/ma/implib/co 9 | CC=sc 10 | 11 | .c.obj: 12 | $(CC) -c $(CFLAGS) $* 13 | 14 | .cpp.obj: 15 | $(CC) -c $(CFLAGS) -Aa $* 16 | 17 | OBJS= \ 18 | allchblk.obj\ 19 | alloc.obj\ 20 | blacklst.obj\ 21 | checksums.obj\ 22 | dbg_mlc.obj\ 23 | fnlz_mlc.obj\ 24 | dyn_load.obj\ 25 | finalize.obj\ 26 | gc_cpp.obj\ 27 | headers.obj\ 28 | mach_dep.obj\ 29 | malloc.obj\ 30 | mallocx.obj\ 31 | mark.obj\ 32 | mark_rts.obj\ 33 | misc.obj\ 34 | new_hblk.obj\ 35 | obj_map.obj\ 36 | os_dep.obj\ 37 | ptr_chck.obj\ 38 | reclaim.obj\ 39 | typd_mlc.obj\ 40 | win32_threads.obj 41 | 42 | targets: gc.dll gc.lib gctest.exe 43 | 44 | gc.dll: $(OBJS) gc.def digimars.mak 45 | sc -ogc.dll $(OBJS) -L$(LFLAGS) gc.def kernel32.lib user32.lib 46 | 47 | gc.def: digimars.mak 48 | echo LIBRARY GC >gc.def 49 | echo DESCRIPTION "Hans Boehm Garbage Collector" >>gc.def 50 | echo EXETYPE NT >>gc.def 51 | echo EXPORTS >>gc.def 52 | echo GC_is_visible_print_proc >>gc.def 53 | echo GC_is_valid_displacement_print_proc >>gc.def 54 | 55 | clean: 56 | del gc.def 57 | del $(OBJS) 58 | 59 | 60 | gctest.exe : gc.lib tests\test.obj 61 | sc -ogctest.exe tests\test.obj gc.lib 62 | 63 | tests\test.obj : tests\test.c 64 | $(CC) -c -g -DNDEBUG -D_WINDOWS -DGC_DLL \ 65 | -DALL_INTERIOR_POINTERS -DWIN32_THREADS \ 66 | -Iinclude tests\test.c -otests\test.obj 67 | 68 | allchblk.obj: allchblk.c 69 | alloc.obj: alloc.c 70 | blacklst.obj: blacklst.c 71 | checksums.obj: checksums.c 72 | dbg_mlc.obj: dbg_mlc.c 73 | dyn_load.obj: dyn_load.c 74 | finalize.obj: finalize.c 75 | fnlz_mlc.obj: fnlz_mlc.c 76 | gc_cpp.obj: gc_cpp.cpp 77 | headers.obj: headers.c 78 | mach_dep.obj: mach_dep.c 79 | malloc.obj: malloc.c 80 | mallocx.obj: mallocx.c 81 | mark.obj: mark.c 82 | mark_rts.obj: mark_rts.c 83 | misc.obj: misc.c 84 | new_hblk.obj: new_hblk.c 85 | obj_map.obj: obj_map.c 86 | os_dep.obj: os_dep.c 87 | ptr_chck.obj: ptr_chck.c 88 | reclaim.obj: reclaim.c 89 | typd_mlc.obj: typd_mlc.c 90 | win32_threads.obj: win32_threads.c 91 | -------------------------------------------------------------------------------- /include/private/pthread_stop_world.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1994 by Xerox Corporation. All rights reserved. 3 | * Copyright (c) 1996 by Silicon Graphics. All rights reserved. 4 | * Copyright (c) 1998 by Fergus Henderson. All rights reserved. 5 | * Copyright (c) 2000-2009 by Hewlett-Packard Development Company. 6 | * All rights reserved. 7 | * 8 | * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED 9 | * OR IMPLIED. ANY USE IS AT YOUR OWN RISK. 10 | * 11 | * Permission is hereby granted to use or copy this program 12 | * for any purpose, provided the above notices are retained on all copies. 13 | * Permission to modify the code and to distribute modified code is granted, 14 | * provided the above notices are retained, and a notice that the code was 15 | * modified is included with the above copyright notice. 16 | */ 17 | 18 | #ifndef GC_PTHREAD_STOP_WORLD_H 19 | #define GC_PTHREAD_STOP_WORLD_H 20 | 21 | EXTERN_C_BEGIN 22 | 23 | struct thread_stop_info { 24 | # if !defined(GC_OPENBSD_UTHREADS) && !defined(NACL) 25 | # ifdef GC_ATOMIC_OPS_H 26 | volatile AO_t last_stop_count; 27 | # else 28 | word last_stop_count; 29 | # endif 30 | /* The value of GC_stop_count when the thread */ 31 | /* last successfully handled a suspend signal. */ 32 | # endif 33 | 34 | ptr_t stack_ptr; /* Valid only when stopped. */ 35 | 36 | # ifdef NACL 37 | /* Grab NACL_GC_REG_STORAGE_SIZE pointers off the stack when */ 38 | /* going into a syscall. 20 is more than we need, but it's an */ 39 | /* overestimate in case the instrumented function uses any callee */ 40 | /* saved registers, they may be pushed to the stack much earlier. */ 41 | /* Also, on amd64 'push' puts 8 bytes on the stack even though */ 42 | /* our pointers are 4 bytes. */ 43 | # ifdef ARM32 44 | /* Space for r4-r8, r10-r12, r14. */ 45 | # define NACL_GC_REG_STORAGE_SIZE 9 46 | # else 47 | # define NACL_GC_REG_STORAGE_SIZE 20 48 | # endif 49 | ptr_t reg_storage[NACL_GC_REG_STORAGE_SIZE]; 50 | # endif 51 | 52 | #if defined(PLATFORM_GC_REG_STORAGE_SIZE) 53 | __uint64_t registers[PLATFORM_GC_REG_STORAGE_SIZE]; 54 | #endif 55 | }; 56 | 57 | GC_INNER void GC_stop_init(void); 58 | 59 | EXTERN_C_END 60 | 61 | #endif 62 | -------------------------------------------------------------------------------- /doc/README.ews4800: -------------------------------------------------------------------------------- 1 | GC on EWS4800 2 | ------------- 3 | 4 | 1. About EWS4800 5 | 6 | EWS4800 is a 32/64-bit workstation. 7 | 8 | Vendor: NEC Corporation 9 | OS: UX/4800 R9.* - R13.* (SystemV R4.2) 10 | CPU: R4000, R4400, R10000 (MIPS) 11 | 12 | 2. Compiler 13 | 14 | 32-bit: 15 | Use ANSI C compiler. 16 | CC = /usr/abiccs/bin/cc 17 | 18 | 64-bit: 19 | Use the 64-bit ANSI C compiler. 20 | CC = /usr/ccs64/bin/cc 21 | AR = /usr/ccs64/bin/ar 22 | 23 | 3. ELF file format 24 | *** Caution: The following information is empirical. *** 25 | 26 | 32-bit: 27 | ELF file has an unique format. (See a.out(4) and end(3C).) 28 | 29 | &_start 30 | : text segment 31 | &etext 32 | DATASTART 33 | : data segment (initialized) 34 | &edata 35 | DATASTART2 36 | : data segment (uninitialized) 37 | &end 38 | 39 | Here, DATASTART and DATASTART2 are macros of GC, and are defined as 40 | the following equations. (See include/private/gcconfig.h.) 41 | The algorithm for DATASTART is similar with the function 42 | GC_SysVGetDataStart() in os_dep.c. 43 | 44 | DATASTART = ((&etext + 0x3ffff) & ~0x3ffff) + (&etext & 0xffff) 45 | 46 | Dynamically linked: 47 | DATASTART2 = (&_gp + 0x8000 + 0x3ffff) & ~0x3ffff 48 | 49 | Statically linked: 50 | DATASTART2 = &edata 51 | 52 | GC has to check addresses both between DATASTART and &edata, and 53 | between DATASTART2 and &end. If a program accesses between &etext 54 | and DATASTART, or between &edata and DATASTART2, the segmentation 55 | error occurs and the program stops. 56 | 57 | If a program is statically linked, there is not a gap between 58 | &edata and DATASTART2. The global symbol &_DYNAMIC_LINKING is used 59 | for the detection. 60 | 61 | 64-bit: 62 | ELF file has a simple format. (See end(3C).) 63 | 64 | _ftext 65 | : text segment 66 | _etext 67 | _fdata = DATASTART 68 | : data segment (initialized) 69 | _edata 70 | _fbss 71 | : data segment (uninitialized) 72 | _end = DATAEND 73 | 74 | -- 75 | Hironori SAKAMOTO 76 | 77 | 78 | When using the new "configure; make" build process, please 79 | run configure with the --disable-shared option. "Make check" does not 80 | yet pass with dynamic libraries. The reasons for that are not yet 81 | understood. (HB, paraphrasing message from Hironori SAKAMOTO.) 82 | -------------------------------------------------------------------------------- /include/ec.h: -------------------------------------------------------------------------------- 1 | # ifndef EC_H 2 | # define EC_H 3 | 4 | # ifndef CORD_H 5 | # include "cord.h" 6 | # endif 7 | 8 | #ifdef __cplusplus 9 | extern "C" { 10 | #endif 11 | 12 | /* Extensible cords are strings that may be destructively appended to. */ 13 | /* They allow fast construction of cords from characters that are */ 14 | /* being read from a stream. */ 15 | /* 16 | * A client might look like: 17 | * 18 | * { 19 | * CORD_ec x; 20 | * CORD result; 21 | * char c; 22 | * FILE *f; 23 | * 24 | * ... 25 | * CORD_ec_init(x); 26 | * while(...) { 27 | * c = getc(f); 28 | * ... 29 | * CORD_ec_append(x, c); 30 | * } 31 | * result = CORD_balance(CORD_ec_to_cord(x)); 32 | * 33 | * If a C string is desired as the final result, the call to CORD_balance 34 | * may be replaced by a call to CORD_to_char_star. 35 | */ 36 | 37 | # ifndef CORD_BUFSZ 38 | # define CORD_BUFSZ 128 39 | # endif 40 | 41 | typedef struct CORD_ec_struct { 42 | CORD ec_cord; 43 | char * ec_bufptr; 44 | char ec_buf[CORD_BUFSZ+1]; 45 | } CORD_ec[1]; 46 | 47 | /* This structure represents the concatenation of ec_cord with */ 48 | /* ec_buf[0 ... (ec_bufptr-ec_buf-1)] */ 49 | 50 | /* Flush the buffer part of the extended chord into ec_cord. */ 51 | /* Note that this is almost the only real function, and it is */ 52 | /* implemented in 6 lines in cordxtra.c */ 53 | void CORD_ec_flush_buf(CORD_ec x); 54 | 55 | /* Convert an extensible cord to a cord. */ 56 | # define CORD_ec_to_cord(x) (CORD_ec_flush_buf(x), (x)[0].ec_cord) 57 | 58 | /* Initialize an extensible cord. */ 59 | #define CORD_ec_init(x) \ 60 | ((x)[0].ec_cord = 0, (void)((x)[0].ec_bufptr = (x)[0].ec_buf)) 61 | 62 | /* Append a character to an extensible cord. */ 63 | #define CORD_ec_append(x, c) \ 64 | (((x)[0].ec_bufptr == (x)[0].ec_buf + CORD_BUFSZ ? \ 65 | (CORD_ec_flush_buf(x), 0) : 0), \ 66 | (void)(*(x)[0].ec_bufptr++ = (c))) 67 | 68 | /* Append a cord to an extensible cord. Structure remains shared with */ 69 | /* original. */ 70 | void CORD_ec_append_cord(CORD_ec x, CORD s); 71 | 72 | #ifdef __cplusplus 73 | } /* extern "C" */ 74 | #endif 75 | 76 | # endif /* EC_H */ 77 | -------------------------------------------------------------------------------- /doc/README.cords: -------------------------------------------------------------------------------- 1 | Copyright (c) 1993-1994 by Xerox Corporation. All rights reserved. 2 | 3 | THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED 4 | OR IMPLIED. ANY USE IS AT YOUR OWN RISK. 5 | 6 | Permission is hereby granted to use or copy this program 7 | for any purpose, provided the above notices are retained on all copies. 8 | Permission to modify the code and to distribute modified code is granted, 9 | provided the above notices are retained, and a notice that the code was 10 | modified is included with the above copyright notice. 11 | 12 | Please send bug reports to Hans-J. Boehm. 13 | 14 | This is a string packages that uses a tree-based representation. 15 | See cord.h for a description of the functions provided. Ec.h describes 16 | "extensible cords", which are essentially output streams that write 17 | to a cord. These allow for efficient construction of cords without 18 | requiring a bound on the size of a cord. 19 | 20 | More details on the data structure can be found in 21 | 22 | Boehm, Atkinson, and Plass, "Ropes: An Alternative to Strings", 23 | Software Practice and Experience 25, 12, December 1995, pp. 1315-1330. 24 | 25 | A fundamentally similar "rope" data structure is also part of SGI's standard 26 | template library implementation, and its descendants, which include the 27 | GNU C++ library. That uses reference counting by default. 28 | There is a short description of that data structure at 29 | http://www.sgi.com/tech/stl/ropeimpl.html . 30 | 31 | All of these are descendants of the "ropes" in Xerox Cedar. 32 | 33 | cord/tests/de.c is a very dumb text editor that illustrates the use of cords. 34 | It maintains a list of file versions. Each version is simply a 35 | cord representing the file contents. Nonetheless, standard 36 | editing operations are efficient, even on very large files. 37 | (Its 3 line "user manual" can be obtained by invoking it without 38 | arguments. Note that ^R^N and ^R^P move the cursor by 39 | almost a screen. It does not understand tabs, which will show 40 | up as highlighted "I"s. Use the UNIX "expand" program first.) 41 | To build the editor, type "make cord/de" in the gc directory. 42 | 43 | Note that CORD_printf and friends use C functions with variable numbers 44 | of arguments in non-standard-conforming ways. This code is known to 45 | break on some platforms, notably PowerPC. It should be possible to 46 | build the remainder of the library (everything but cordprnt.c) on 47 | any platform that supports the collector. 48 | -------------------------------------------------------------------------------- /tests/huge_test.c: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | #include 5 | 6 | #ifndef GC_IGNORE_WARN 7 | /* Ignore misleading "Out of Memory!" warning (which is printed on */ 8 | /* every GC_MALLOC call below) by defining this macro before "gc.h" */ 9 | /* inclusion. */ 10 | # define GC_IGNORE_WARN 11 | #endif 12 | 13 | #ifndef GC_MAXIMUM_HEAP_SIZE 14 | # define GC_MAXIMUM_HEAP_SIZE 100 * 1024 * 1024 15 | # define GC_INITIAL_HEAP_SIZE GC_MAXIMUM_HEAP_SIZE / 20 16 | /* Otherwise heap expansion aborts when deallocating large block. */ 17 | /* That's OK. We test this corner case mostly to make sure that */ 18 | /* it fails predictably. */ 19 | #endif 20 | 21 | #ifndef GC_ATTR_ALLOC_SIZE 22 | /* Omit alloc_size attribute to avoid compiler warnings about */ 23 | /* exceeding maximum object size when values close to GC_SWORD_MAX */ 24 | /* are passed to GC_MALLOC. */ 25 | # define GC_ATTR_ALLOC_SIZE(argnum) /* empty */ 26 | #endif 27 | 28 | #include "gc.h" 29 | 30 | /* 31 | * Check that very large allocation requests fail. "Success" would usually 32 | * indicate that the size was somehow converted to a negative 33 | * number. Clients shouldn't do this, but we should fail in the 34 | * expected manner. 35 | */ 36 | 37 | #define CHECK_ALLOC_FAILED(r, sz_str) \ 38 | do { \ 39 | if (NULL != (r)) { \ 40 | fprintf(stderr, \ 41 | "Size " sz_str " allocation unexpectedly succeeded\n"); \ 42 | exit(1); \ 43 | } \ 44 | } while (0) 45 | 46 | #define GC_WORD_MAX ((GC_word)-1) 47 | #define GC_SWORD_MAX ((GC_signed_word)(GC_WORD_MAX >> 1)) 48 | 49 | int main(void) 50 | { 51 | GC_INIT(); 52 | 53 | CHECK_ALLOC_FAILED(GC_MALLOC(GC_SWORD_MAX - 1024), "SWORD_MAX-1024"); 54 | CHECK_ALLOC_FAILED(GC_MALLOC(GC_SWORD_MAX), "SWORD_MAX"); 55 | CHECK_ALLOC_FAILED(GC_MALLOC((GC_word)GC_SWORD_MAX + 1), "SWORD_MAX+1"); 56 | CHECK_ALLOC_FAILED(GC_MALLOC((GC_word)GC_SWORD_MAX + 1024), 57 | "SWORD_MAX+1024"); 58 | CHECK_ALLOC_FAILED(GC_MALLOC(GC_WORD_MAX - 1024), "WORD_MAX-1024"); 59 | CHECK_ALLOC_FAILED(GC_MALLOC(GC_WORD_MAX - 16), "WORD_MAX-16"); 60 | CHECK_ALLOC_FAILED(GC_MALLOC(GC_WORD_MAX - 8), "WORD_MAX-8"); 61 | CHECK_ALLOC_FAILED(GC_MALLOC(GC_WORD_MAX - 4), "WORD_MAX-4"); 62 | CHECK_ALLOC_FAILED(GC_MALLOC(GC_WORD_MAX), "WORD_MAX"); 63 | return 0; 64 | } 65 | -------------------------------------------------------------------------------- /doc/README.autoconf: -------------------------------------------------------------------------------- 1 | Starting from GC v6.0, we support GNU-style builds based on automake, 2 | autoconf and libtool. This is based almost entirely on Tom Tromey's work 3 | with gcj. 4 | 5 | To build and install libraries use 6 | 7 | configure; make; make install 8 | 9 | The advantages of this process are: 10 | 11 | 1) It should eventually do a better job of automatically determining the 12 | right compiler to use, etc. It probably already does in some cases. 13 | 14 | 2) It tries to automatically set a good set of default GC parameters for 15 | the platform (e.g. thread support). It provides an easier way to configure 16 | some of the others. 17 | 18 | 3) It integrates better with other projects using a GNU-style build process. 19 | 20 | 4) It builds both dynamic and static libraries. 21 | 22 | The known disadvantages are: 23 | 24 | 1) The build scripts are much more complex and harder to debug (though largely 25 | standard). I don't understand them all, and there's probably lots of redundant 26 | stuff. 27 | 28 | 2) It probably doesn't work on all Un*x-like platforms yet. It probably will 29 | never work on the rest. 30 | 31 | 3) The scripts are not yet complete. Some of the standard GNU targets don't 32 | yet work. (Corrections/additions are very welcome.) 33 | 34 | The distribution should contain all files needed to run "configure" and "make", 35 | as well as the sources needed to regenerate the derived files. (If I missed 36 | some, please let me know.) 37 | 38 | Note that the distribution comes without "Makefile" which is generated by 39 | "configure". The distribution also contains "Makefile.direct" which is not 40 | always equivalent to the generated one. 41 | 42 | Important options to configure: 43 | 44 | --prefix=PREFIX install architecture-independent files in PREFIX 45 | [/usr/local] 46 | --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX 47 | [same as prefix] 48 | --enable-threads=TYPE choose threading package 49 | --disable-parallel-mark do not parallelize marking and free list 50 | construction 51 | --enable-gc-debug include full support for pointer back-tracing, etc. 52 | 53 | 54 | Unless --prefix is set (or --exec-prefix or one of the more obscure options), 55 | make install will install libgc.a and libgc.so in /usr/local/bin, which 56 | would typically require the "make install" to be run as root. 57 | 58 | It is not recommended to turn off parallel marking for multiprocessors unless 59 | a poor support of the feature on the platform. 60 | -------------------------------------------------------------------------------- /gc_cpp.cc: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1994 by Xerox Corporation. All rights reserved. 3 | * 4 | * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED 5 | * OR IMPLIED. ANY USE IS AT YOUR OWN RISK. 6 | * 7 | * Permission is hereby granted to copy this code for any purpose, 8 | * provided the above notices are retained on all copies. 9 | */ 10 | 11 | /************************************************************************* 12 | This implementation module for gc_c++.h provides an implementation of 13 | the global operators "new" and "delete" that calls the Boehm 14 | allocator. All objects allocated by this implementation will be 15 | uncollectible but part of the root set of the collector. 16 | 17 | You should ensure (using implementation-dependent techniques) that the 18 | linker finds this module before the library that defines the default 19 | built-in "new" and "delete". 20 | **************************************************************************/ 21 | 22 | #ifdef HAVE_CONFIG_H 23 | # include "config.h" 24 | #endif 25 | 26 | #ifndef GC_BUILD 27 | # define GC_BUILD 28 | #endif 29 | 30 | #include "gc_cpp.h" 31 | 32 | #if GC_GNUC_PREREQ(4, 2) && !defined(GC_NEW_DELETE_NEED_THROW) 33 | # define GC_NEW_DELETE_NEED_THROW 34 | #endif 35 | 36 | #ifdef GC_NEW_DELETE_NEED_THROW 37 | # include /* for std::bad_alloc */ 38 | # define GC_DECL_NEW_THROW throw(std::bad_alloc) 39 | # define GC_DECL_DELETE_THROW throw() 40 | #else 41 | # define GC_DECL_NEW_THROW /* empty */ 42 | # define GC_DECL_DELETE_THROW /* empty */ 43 | #endif // !GC_NEW_DELETE_NEED_THROW 44 | 45 | #ifndef _MSC_VER 46 | 47 | void* operator new(size_t size) GC_DECL_NEW_THROW { 48 | return GC_MALLOC_UNCOLLECTABLE(size); 49 | } 50 | 51 | void operator delete(void* obj) GC_DECL_DELETE_THROW { 52 | GC_FREE(obj); 53 | } 54 | 55 | # if defined(GC_OPERATOR_NEW_ARRAY) && !defined(CPPCHECK) 56 | void* operator new[](size_t size) GC_DECL_NEW_THROW { 57 | return GC_MALLOC_UNCOLLECTABLE(size); 58 | } 59 | 60 | void operator delete[](void* obj) GC_DECL_DELETE_THROW { 61 | GC_FREE(obj); 62 | } 63 | # endif // GC_OPERATOR_NEW_ARRAY 64 | 65 | # if __cplusplus > 201103L // C++14 66 | void operator delete(void* obj, size_t size) GC_DECL_DELETE_THROW { 67 | (void)size; // size is ignored 68 | GC_FREE(obj); 69 | } 70 | 71 | # if defined(GC_OPERATOR_NEW_ARRAY) && !defined(CPPCHECK) 72 | void operator delete[](void* obj, size_t size) GC_DECL_DELETE_THROW { 73 | (void)size; 74 | GC_FREE(obj); 75 | } 76 | # endif 77 | # endif // C++14 78 | 79 | #endif // !_MSC_VER 80 | -------------------------------------------------------------------------------- /include/gc_vector.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 1988, 1989 Hans-J. Boehm, Alan J. Demers 3 | * Copyright (c) 1991-1995 by Xerox Corporation. All rights reserved. 4 | * Copyright 1996-1999 by Silicon Graphics. All rights reserved. 5 | * Copyright 1999 by Hewlett-Packard Company. All rights reserved. 6 | * 7 | * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED 8 | * OR IMPLIED. ANY USE IS AT YOUR OWN RISK. 9 | * 10 | * Permission is hereby granted to use or copy this program 11 | * for any purpose, provided the above notices are retained on all copies. 12 | * Permission to modify the code and to distribute modified code is granted, 13 | * provided the above notices are retained, and a notice that the code was 14 | * modified is included with the above copyright notice. 15 | */ 16 | 17 | /* This file assumes the collector has been compiled with GC_GCJ_SUPPORT. */ 18 | 19 | /* 20 | * We allocate objects whose first word contains a pointer to a struct 21 | * describing the object type. This struct contains a garbage collector mark 22 | * descriptor at offset MARK_DESCR_OFFSET. Alternatively, the objects 23 | * may be marked by the mark procedure passed to GC_init_gcj_malloc. 24 | */ 25 | 26 | #ifndef GC_VECTOR_H 27 | #define GC_VECTOR_H 28 | 29 | /* Gcj keeps GC descriptor as second word of vtable. This */ 30 | /* probably needs to be adjusted for other clients. */ 31 | /* We currently assume that this offset is such that: */ 32 | /* - all objects of this kind are large enough to have */ 33 | /* a value at that offset, and */ 34 | /* - it is not zero. */ 35 | /* These assumptions allow objects on the free list to be */ 36 | /* marked normally. */ 37 | 38 | #ifndef GC_H 39 | # include "gc.h" 40 | #endif 41 | 42 | # include "gc_typed.h" 43 | 44 | #ifdef __cplusplus 45 | extern "C" { 46 | #endif 47 | 48 | GC_API void GC_CALL GC_init_gcj_vector (int /* mp_index */, 49 | void * /* really mark_proc */ /* mp */); 50 | 51 | GC_API GC_ATTR_MALLOC void * GC_CALL GC_gcj_vector_malloc(size_t /* lb */, 52 | void * /* ptr_to_struct_containing_descr */); 53 | 54 | GC_API struct GC_ms_entry *GC_CALL 55 | GC_gcj_vector_mark_proc (struct GC_ms_entry *mark_stack_ptr, 56 | struct GC_ms_entry* mark_stack_limit, 57 | GC_descr element_desc, 58 | GC_word*start, 59 | GC_word*end, 60 | int words_per_element); 61 | 62 | #ifdef __cplusplus 63 | } /* extern "C" */ 64 | #endif 65 | 66 | #endif /* GC_VECTOR_H */ 67 | -------------------------------------------------------------------------------- /BCC_MAKEFILE: -------------------------------------------------------------------------------- 1 | # Makefile for Borland C++ 5.5 on NT 2 | # 3 | bc= c:\Borland\BCC55 4 | bcbin= $(bc)\bin 5 | bclib= $(bc)\lib 6 | bcinclude= $(bc)\include 7 | 8 | gcinclude1 = $(bc)\gc6.2\include 9 | gcinclude2 = $(bc)\gc6.2\cord 10 | 11 | cc= $(bcbin)\bcc32 12 | rc= $(bcbin)\brc32 13 | lib= $(bcbin)\tlib 14 | link= $(bcbin)\ilink32 15 | cflags= -O2 -R -v- -vi -H -H=gc.csm -I$(bcinclude);$(gcinclude1);$(gcinclude2) -L$(bclib) \ 16 | -w-pro -w-aus -w-par -w-ccc -w-rch -a4 17 | defines= -DALL_INTERIOR_POINTERS -DNO_GETENV -DJAVA_FINALIZATION -DENABLE_DISCLAIM -DGC_OPERATOR_NEW_ARRAY 18 | 19 | .c.obj: 20 | $(cc) @&&| 21 | $(cdebug) $(cflags) $(cvars) $(defines) -o$* -c $*.c 22 | | 23 | 24 | .cpp.obj: 25 | $(cc) @&&| 26 | $(cdebug) $(cflags) $(cvars) $(defines) -o$* -c $*.cpp 27 | | 28 | 29 | .rc.res: 30 | $(rc) -i$(bcinclude) -r -fo$* $*.rc 31 | 32 | XXXOBJS= XXXalloc.obj XXXreclaim.obj XXXallchblk.obj XXXmisc.obj \ 33 | XXXmach_dep.obj XXXos_dep.obj XXXmark_rts.obj XXXheaders.obj XXXmark.obj \ 34 | XXXobj_map.obj XXXblacklst.obj XXXfinalize.obj XXXnew_hblk.obj \ 35 | XXXdbg_mlc.obj XXXmalloc.obj XXXdyn_load.obj \ 36 | XXXtypd_mlc.obj XXXptr_chck.obj XXXgc_cpp.obj XXXmallocx.obj \ 37 | XXXfnlz_mlc.obj 38 | 39 | OBJS= $(XXXOBJS:XXX=) 40 | 41 | all: gctest.exe cord\de.exe test_cpp.exe 42 | 43 | $(OBJS) test.obj: include\private\gc_priv.h include\private\gc_hdrs.h include\gc.h include\private\gcconfig.h MAKEFILE 44 | 45 | gc.lib: $(OBJS) 46 | del gc.lib 47 | $(lib) $* @&&| 48 | $(XXXOBJS:XXX=+) 49 | | 50 | 51 | gctest.exe: tests\test.obj gc.lib 52 | $(cc) @&&| 53 | $(cflags) -W -e$* tests\test.obj gc.lib 54 | | 55 | 56 | cord\tests\de.obj cord\tests\de_win.obj: include\cord.h \ 57 | include\cord_pos.h cord\tests\de_win.h cord\tests\de_cmds.h 58 | 59 | cord\de.exe: cord\cordbscs.obj cord\cordxtra.obj cord\tests\de.obj \ 60 | cord\tests\de_win.obj cord\tests\de_win.res gc.lib 61 | $(cc) @&&| 62 | $(cflags) -W -e$* cord\cordbscs.obj cord\cordxtra.obj \ 63 | cord\tests\de.obj cord\tests\de_win.obj gc.lib 64 | | 65 | $(rc) cord\tests\de_win.res cord\de.exe 66 | 67 | gc_cpp.obj: include\gc_cpp.h include\gc.h 68 | 69 | gc_cpp.cpp: gc_cpp.cc 70 | copy gc_cpp.cc gc_cpp.cpp 71 | 72 | test_cpp.cpp: tests\test_cpp.cc 73 | copy tests\test_cpp.cc test_cpp.cpp 74 | 75 | test_cpp.exe: test_cpp.obj include\gc_cpp.h include\gc.h gc.lib 76 | $(cc) @&&| 77 | $(cflags) -W -e$* test_cpp.obj gc.lib 78 | | 79 | 80 | scratch: 81 | -del *.obj *.res *.exe *.csm cord\*.obj cord\*.res cord\*.exe cord\*.csm 82 | 83 | clean: 84 | del gc.lib 85 | del *.obj 86 | del tests\test.obj 87 | -------------------------------------------------------------------------------- /include/javaxfc.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1994 by Xerox Corporation. All rights reserved. 3 | * Copyright (c) 1996 by Silicon Graphics. All rights reserved. 4 | * Copyright (c) 1998 by Fergus Henderson. All rights reserved. 5 | * Copyright (c) 2000-2009 by Hewlett-Packard Development Company. 6 | * All rights reserved. 7 | * 8 | * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED 9 | * OR IMPLIED. ANY USE IS AT YOUR OWN RISK. 10 | * 11 | * Permission is hereby granted to use or copy this program 12 | * for any purpose, provided the above notices are retained on all copies. 13 | * Permission to modify the code and to distribute modified code is granted, 14 | * provided the above notices are retained, and a notice that the code was 15 | * modified is included with the above copyright notice. 16 | */ 17 | 18 | #ifndef GC_H 19 | # include "gc.h" 20 | #endif 21 | 22 | #ifdef __cplusplus 23 | extern "C" { 24 | #endif 25 | 26 | /* 27 | * Invoke all remaining finalizers that haven't yet been run. (Since the 28 | * notifier is not called, this should be called from a separate thread.) 29 | * This function is needed for strict compliance with the Java standard, 30 | * which can make the runtime guarantee that all finalizers are run. 31 | * This is problematic for several reasons: 32 | * 1) It means that finalizers, and all methods called by them, 33 | * must be prepared to deal with objects that have been finalized in 34 | * spite of the fact that they are still referenced by statically 35 | * allocated pointer variables. 36 | * 2) It may mean that we get stuck in an infinite loop running 37 | * finalizers which create new finalizable objects, though that's 38 | * probably unlikely. 39 | * Thus this is not recommended for general use. 40 | */ 41 | GC_API void GC_CALL GC_finalize_all(void); 42 | 43 | #ifdef GC_THREADS 44 | /* External thread suspension support. No thread suspension count */ 45 | /* (so a thread which has been suspended numerous times will be */ 46 | /* resumed with the very first call to GC_resume_thread). */ 47 | /* Acquire the allocation lock. Thread should be registered in GC */ 48 | /* (otherwise no-op, GC_is_thread_suspended returns false). */ 49 | /* Unimplemented on some platforms. Not recommended for general use. */ 50 | # ifndef GC_SUSPEND_THREAD_ID 51 | # define GC_SUSPEND_THREAD_ID void* 52 | # endif 53 | GC_API void GC_CALL GC_suspend_thread(GC_SUSPEND_THREAD_ID); 54 | GC_API void GC_CALL GC_resume_thread(GC_SUSPEND_THREAD_ID); 55 | GC_API int GC_CALL GC_is_thread_suspended(GC_SUSPEND_THREAD_ID); 56 | #endif /* GC_THREADS */ 57 | 58 | #ifdef __cplusplus 59 | } /* extern "C" */ 60 | #endif 61 | -------------------------------------------------------------------------------- /extra/krait_signal_handler.c: -------------------------------------------------------------------------------- 1 | #if defined(__ANDROID__) 2 | 3 | #include 4 | 5 | extern int __real_sigaction(int signum, const struct sigaction *action, struct sigaction *old_action); 6 | 7 | // Workaround a bug on Krait CPUs where a signal handler would not properly transition from thumb to non-thumb. 8 | // Note: The workaround has a flaw if multiple signal handlers are used, then the last sigaction call overwrites wrapped_signal_handlers value. 9 | // Since it's only needed for ARM 32 bit, don't perform this workaround on other architectures 10 | // Note: Previously this workaround (when used for all CPU architectures) caused a test failure in unity repo: 11 | // - Tests\Unity.IntegrationTests\Android\AndroidCrashHandler.cs 12 | // Since the test was using multiple signal handlers to validate that handlers are correcty invoked when registered before and after Unity runtime initialization 13 | #if defined(__arm__) 14 | #define SIGMAX 64 15 | static void (*wrapped_signal_handlers[SIGMAX]) (int, siginfo_t *, void *); 16 | 17 | static void signal_handler(int signum, siginfo_t* siginfo, void* sigcontext) 18 | { 19 | if (wrapped_signal_handlers[signum]) 20 | wrapped_signal_handlers[signum](signum, siginfo, sigcontext); 21 | } 22 | 23 | __attribute__((used)) int __wrap_sigaction(int signum, const struct sigaction *action, struct sigaction *old_action) 24 | { 25 | struct sigaction wrapper_action_data; 26 | struct sigaction* wrapper_action = NULL; 27 | 28 | if (signum >= SIGMAX) 29 | return __real_sigaction(signum, action, old_action); 30 | 31 | // patch sig action with our thumb compiled dispatcher 32 | if (action) 33 | { 34 | wrapper_action = &wrapper_action_data; 35 | memcpy(wrapper_action, action, sizeof(*action)); 36 | wrapper_action->sa_sigaction = signal_handler; 37 | 38 | } 39 | 40 | // install handler (abort on error) 41 | if (__real_sigaction(signum, wrapper_action, old_action) == -1) 42 | return -1; 43 | 44 | // hide any previously installed wrapper 45 | if (old_action && old_action->sa_sigaction == signal_handler) 46 | old_action->sa_sigaction = wrapped_signal_handlers[signum]; 47 | 48 | // add action to dispatch table 49 | if (action) 50 | wrapped_signal_handlers[signum] = action->sa_sigaction; 51 | 52 | return 0; 53 | } 54 | 55 | #undef SIGMAX 56 | #else 57 | __attribute__((used)) int __wrap_sigaction(int signum, const struct sigaction *action, struct sigaction *old_action) 58 | { 59 | return __real_sigaction(signum, action, old_action); 60 | } 61 | #endif 62 | 63 | #endif /* __ANDROID__ */ -------------------------------------------------------------------------------- /windows-untested/gc.ver: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include "../include/gc_version.h" 5 | 6 | #define GC_VERSION_REVISION 0 7 | 8 | #define GC_VERSION ((GC_VERSION_MAJOR) * 100 + GC_VERSION_MINOR) 9 | #define GC_FULL_VERSION ((GC_VERSION) * 10000 + GC_VERSION_MICRO) 10 | 11 | #ifndef __T 12 | # ifdef UNICODE 13 | # define __T(x) L ## x 14 | # else 15 | # define __T(x) x 16 | # endif 17 | #endif 18 | 19 | #define PP_TSTR(x) __T(#x) 20 | #define PP_EVAL_TSTR(x) PP_TSTR(x) 21 | 22 | #define GC_VERSION_STR PP_EVAL_TSTR(GC_VERSION_MAJOR) __T(".") PP_EVAL_TSTR(GC_VERSION_MINOR) 23 | #define GC_FULL_VERSION_STR PP_EVAL_TSTR(GC_VERSION_MAJOR) __T(".") PP_EVAL_TSTR(GC_VERSION_MINOR) __T(".") PP_EVAL_TSTR(GC_VERSION_MICRO) __T(".") PP_EVAL_TSTR(GC_VERSION_REVISION) 24 | #define GC_FULL_VERSION_CSV GC_VERSION_MAJOR, GC_VERSION_MINOR, GC_VERSION_MICRO, GC_VERSION_REVISION 25 | 26 | #ifdef _DEBUG 27 | #define VER_DEBUG VS_FF_DEBUG 28 | #else 29 | #define VER_DEBUG 0 30 | #endif 31 | 32 | #ifdef _BETA 33 | #define VER_PRERELEASE VS_FF_PRERELEASE 34 | #else 35 | #define VER_PRERELEASE 0 36 | #endif 37 | 38 | LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US 39 | #pragma code_page(1252) 40 | 41 | VS_VERSION_INFO VERSIONINFO 42 | FILEVERSION GC_FULL_VERSION_CSV 43 | PRODUCTVERSION GC_FULL_VERSION_CSV 44 | FILEFLAGSMASK VS_FFI_FILEFLAGSMASK 45 | FILEFLAGS VER_DEBUG | VER_PRERELEASE 46 | FILEOS VOS__WINDOWS32 47 | FILETYPE VFT_DLL 48 | FILESUBTYPE VFT2_UNKNOWN 49 | BEGIN 50 | BLOCK "StringFileInfo" 51 | BEGIN 52 | BLOCK "040904B0" 53 | BEGIN 54 | VALUE "CompanyName", "\ 55 | Hans-J. Boehm, \ 56 | Alan J. Demers, \ 57 | Xerox Corporation, \ 58 | Silicon Graphics, \ 59 | and Hewlett-Packard Company. \ 60 | \0" 61 | VALUE "LegalCopyright", "\ 62 | Copyright 1988, 1989 Hans-J. Boehm, Alan J. Demers. \ 63 | Copyright (c) 1991-1995 by Xerox Corporation. All rights reserved. \ 64 | Copyright (c) 1996-1999 by Silicon Graphics. All rights reserved. \ 65 | Copyright (c) 1999-2004 by Hewlett-Packard. All rights reserved. \ 66 | \0" 67 | 68 | VALUE "OriginalFilename", "GC.DLL\0" 69 | VALUE "InternalName", "GC\0" 70 | VALUE "FileDescription", "Conservative Garbage Collector for C and C++\0" 71 | VALUE "FileVersion", GC_FULL_VERSION_STR 72 | 73 | VALUE "ProductName", "Conservative Garbage Collector for C and C++\0" 74 | VALUE "ProductVersion", GC_FULL_VERSION_STR 75 | END 76 | END 77 | BLOCK "VarFileInfo" 78 | BEGIN 79 | VALUE "Translation", 0x409, 1200 80 | END 81 | END 82 | -------------------------------------------------------------------------------- /heapsections.c: -------------------------------------------------------------------------------- 1 | #include "private/gc_priv.h" 2 | 3 | void GC_foreach_heap_section(void* user_data, GC_heap_section_proc callback) 4 | { 5 | GC_ASSERT(I_HOLD_LOCK()); 6 | 7 | if (callback == NULL) 8 | return; 9 | 10 | // GC memory is organized in heap sections, which are split in heap blocks. 11 | // Each block has header (can get via HDR(ptr)) and it's size is aligned to HBLKSIZE 12 | // Block headers are kept separately from memory their points to, and quickly address 13 | // headers GC maintains 2-level cache structure which uses address as a hash key. 14 | for (unsigned i = 0; i < GC_n_heap_sects; i++) 15 | { 16 | ptr_t sectionStart = GC_heap_sects[i].hs_start; 17 | ptr_t sectionEnd = sectionStart + GC_heap_sects[i].hs_bytes; 18 | 19 | // Merge in contiguous sections. 20 | // A heap block might start in one heap section and extend 21 | // into the next one. 22 | while (i + 1 < GC_n_heap_sects && GC_heap_sects[i + 1].hs_start == sectionEnd) 23 | { 24 | ++i; 25 | sectionEnd = GC_heap_sects[i].hs_start + GC_heap_sects[i].hs_bytes; 26 | } 27 | 28 | ptr_t blockStart = sectionStart; 29 | while (blockStart < sectionEnd) 30 | { 31 | // This does lookup into 2 level tree data structure, 32 | // which uses address as hash key to find block header. 33 | hdr* hhdr = HDR(blockStart); 34 | 35 | if (IS_FORWARDING_ADDR_OR_NIL(hhdr)) 36 | { 37 | // This pointer has no header registered in headers cache. 38 | // We skip one HBLKSIZE and attempt to get header for it. 39 | // We don't report it, as we don't know is mapped or not. 40 | blockStart = blockStart + HBLKSIZE; 41 | } 42 | else if (HBLK_IS_FREE(hhdr)) 43 | { 44 | // We have a header, and the block is marked as free. 45 | // Note: for "free" blocks "hb_sz" = the size in bytes of the whole block. 46 | ptr_t blockEnd = blockStart + hhdr->hb_sz; 47 | 48 | #if USE_MUNMAP 49 | // Only report free block if it's mapped. 50 | if ((hhdr->hb_flags & WAS_UNMAPPED) != 0) 51 | { 52 | blockStart = blockEnd; 53 | continue; 54 | } 55 | #endif 56 | callback(user_data, blockStart, blockEnd, GC_HEAP_SECTION_TYPE_FREE); 57 | 58 | blockStart = blockEnd; 59 | } 60 | else 61 | { 62 | // This heap block is used, report it. 63 | // Note: for used blocks "hb_sz" = size in bytes, of objects in the block. 64 | ptr_t blockEnd = blockStart + HBLKSIZE * OBJ_SZ_TO_BLOCKS(hhdr->hb_sz); 65 | ptr_t usedBlocknEnd = blockStart + hhdr->hb_sz; 66 | 67 | if (usedBlocknEnd > blockStart) 68 | callback(user_data, blockStart, usedBlocknEnd, GC_HEAP_SECTION_TYPE_USED); 69 | if (blockEnd > usedBlocknEnd) 70 | callback(user_data, usedBlocknEnd, blockEnd, GC_HEAP_SECTION_TYPE_PADDING); 71 | 72 | blockStart = blockEnd; 73 | } 74 | } 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /include/private/darwin_semaphore.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1994 by Xerox Corporation. All rights reserved. 3 | * Copyright (c) 1996 by Silicon Graphics. All rights reserved. 4 | * Copyright (c) 1998 by Fergus Henderson. All rights reserved. 5 | * Copyright (c) 2000-2009 by Hewlett-Packard Development Company. 6 | * All rights reserved. 7 | * 8 | * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED 9 | * OR IMPLIED. ANY USE IS AT YOUR OWN RISK. 10 | * 11 | * Permission is hereby granted to use or copy this program 12 | * for any purpose, provided the above notices are retained on all copies. 13 | * Permission to modify the code and to distribute modified code is granted, 14 | * provided the above notices are retained, and a notice that the code was 15 | * modified is included with the above copyright notice. 16 | */ 17 | 18 | #ifndef GC_DARWIN_SEMAPHORE_H 19 | #define GC_DARWIN_SEMAPHORE_H 20 | 21 | #if !defined(GC_DARWIN_THREADS) 22 | # error darwin_semaphore.h included with GC_DARWIN_THREADS not defined 23 | #endif 24 | 25 | #ifdef __cplusplus 26 | extern "C" { 27 | #endif 28 | 29 | /* This is a very simple semaphore implementation for Darwin. It is */ 30 | /* implemented in terms of pthread calls so it is not async signal */ 31 | /* safe. But this is not a problem because signals are not used to */ 32 | /* suspend threads on Darwin. */ 33 | 34 | typedef struct { 35 | pthread_mutex_t mutex; 36 | pthread_cond_t cond; 37 | int value; 38 | } sem_t; 39 | 40 | GC_INLINE int sem_init(sem_t *sem, int pshared, int value) { 41 | if (pshared != 0) { 42 | errno = EPERM; /* unsupported */ 43 | return -1; 44 | } 45 | sem->value = value; 46 | if (pthread_mutex_init(&sem->mutex, NULL) != 0) 47 | return -1; 48 | if (pthread_cond_init(&sem->cond, NULL) != 0) { 49 | (void)pthread_mutex_destroy(&sem->mutex); 50 | return -1; 51 | } 52 | return 0; 53 | } 54 | 55 | GC_INLINE int sem_post(sem_t *sem) { 56 | if (pthread_mutex_lock(&sem->mutex) != 0) 57 | return -1; 58 | sem->value++; 59 | if (pthread_cond_signal(&sem->cond) != 0) { 60 | (void)pthread_mutex_unlock(&sem->mutex); 61 | return -1; 62 | } 63 | return pthread_mutex_unlock(&sem->mutex) != 0 ? -1 : 0; 64 | } 65 | 66 | GC_INLINE int sem_wait(sem_t *sem) { 67 | if (pthread_mutex_lock(&sem->mutex) != 0) 68 | return -1; 69 | while (sem->value == 0) { 70 | if (pthread_cond_wait(&sem->cond, &sem->mutex) != 0) { 71 | (void)pthread_mutex_unlock(&sem->mutex); 72 | return -1; 73 | } 74 | } 75 | sem->value--; 76 | return pthread_mutex_unlock(&sem->mutex) != 0 ? -1 : 0; 77 | } 78 | 79 | GC_INLINE int sem_destroy(sem_t *sem) { 80 | return pthread_cond_destroy(&sem->cond) != 0 81 | || pthread_mutex_destroy(&sem->mutex) != 0 ? -1 : 0; 82 | } 83 | 84 | #ifdef __cplusplus 85 | } /* extern "C" */ 86 | #endif 87 | 88 | #endif 89 | -------------------------------------------------------------------------------- /tests/test_atomic_ops.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017 Ivan Maidanski 3 | * 4 | * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED 5 | * OR IMPLIED. ANY USE IS AT YOUR OWN RISK. 6 | * 7 | * Permission is hereby granted to use or copy this program 8 | * for any purpose, provided the above notices are retained on all copies. 9 | * Permission to modify the code and to distribute modified code is granted, 10 | * provided the above notices are retained, and a notice that the code was 11 | * modified is included with the above copyright notice. 12 | */ 13 | 14 | /* Minimal testing of atomic operations used by the BDWGC. Primary use */ 15 | /* is to determine whether compiler atomic intrinsics can be relied on. */ 16 | 17 | #ifdef HAVE_CONFIG_H 18 | # include "config.h" 19 | #endif 20 | 21 | #include 22 | 23 | #if defined(GC_BUILTIN_ATOMIC) || defined(GC_THREADS) 24 | 25 | # include 26 | 27 | # ifdef PARALLEL_MARK 28 | # define AO_REQUIRE_CAS 29 | # endif 30 | 31 | # include "private/gc_atomic_ops.h" 32 | 33 | # define TA_assert(e) \ 34 | if (!(e)) { \ 35 | fprintf(stderr, "Assertion failure, line %d: " #e "\n", __LINE__); \ 36 | exit(-1); \ 37 | } 38 | 39 | int main(void) { 40 | AO_t x = 13; 41 | # if defined(AO_HAVE_char_load) || defined(AO_HAVE_char_store) 42 | unsigned char c = 117; 43 | # endif 44 | # ifdef AO_HAVE_test_and_set_acquire 45 | AO_TS_t z = AO_TS_INITIALIZER; 46 | 47 | TA_assert(AO_test_and_set_acquire(&z) == AO_TS_CLEAR); 48 | TA_assert(AO_test_and_set_acquire(&z) == AO_TS_SET); 49 | AO_CLEAR(&z); 50 | # endif 51 | AO_compiler_barrier(); 52 | # ifdef AO_HAVE_nop_full 53 | AO_nop_full(); 54 | # endif 55 | # ifdef AO_HAVE_char_load 56 | TA_assert(AO_char_load(&c) == 117); 57 | # endif 58 | # ifdef AO_HAVE_char_store 59 | AO_char_store(&c, 119); 60 | TA_assert(c == 119); 61 | # endif 62 | # ifdef AO_HAVE_load_acquire 63 | TA_assert(AO_load_acquire(&x) == 13); 64 | # endif 65 | # if defined(AO_HAVE_fetch_and_add) && defined(AO_HAVE_fetch_and_add1) 66 | TA_assert(AO_fetch_and_add(&x, 42) == 13); 67 | TA_assert(AO_fetch_and_add(&x, (AO_t)(-43)) == 55); 68 | TA_assert(AO_fetch_and_add1(&x) == 12); 69 | # endif 70 | # ifdef AO_HAVE_compare_and_swap_release 71 | TA_assert(!AO_compare_and_swap(&x, 14, 42)); 72 | TA_assert(x == 13); 73 | TA_assert(AO_compare_and_swap_release(&x, 13, 42)); 74 | TA_assert(x == 42); 75 | # else 76 | if (*(volatile AO_t *)&x == 13) 77 | *(volatile AO_t *)&x = 42; 78 | # endif 79 | # ifdef AO_HAVE_or 80 | AO_or(&x, 66); 81 | TA_assert(x == 106); 82 | # endif 83 | # ifdef AO_HAVE_store_release 84 | AO_store_release(&x, 113); 85 | TA_assert(x == 113); 86 | # endif 87 | return 0; 88 | } 89 | 90 | #else 91 | 92 | int main(void) 93 | { 94 | printf("test_atomic_ops skipped\n"); 95 | return 0; 96 | } 97 | 98 | #endif 99 | -------------------------------------------------------------------------------- /include/gc_disclaim.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2007-2011 by Hewlett-Packard Company. All rights reserved. 3 | * 4 | * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED 5 | * OR IMPLIED. ANY USE IS AT YOUR OWN RISK. 6 | * 7 | * Permission is hereby granted to use or copy this program 8 | * for any purpose, provided the above notices are retained on all copies. 9 | * Permission to modify the code and to distribute modified code is granted, 10 | * provided the above notices are retained, and a notice that the code was 11 | * modified is included with the above copyright notice. 12 | * 13 | */ 14 | 15 | #ifndef GC_DISCLAIM_H 16 | #define GC_DISCLAIM_H 17 | 18 | #include "gc.h" 19 | 20 | #ifdef __cplusplus 21 | extern "C" { 22 | #endif 23 | 24 | /* This API is defined only if the library has been suitably compiled */ 25 | /* (i.e. with ENABLE_DISCLAIM defined). */ 26 | 27 | /* Prepare the object kind used by GC_finalized_malloc. Call it from */ 28 | /* your initialization code or, at least, at some point before using */ 29 | /* finalized allocations. The function is thread-safe. */ 30 | GC_API void GC_CALL GC_init_finalized_malloc(void); 31 | 32 | /* Type of a disclaim call-back. */ 33 | typedef int (GC_CALLBACK * GC_disclaim_proc)(void * /*obj*/); 34 | 35 | /* Register "proc" to be called on each object of "kind" ready to be */ 36 | /* reclaimed. If "proc" returns non-zero, the collector will not */ 37 | /* reclaim the object on this GC cycle. Objects reachable from "proc" */ 38 | /* will be protected from collection if "mark_from_all" is non-zero, */ 39 | /* but at the expense that long chains of objects will take many cycles */ 40 | /* to reclaim. */ 41 | GC_API void GC_CALL GC_register_disclaim_proc(int /*kind*/, 42 | GC_disclaim_proc /*proc*/, 43 | int /*mark_from_all*/); 44 | 45 | /* The finalizer closure used by GC_finalized_malloc. */ 46 | struct GC_finalizer_closure { 47 | GC_finalization_proc proc; 48 | void *cd; 49 | }; 50 | 51 | /* Allocate "size" bytes which is finalized by "fc". This uses a */ 52 | /* dedicated object kind with a disclaim procedure, and is more */ 53 | /* efficient than GC_register_finalizer and friends. */ 54 | /* GC_init_finalized_malloc must be called before using this. */ 55 | /* Note that GC_size (applied to such allocated object) returns a value */ 56 | /* slightly bigger than the specified allocation size, and that GC_base */ 57 | /* result points to a word prior to the start of the allocated object. */ 58 | GC_API GC_ATTR_MALLOC GC_ATTR_ALLOC_SIZE(1) void * GC_CALL 59 | GC_finalized_malloc(size_t /*size*/, 60 | const struct GC_finalizer_closure * /*fc*/); 61 | 62 | #ifdef __cplusplus 63 | } /* extern "C" */ 64 | #endif 65 | 66 | #endif 67 | -------------------------------------------------------------------------------- /tools/threadlibs.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1994 by Xerox Corporation. All rights reserved. 3 | * Copyright (c) 1996 by Silicon Graphics. All rights reserved. 4 | * Copyright (c) 1998 by Fergus Henderson. All rights reserved. 5 | * Copyright (c) 2000-2010 by Hewlett-Packard Development Company. 6 | * All rights reserved. 7 | * 8 | * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED 9 | * OR IMPLIED. ANY USE IS AT YOUR OWN RISK. 10 | * 11 | * Permission is hereby granted to use or copy this program 12 | * for any purpose, provided the above notices are retained on all copies. 13 | * Permission to modify the code and to distribute modified code is granted, 14 | * provided the above notices are retained, and a notice that the code was 15 | * modified is included with the above copyright notice. 16 | */ 17 | 18 | # include "private/gc_priv.h" 19 | 20 | # include 21 | 22 | int main(void) 23 | { 24 | # if defined(GC_USE_LD_WRAP) 25 | printf("-Wl,--wrap -Wl,dlopen " 26 | "-Wl,--wrap -Wl,pthread_create -Wl,--wrap -Wl,pthread_join " 27 | "-Wl,--wrap -Wl,pthread_detach -Wl,--wrap -Wl,pthread_sigmask " 28 | "-Wl,--wrap -Wl,pthread_exit -Wl,--wrap -Wl,pthread_cancel\n"); 29 | # endif 30 | # if (defined(GC_LINUX_THREADS) && !defined(HOST_ANDROID)) \ 31 | || defined(GC_IRIX_THREADS) || defined(GC_DARWIN_THREADS) \ 32 | || defined(GC_AIX_THREADS) || (defined(HURD) && defined(GC_THREADS)) 33 | # ifdef GC_USE_DLOPEN_WRAP 34 | printf("-ldl "); 35 | # endif 36 | printf("-lpthread\n"); 37 | # endif 38 | # if defined(GC_OPENBSD_THREADS) 39 | printf("-pthread\n"); 40 | # endif 41 | # if defined(GC_FREEBSD_THREADS) 42 | # ifdef GC_USE_DLOPEN_WRAP 43 | printf("-ldl "); 44 | # endif 45 | # if (__FREEBSD_version < 500000) 46 | printf("-pthread\n"); 47 | # else /* __FREEBSD__ || __DragonFly__ */ 48 | printf("-lpthread\n"); 49 | # endif 50 | # endif 51 | # if defined(GC_NETBSD_THREADS) 52 | printf("-lpthread -lrt\n"); 53 | # endif 54 | 55 | # if defined(GC_HPUX_THREADS) || defined(GC_OSF1_THREADS) 56 | printf("-lpthread -lrt\n"); 57 | # endif 58 | # if defined(GC_SOLARIS_THREADS) 59 | printf("-lthread -lposix4\n"); 60 | /* Is this right for recent versions? */ 61 | # endif 62 | # if defined(GC_WIN32_THREADS) && defined(CYGWIN32) 63 | printf("-lpthread\n"); 64 | # endif 65 | # if defined(GC_WIN32_PTHREADS) 66 | # ifdef PTW32_STATIC_LIB 67 | /* assume suffix s for static version of the win32 pthread library */ 68 | printf("-lpthreadGC2s -lws2_32\n"); 69 | # else 70 | printf("-lpthreadGC2\n"); 71 | # endif 72 | # endif 73 | # if defined(GC_OSF1_THREADS) 74 | printf("-pthread -lrt\n"); /* DOB: must be -pthread, not -lpthread */ 75 | # endif 76 | /* You need GCC 3.0.3 to build this one! */ 77 | /* DG/UX native gcc doesn't know what "-pthread" is */ 78 | # if defined(GC_DGUX386_THREADS) 79 | printf("-ldl -pthread\n"); 80 | # endif 81 | return 0; 82 | } 83 | -------------------------------------------------------------------------------- /include/private/msvc_dbg.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2004-2005 Andrei Polushin 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy 5 | of this software and associated documentation files (the "Software"), to deal 6 | in the Software without restriction, including without limitation the rights 7 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | copies of the Software, and to permit persons to whom the Software is 9 | furnished to do so, subject to the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included in 12 | all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 | THE SOFTWARE. 21 | */ 22 | 23 | #ifndef GC_MSVC_DBG_H 24 | #define GC_MSVC_DBG_H 25 | 26 | #include 27 | 28 | #ifdef __cplusplus 29 | extern "C" { 30 | #endif 31 | 32 | #if !MSVC_DBG_DLL 33 | #define MSVC_DBG_EXPORT 34 | #elif MSVC_DBG_BUILD 35 | #define MSVC_DBG_EXPORT __declspec(dllexport) 36 | #else 37 | #define MSVC_DBG_EXPORT __declspec(dllimport) 38 | #endif 39 | 40 | #ifndef MAX_SYM_NAME 41 | #define MAX_SYM_NAME 2000 42 | #endif 43 | 44 | typedef void* HANDLE; 45 | typedef struct _CONTEXT CONTEXT; 46 | 47 | MSVC_DBG_EXPORT size_t GetStackFrames(size_t skip, void* frames[], size_t maxFrames); 48 | MSVC_DBG_EXPORT size_t GetStackFramesFromContext(HANDLE hProcess, HANDLE hThread, CONTEXT* context, size_t skip, void* frames[], size_t maxFrames); 49 | 50 | MSVC_DBG_EXPORT size_t GetModuleNameFromAddress(void* address, char* moduleName, size_t size); 51 | MSVC_DBG_EXPORT size_t GetModuleNameFromStack(size_t skip, char* moduleName, size_t size); 52 | 53 | MSVC_DBG_EXPORT size_t GetSymbolNameFromAddress(void* address, char* symbolName, size_t size, size_t* offsetBytes); 54 | MSVC_DBG_EXPORT size_t GetSymbolNameFromStack(size_t skip, char* symbolName, size_t size, size_t* offsetBytes); 55 | 56 | MSVC_DBG_EXPORT size_t GetFileLineFromAddress(void* address, char* fileName, size_t size, size_t* lineNumber, size_t* offsetBytes); 57 | MSVC_DBG_EXPORT size_t GetFileLineFromStack(size_t skip, char* fileName, size_t size, size_t* lineNumber, size_t* offsetBytes); 58 | 59 | MSVC_DBG_EXPORT size_t GetDescriptionFromAddress(void* address, const char* format, char* description, size_t size); 60 | MSVC_DBG_EXPORT size_t GetDescriptionFromStack(void*const frames[], size_t count, const char* format, char* description[], size_t size); 61 | 62 | /* Compatibility with */ 63 | MSVC_DBG_EXPORT int backtrace(void* addresses[], int count); 64 | MSVC_DBG_EXPORT char** backtrace_symbols(void*const addresses[], int count); 65 | 66 | #ifdef __cplusplus 67 | } /* extern "C" */ 68 | #endif 69 | 70 | #endif /* GC_MSVC_DBG_H */ 71 | -------------------------------------------------------------------------------- /tests/threadkey_test.c: -------------------------------------------------------------------------------- 1 | 2 | #ifdef HAVE_CONFIG_H 3 | # include "config.h" 4 | #endif 5 | 6 | #ifndef GC_THREADS 7 | # define GC_THREADS 8 | #endif 9 | 10 | #define GC_NO_THREAD_REDIRECTS 1 11 | 12 | #include "gc.h" 13 | 14 | #include 15 | #include 16 | 17 | #if (!defined(GC_PTHREADS) || defined(GC_SOLARIS_THREADS) \ 18 | || defined(__native_client__)) && !defined(SKIP_THREADKEY_TEST) 19 | /* FIXME: Skip this test on Solaris for now. The test may fail on */ 20 | /* other targets as well. Currently, tested only on Linux, Cygwin */ 21 | /* and Darwin. */ 22 | # define SKIP_THREADKEY_TEST 23 | #endif 24 | 25 | #ifdef SKIP_THREADKEY_TEST 26 | 27 | int main (void) 28 | { 29 | printf("threadkey_test skipped\n"); 30 | return 0; 31 | } 32 | 33 | #else 34 | 35 | #include 36 | 37 | pthread_key_t key; 38 | 39 | #ifdef GC_SOLARIS_THREADS 40 | /* pthread_once_t key_once = { PTHREAD_ONCE_INIT }; */ 41 | #else 42 | pthread_once_t key_once = PTHREAD_ONCE_INIT; 43 | #endif 44 | 45 | void * entry (void *arg) 46 | { 47 | pthread_setspecific(key, 48 | (void *)GC_HIDE_POINTER(GC_STRDUP("hello, world"))); 49 | return arg; 50 | } 51 | 52 | void * GC_CALLBACK on_thread_exit_inner (struct GC_stack_base * sb, void * arg) 53 | { 54 | int res = GC_register_my_thread (sb); 55 | pthread_t t; 56 | int creation_res; /* Used to suppress a warning about */ 57 | /* unchecked pthread_create() result. */ 58 | pthread_attr_t attr; 59 | 60 | if (pthread_attr_init(&attr) != 0 61 | || pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED) != 0) { 62 | fprintf(stderr, "Thread attribute init or setdetachstate failed\n"); 63 | exit(2); 64 | } 65 | creation_res = GC_pthread_create(&t, &attr, entry, NULL); 66 | (void)pthread_attr_destroy(&attr); 67 | if (res == GC_SUCCESS) 68 | GC_unregister_my_thread (); 69 | 70 | return arg ? (void*)(GC_word)creation_res : 0; 71 | } 72 | 73 | void on_thread_exit (void *v) 74 | { 75 | GC_call_with_stack_base (on_thread_exit_inner, v); 76 | } 77 | 78 | void make_key (void) 79 | { 80 | pthread_key_create (&key, on_thread_exit); 81 | } 82 | 83 | #ifndef NTHREADS 84 | # define NTHREADS 30 /* number of initial threads */ 85 | #endif 86 | 87 | int main (void) 88 | { 89 | int i; 90 | GC_INIT (); 91 | 92 | # ifdef GC_SOLARIS_THREADS 93 | pthread_key_create (&key, on_thread_exit); 94 | # else 95 | pthread_once (&key_once, make_key); 96 | # endif 97 | for (i = 0; i < NTHREADS; i++) { 98 | pthread_t t; 99 | 100 | if (GC_pthread_create(&t, NULL, entry, NULL) == 0) { 101 | void *res; 102 | int code = (i & 1) != 0 ? GC_pthread_join(t, &res) 103 | : GC_pthread_detach(t); 104 | 105 | if (code != 0) { 106 | fprintf(stderr, "Thread %s failed %d\n", 107 | (i & 1) != 0 ? "join" : "detach", code); 108 | exit(2); 109 | } 110 | } 111 | } 112 | return 0; 113 | } 114 | 115 | #endif /* !SKIP_THREADKEY_TEST */ 116 | -------------------------------------------------------------------------------- /pthread_start.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1994 by Xerox Corporation. All rights reserved. 3 | * Copyright (c) 1996 by Silicon Graphics. All rights reserved. 4 | * Copyright (c) 1998 by Fergus Henderson. All rights reserved. 5 | * Copyright (c) 2000-2010 by Hewlett-Packard Development Company. 6 | * All rights reserved. 7 | * 8 | * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED 9 | * OR IMPLIED. ANY USE IS AT YOUR OWN RISK. 10 | * 11 | * Permission is hereby granted to use or copy this program 12 | * for any purpose, provided the above notices are retained on all copies. 13 | * Permission to modify the code and to distribute modified code is granted, 14 | * provided the above notices are retained, and a notice that the code was 15 | * modified is included with the above copyright notice. 16 | */ 17 | 18 | /* We want to make sure that GC_thread_exit_proc() is unconditionally */ 19 | /* invoked, even if the client is not compiled with -fexceptions, but */ 20 | /* the GC is. The workaround is to put GC_inner_start_routine() in its */ 21 | /* own file (pthread_start.c), and undefine __EXCEPTIONS in the GCC */ 22 | /* case at the top of the file. FIXME: it's still unclear whether this */ 23 | /* will actually cause the exit handler to be invoked last when */ 24 | /* thread_exit is called (and if -fexceptions is used). */ 25 | #if defined(__GNUC__) && defined(__linux__) 26 | /* We undefine __EXCEPTIONS to avoid using GCC __cleanup__ attribute. */ 27 | /* The current NPTL implementation of pthread_cleanup_push uses */ 28 | /* __cleanup__ attribute when __EXCEPTIONS is defined (-fexceptions). */ 29 | /* The stack unwinding and cleanup with __cleanup__ attributes work */ 30 | /* correctly when everything is compiled with -fexceptions, but it is */ 31 | /* not the requirement for this library clients to use -fexceptions */ 32 | /* everywhere. With __EXCEPTIONS undefined, the cleanup routines are */ 33 | /* registered with __pthread_register_cancel thus should work anyway. */ 34 | # undef __EXCEPTIONS 35 | #endif 36 | 37 | #include "private/pthread_support.h" 38 | 39 | #if defined(GC_PTHREADS) && !defined(GC_WIN32_THREADS) 40 | 41 | #include 42 | #include 43 | 44 | /* Invoked from GC_start_routine(). */ 45 | GC_INNER_PTHRSTART void * GC_CALLBACK GC_inner_start_routine( 46 | struct GC_stack_base *sb, void *arg) 47 | { 48 | void * (*start)(void *); 49 | void * start_arg; 50 | void * result; 51 | volatile GC_thread me = 52 | GC_start_rtn_prepare_thread(&start, &start_arg, sb, arg); 53 | 54 | # ifndef NACL 55 | pthread_cleanup_push(GC_thread_exit_proc, me); 56 | # endif 57 | result = (*start)(start_arg); 58 | # if defined(DEBUG_THREADS) && !defined(GC_PTHREAD_START_STANDALONE) 59 | GC_log_printf("Finishing thread %p\n", (void *)pthread_self()); 60 | # endif 61 | me -> status = result; 62 | GC_dirty(me); 63 | # ifndef NACL 64 | pthread_cleanup_pop(1); 65 | /* Cleanup acquires lock, ensuring that we can't exit while */ 66 | /* a collection that thinks we're alive is trying to stop us. */ 67 | # endif 68 | return result; 69 | } 70 | 71 | #endif /* GC_PTHREADS */ 72 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Ignored files in bdwgc Git repo. 2 | 3 | # Binary files (in root dir, cord, tests): 4 | *.dll 5 | *.exe 6 | *.gcda 7 | *.gch 8 | *.gcno 9 | *.la 10 | *.lib 11 | *.lo 12 | *.o 13 | *.obj 14 | 15 | *.gc.log 16 | .dirstamp 17 | /*_bench.log 18 | /*_bench.trs 19 | /*test.log 20 | /*test.trs 21 | /.libs/ 22 | /Makefile 23 | /add_gc_prefix 24 | /base_lib 25 | /bdw-gc.pc 26 | /bsd-libgc.a 27 | /bsd-libleak.a 28 | /c++ 29 | /config.cache 30 | /config.log 31 | /config.status 32 | /cord/cordtest 33 | /cord/de 34 | /cord/de_win.rbj 35 | /cord/de_win.res 36 | /cord/tests/de_win.rbj 37 | /cord/tests/de_win.res 38 | /cords 39 | /cordtest 40 | /core 41 | /de 42 | /disclaim_bench 43 | /disclaim_test 44 | /dont_ar_1 45 | /dont_ar_3 46 | /dont_ar_4 47 | /gc-* 48 | /gc.a 49 | /gc.log 50 | /gcname 51 | /gctest 52 | /gctest_dyn_link 53 | /gctest_irix_dyn_link 54 | /hugetest 55 | /if_mach 56 | /if_not_there 57 | /initsecondarythread_test 58 | /leaktest 59 | /libalphagc.so 60 | /libgc.so 61 | /libirixgc.so 62 | /liblinuxgc.so 63 | /libtool 64 | /middletest 65 | /realloc_test 66 | /setjmp_test 67 | /smashtest 68 | /staticrootstest 69 | /subthreadcreate_test 70 | /sunos5gc.so 71 | /test-suite.log 72 | /test_atomic_ops 73 | /test_atomic_ops.log 74 | /test_atomic_ops.trs 75 | /test_cpp 76 | /test_cpp.cpp 77 | /test_cpp.log 78 | /test_cpp.trs 79 | /threadkey_test 80 | /threadleaktest 81 | /threadlibs 82 | /tracetest 83 | 84 | # Config, dependency and stamp files generated by configure: 85 | .deps/ 86 | /include/config.h 87 | config.h.in~ 88 | stamp-h1 89 | 90 | # External library (without trailing slash to allow symlinks): 91 | /libatomic_ops* 92 | /pthreads-w32* 93 | 94 | # These files are generated by autoreconf: 95 | /Makefile.in 96 | /aclocal.m4 97 | /autom4te.cache/ 98 | /compile 99 | /config.guess 100 | /config.sub 101 | /configure 102 | /depcomp 103 | /include/config.h.in 104 | /install-sh 105 | /ltmain.sh 106 | /m4/libtool.m4 107 | /m4/ltoptions.m4 108 | /m4/ltsugar.m4 109 | /m4/ltversion.m4 110 | /m4/lt~obsolete.m4 111 | /missing 112 | /mkinstalldirs 113 | /test-driver 114 | 115 | # These files are generated by CMake: 116 | *.tlog 117 | /*.vcxproj 118 | /*.vcxproj.filters 119 | /CMakeCache.txt 120 | /CMakeFiles/ 121 | /CTestTestfile.cmake 122 | /DartConfiguration.tcl 123 | /Testing/Temporary/ 124 | /cmake_install.cmake 125 | /gc.sln 126 | /libgc*-dll.so 127 | /libgc*-lib.a 128 | /tests/*.vcxproj 129 | /tests/*.vcxproj.filters 130 | /tests/*test 131 | /tests/CMakeFiles/ 132 | /tests/CTestTestfile.cmake 133 | /tests/Makefile 134 | /tests/cmake_install.cmake 135 | /tests/test_cpp 136 | 137 | # Rarely generated files (mostly by some Win/DOS compilers): 138 | /*.copied.c 139 | /*.csm 140 | /*.err 141 | /*.i 142 | /*.lb1 143 | /*.lnk 144 | /*.map 145 | /*.out 146 | /*.rbj 147 | /*.res 148 | /*.stackdump 149 | /*.sym 150 | /*.tmp 151 | *.bsc 152 | *.dll.manifest 153 | *.exp 154 | *.idb 155 | *.ilk 156 | *.pdb 157 | *.sbr 158 | 159 | # Stuff from VS build system and IDE 160 | *.vcproj.*.user 161 | 162 | # Code analysis tools: 163 | *.c.gcov 164 | *.cc.gcov 165 | *.h.gcov 166 | *.sancov 167 | /.sv*-dir 168 | /cov-int 169 | /coverage.info 170 | /pvs-project.log 171 | /pvs-project.tasks 172 | /strace_out 173 | -------------------------------------------------------------------------------- /obj_map.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 1988, 1989 Hans-J. Boehm, Alan J. Demers 3 | * Copyright (c) 1991, 1992 by Xerox Corporation. All rights reserved. 4 | * Copyright (c) 1999-2001 by Hewlett-Packard Company. All rights reserved. 5 | * 6 | * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED 7 | * OR IMPLIED. ANY USE IS AT YOUR OWN RISK. 8 | * 9 | * Permission is hereby granted to use or copy this program 10 | * for any purpose, provided the above notices are retained on all copies. 11 | * Permission to modify the code and to distribute modified code is granted, 12 | * provided the above notices are retained, and a notice that the code was 13 | * modified is included with the above copyright notice. 14 | */ 15 | 16 | #include "private/gc_priv.h" 17 | 18 | /* Routines for maintaining maps describing heap block 19 | * layouts for various object sizes. Allows fast pointer validity checks 20 | * and fast location of object start locations on machines (such as SPARC) 21 | * with slow division. 22 | */ 23 | 24 | /* Consider pointers that are offset bytes displaced from the beginning */ 25 | /* of an object to be valid. */ 26 | 27 | GC_API void GC_CALL GC_register_displacement(size_t offset) 28 | { 29 | DCL_LOCK_STATE; 30 | 31 | LOCK(); 32 | GC_register_displacement_inner(offset); 33 | UNLOCK(); 34 | } 35 | 36 | GC_INNER void GC_register_displacement_inner(size_t offset) 37 | { 38 | if (offset >= VALID_OFFSET_SZ) { 39 | ABORT("Bad argument to GC_register_displacement"); 40 | } 41 | if (!GC_valid_offsets[offset]) { 42 | GC_valid_offsets[offset] = TRUE; 43 | GC_modws_valid_offsets[offset % sizeof(word)] = TRUE; 44 | } 45 | } 46 | 47 | #ifdef MARK_BIT_PER_GRANULE 48 | /* Add a heap block map for objects of size granules to obj_map. */ 49 | /* Return FALSE on failure. */ 50 | /* A size of 0 granules is used for large objects. */ 51 | GC_INNER GC_bool GC_add_map_entry(size_t granules) 52 | { 53 | unsigned displ; 54 | unsigned short * new_map; 55 | 56 | if (granules > BYTES_TO_GRANULES(MAXOBJBYTES)) granules = 0; 57 | if (GC_obj_map[granules] != 0) { 58 | return(TRUE); 59 | } 60 | new_map = (unsigned short *)GC_scratch_alloc(MAP_LEN * sizeof(short)); 61 | if (new_map == 0) return(FALSE); 62 | GC_COND_LOG_PRINTF( 63 | "Adding block map for size of %u granules (%u bytes)\n", 64 | (unsigned)granules, (unsigned)GRANULES_TO_BYTES(granules)); 65 | if (granules == 0) { 66 | for (displ = 0; displ < BYTES_TO_GRANULES(HBLKSIZE); displ++) { 67 | new_map[displ] = 1; /* Nonzero to get us out of marker fast path. */ 68 | } 69 | } else { 70 | for (displ = 0; displ < BYTES_TO_GRANULES(HBLKSIZE); displ++) { 71 | new_map[displ] = (unsigned short)(displ % granules); 72 | } 73 | } 74 | GC_obj_map[granules] = new_map; 75 | return(TRUE); 76 | } 77 | #endif /* MARK_BIT_PER_GRANULE */ 78 | 79 | GC_INNER void GC_initialize_offsets(void) 80 | { 81 | unsigned i; 82 | if (GC_all_interior_pointers) { 83 | for (i = 0; i < VALID_OFFSET_SZ; ++i) 84 | GC_valid_offsets[i] = TRUE; 85 | } else { 86 | BZERO(GC_valid_offsets, sizeof(GC_valid_offsets)); 87 | for (i = 0; i < sizeof(word); ++i) 88 | GC_modws_valid_offsets[i] = FALSE; 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /tests/initsecondarythread.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011 Ludovic Courtes 3 | * 4 | * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED 5 | * OR IMPLIED. ANY USE IS AT YOUR OWN RISK. 6 | * 7 | * Permission is hereby granted to use or copy this program 8 | * for any purpose, provided the above notices are retained on all copies. 9 | * Permission to modify the code and to distribute modified code is granted, 10 | * provided the above notices are retained, and a notice that the code was 11 | * modified is included with the above copyright notice. 12 | */ 13 | 14 | /* Make sure 'GC_INIT' can be called from threads other than the initial 15 | * thread. 16 | */ 17 | 18 | #ifdef HAVE_CONFIG_H 19 | # include "config.h" 20 | #endif 21 | 22 | #ifndef GC_THREADS 23 | # define GC_THREADS 24 | #endif 25 | 26 | #define GC_NO_THREAD_REDIRECTS 1 27 | /* Do not redirect thread creation and join calls. */ 28 | 29 | #include "gc.h" 30 | 31 | #ifdef GC_PTHREADS 32 | # include 33 | #else 34 | # include 35 | #endif 36 | 37 | #include 38 | #include 39 | 40 | #ifdef GC_PTHREADS 41 | static void *thread(void *arg) 42 | #else 43 | static DWORD WINAPI thread(LPVOID arg) 44 | #endif 45 | { 46 | GC_INIT(); 47 | (void)GC_MALLOC(123); 48 | (void)GC_MALLOC(12345); 49 | # ifdef GC_PTHREADS 50 | return arg; 51 | # else 52 | return (DWORD)(GC_word)arg; 53 | # endif 54 | } 55 | 56 | #include "private/gcconfig.h" 57 | 58 | int main(void) 59 | { 60 | # ifdef GC_PTHREADS 61 | int code; 62 | pthread_t t; 63 | 64 | # ifdef LINT2 65 | t = pthread_self(); /* explicitly initialize to some value */ 66 | # endif 67 | # else 68 | HANDLE t; 69 | DWORD thread_id; 70 | # endif 71 | # if !(defined(BEOS) || defined(MSWIN32) || defined(MSWINCE) \ 72 | || defined(CYGWIN32) || defined(GC_OPENBSD_UTHREADS) \ 73 | || (defined(DARWIN) && !defined(NO_PTHREAD_GET_STACKADDR_NP)) \ 74 | || ((defined(FREEBSD) || defined(LINUX) || defined(NETBSD) \ 75 | || defined(HOST_ANDROID)) && !defined(NO_PTHREAD_GETATTR_NP) \ 76 | && !defined(NO_PTHREAD_ATTR_GET_NP)) \ 77 | || (defined(GC_SOLARIS_THREADS) && !defined(_STRICT_STDC)) \ 78 | || (!defined(STACKBOTTOM) && (defined(HEURISTIC1) \ 79 | || (!defined(LINUX_STACKBOTTOM) && !defined(FREEBSD_STACKBOTTOM))))) 80 | /* GC_INIT() must be called from main thread only. */ 81 | GC_INIT(); 82 | # endif 83 | (void)GC_get_parallel(); /* linking fails if no threads support */ 84 | # ifdef GC_PTHREADS 85 | if ((code = pthread_create (&t, NULL, thread, NULL)) != 0) { 86 | fprintf(stderr, "Thread creation failed %d\n", code); 87 | return 1; 88 | } 89 | if ((code = pthread_join (t, NULL)) != 0) { 90 | fprintf(stderr, "Thread join failed %d\n", code); 91 | return 1; 92 | } 93 | # else 94 | t = CreateThread(NULL, 0, thread, 0, 0, &thread_id); 95 | if (t == NULL) { 96 | fprintf(stderr, "Thread creation failed %d\n", (int)GetLastError()); 97 | return 1; 98 | } 99 | if (WaitForSingleObject(t, INFINITE) != WAIT_OBJECT_0) { 100 | fprintf(stderr, "Thread join failed %d\n", (int)GetLastError()); 101 | CloseHandle(t); 102 | return 1; 103 | } 104 | CloseHandle(t); 105 | # endif 106 | return 0; 107 | } 108 | -------------------------------------------------------------------------------- /extra/gc.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1994 by Xerox Corporation. All rights reserved. 3 | * Copyright (c) 1996 by Silicon Graphics. All rights reserved. 4 | * Copyright (c) 1998 by Fergus Henderson. All rights reserved. 5 | * Copyright (c) 2000-2009 by Hewlett-Packard Development Company. 6 | * All rights reserved. 7 | * 8 | * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED 9 | * OR IMPLIED. ANY USE IS AT YOUR OWN RISK. 10 | * 11 | * Permission is hereby granted to use or copy this program 12 | * for any purpose, provided the above notices are retained on all copies. 13 | * Permission to modify the code and to distribute modified code is granted, 14 | * provided the above notices are retained, and a notice that the code was 15 | * modified is included with the above copyright notice. 16 | */ 17 | 18 | /* This file could be used for the following purposes: */ 19 | /* - get the complete GC as a single link object file (module); */ 20 | /* - enable more compiler optimizations. */ 21 | 22 | /* Tip: to get the highest level of compiler optimizations, the typical */ 23 | /* compiler options (GCC) to use are: */ 24 | /* -O3 -fno-strict-aliasing -march=native -Wall -fprofile-generate/use */ 25 | 26 | /* Warning: GCC for Linux (for C++ clients only): Use -fexceptions both */ 27 | /* for GC and the client otherwise GC_thread_exit_proc() is not */ 28 | /* guaranteed to be invoked (see the comments in pthread_start.c). */ 29 | 30 | #ifndef __cplusplus 31 | /* static is desirable here for more efficient linkage. */ 32 | /* TODO: Enable this in case of the compilation as C++ code. */ 33 | # define GC_INNER STATIC 34 | # define GC_EXTERN GC_INNER 35 | /* STATIC is defined in gcconfig.h. */ 36 | #endif 37 | 38 | /* Small files go first... */ 39 | #include "../backgraph.c" 40 | #include "../blacklst.c" 41 | #include "../checksums.c" 42 | #include "../gcj_mlc.c" 43 | #include "../headers.c" 44 | #include "../new_hblk.c" 45 | #include "../obj_map.c" 46 | #include "../ptr_chck.c" 47 | 48 | #include "gc_inline.h" 49 | #include "../allchblk.c" 50 | #include "../alloc.c" 51 | #include "../dbg_mlc.c" 52 | #include "../finalize.c" 53 | #include "../fnlz_mlc.c" 54 | #include "../malloc.c" 55 | #include "../mallocx.c" 56 | #include "../mark.c" 57 | #include "../mark_rts.c" 58 | #include "../reclaim.c" 59 | #include "../typd_mlc.c" 60 | 61 | #include "../misc.c" 62 | #include "../os_dep.c" 63 | #include "../thread_local_alloc.c" 64 | 65 | /* Unity specific includes */ 66 | #include "../heapsections.c" 67 | #include "../vector_mlc.c" 68 | 69 | /* Most platform-specific files go here... */ 70 | #include "../darwin_stop_world.c" 71 | #include "../dyn_load.c" 72 | #include "../gc_dlopen.c" 73 | #if !defined(PLATFORM_MACH_DEP) 74 | #include "../mach_dep.c" 75 | #endif 76 | #if !defined(PLATFORM_STOP_WORLD) 77 | #include "../pthread_stop_world.c" 78 | #endif 79 | #include "../pthread_support.c" 80 | #include "../specific.c" 81 | #include "../win32_threads.c" 82 | 83 | #ifndef GC_PTHREAD_START_STANDALONE 84 | # include "../pthread_start.c" 85 | #endif 86 | 87 | /* Restore pthread calls redirection (if altered in */ 88 | /* pthread_stop_world.c, pthread_support.c or win32_threads.c). */ 89 | /* This is only useful if directly included from application */ 90 | /* (instead of linking gc). */ 91 | #ifndef GC_NO_THREAD_REDIRECTS 92 | # define GC_PTHREAD_REDIRECTS_ONLY 93 | # include "gc_pthread_redirects.h" 94 | #endif 95 | 96 | /* The files from "extra" folder are not included. */ 97 | -------------------------------------------------------------------------------- /cord/tests/de_win.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1994 by Xerox Corporation. All rights reserved. 3 | * 4 | * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED 5 | * OR IMPLIED. ANY USE IS AT YOUR OWN RISK. 6 | * 7 | * Permission is hereby granted to use or copy this program 8 | * for any purpose, provided the above notices are retained on all copies. 9 | * Permission to modify the code and to distribute modified code is granted, 10 | * provided the above notices are retained, and a notice that the code was 11 | * modified is included with the above copyright notice. 12 | */ 13 | 14 | /* cord.h, de_cmds.h, and windows.h should be included before this. */ 15 | 16 | # define OTHER_FLAG 0x100 17 | # define EDIT_CMD_FLAG 0x200 18 | # define REPEAT_FLAG 0x400 19 | 20 | # define CHAR_CMD(i) ((i) & 0xff) 21 | 22 | /* MENU: DE */ 23 | #define IDM_FILESAVE (EDIT_CMD_FLAG + WRITE) 24 | #define IDM_FILEEXIT (OTHER_FLAG + 1) 25 | #define IDM_HELPABOUT (OTHER_FLAG + 2) 26 | #define IDM_HELPCONTENTS (OTHER_FLAG + 3) 27 | 28 | #define IDM_EDITPDOWN (REPEAT_FLAG + EDIT_CMD_FLAG + DOWN) 29 | #define IDM_EDITPUP (REPEAT_FLAG + EDIT_CMD_FLAG + UP) 30 | #define IDM_EDITUNDO (EDIT_CMD_FLAG + UNDO) 31 | #define IDM_EDITLOCATE (EDIT_CMD_FLAG + LOCATE) 32 | #define IDM_EDITDOWN (EDIT_CMD_FLAG + DOWN) 33 | #define IDM_EDITUP (EDIT_CMD_FLAG + UP) 34 | #define IDM_EDITLEFT (EDIT_CMD_FLAG + LEFT) 35 | #define IDM_EDITRIGHT (EDIT_CMD_FLAG + RIGHT) 36 | #define IDM_EDITBS (EDIT_CMD_FLAG + BS) 37 | #define IDM_EDITDEL (EDIT_CMD_FLAG + DEL) 38 | #define IDM_EDITREPEAT (EDIT_CMD_FLAG + REPEAT) 39 | #define IDM_EDITTOP (EDIT_CMD_FLAG + TOP) 40 | 41 | 42 | 43 | 44 | /* Windows UI stuff */ 45 | 46 | LRESULT CALLBACK WndProc (HWND hwnd, UINT message, 47 | WPARAM wParam, LPARAM lParam); 48 | 49 | /* Screen dimensions. Maintained by de_win.c. */ 50 | extern int LINES; 51 | extern int COLS; 52 | 53 | /* File being edited. */ 54 | extern char * arg_file_name; 55 | 56 | /* Current display position in file. Maintained by de.c */ 57 | extern int dis_line; 58 | extern int dis_col; 59 | 60 | /* Current cursor position in file. */ 61 | extern int line; 62 | extern int col; 63 | 64 | /* 65 | * Calls from de_win.c to de.c 66 | */ 67 | 68 | CORD retrieve_screen_line(int i); 69 | /* Get the contents of i'th screen line. */ 70 | /* Relies on COLS. */ 71 | 72 | void set_position(int x, int y); 73 | /* Set column, row. Upper left of window = (0,0). */ 74 | 75 | void do_command(int); 76 | /* Execute an editor command. */ 77 | /* Agument is a command character or one */ 78 | /* of the IDM_ commands. */ 79 | 80 | void generic_init(void); 81 | /* OS independent initialization */ 82 | 83 | 84 | /* 85 | * Calls from de.c to de_win.c 86 | */ 87 | 88 | void move_cursor(int column, int line); 89 | /* Physically move the cursor on the display, */ 90 | /* so that it appears at */ 91 | /* (column, line). */ 92 | 93 | void invalidate_line(int line); 94 | /* Invalidate line i on the screen. */ 95 | 96 | void de_error(const char *s); 97 | /* Display error message. */ 98 | -------------------------------------------------------------------------------- /doc/README.solaris2: -------------------------------------------------------------------------------- 1 | The collector supports both incremental collection and threads under 2 | Solaris 2. The incremental collector normally retrieves page dirty information 3 | through the appropriate /proc calls. But it can also be configured 4 | (by defining MPROTECT_VDB instead of PROC_VDB in gcconfig.h) to use mprotect 5 | and signals. This may result in shorter pause times, but it is no longer 6 | safe to issue arbitrary system calls that write to the heap. 7 | 8 | Under other UNIX versions, 9 | the collector normally obtains memory through sbrk. There is some reason 10 | to expect that this is not safe if the client program also calls the system 11 | malloc, or especially realloc. The sbrk man page strongly suggests this is 12 | not safe: "Many library routines use malloc() internally, so use brk() 13 | and sbrk() only when you know that malloc() definitely will not be used by 14 | any library routine." This doesn't make a lot of sense to me, since there 15 | seems to be no documentation as to which routines can transitively call malloc. 16 | Nonetheless, under Solaris2, the collector now allocates 17 | memory using mmap by default. (It defines USE_MMAP in gcconfig.h.) 18 | You may want to reverse this decisions if you use -DREDIRECT_MALLOC=... 19 | 20 | Note: 21 | Before you run "make check", you need to set your LD_LIBRARY_PATH correctly 22 | (e.g., to "/usr/local/lib") so that tests can find the shared library 23 | libgcc_s.so.1. Alternatively, you can configure with --disable-shared. 24 | 25 | SOLARIS THREADS: 26 | 27 | Unless --disable-threads option is given, threads support is on by default in 28 | configure. This causes the collector to be compiled with -D GC_THREADS 29 | ensuring thread safety. This assumes use of the pthread_ interface; old-style 30 | Solaris threads are no longer supported. 31 | Thread-local allocation is now on by default. Parallel marking is on by 32 | default starting from GC v7.3 but it could be disabled manually 33 | by configure --disable-parallel-mark option. 34 | 35 | It is also essential that gc.h be included in files that call pthread_create, 36 | pthread_join, pthread_detach, or dlopen. gc.h macro defines these to also do 37 | GC bookkeeping, etc. gc.h must be included with one or both of these macros 38 | defined, otherwise these replacements are not visible. A collector built in 39 | this way way only be used by programs that are linked with the threads library. 40 | 41 | Since 5.0 alpha5, dlopen disables collection temporarily, 42 | unless USE_PROC_FOR_LIBRARIES is defined. In some unlikely cases, this 43 | can result in unpleasant heap growth. But it seems better than the 44 | race/deadlock issues we had before. 45 | 46 | If threads are used on an X86 processor with malloc redirected to 47 | GC_malloc, it is necessary to call GC_INIT explicitly before forking the 48 | first thread. (This avoids a deadlock arising from calling GC_thr_init 49 | with the allocation lock held.) 50 | 51 | It appears that there is a problem in using gc_cpp.h in conjunction with 52 | Solaris threads and Sun's C++ runtime. Apparently the overloaded new operator 53 | is invoked by some iostream initialization code before threads are correctly 54 | initialized. As a result, call to thr_self() in garbage collector 55 | initialization SEGV faults. Currently the only known workaround is to not 56 | invoke the garbage collector from a user defined global operator new, or to 57 | have it invoke the garbage-collector's allocators only after main has started. 58 | (Note that the latter requires a moderately expensive test in operator 59 | delete.) 60 | 61 | I encountered "symbol : offset .... is non-aligned" errors. These 62 | appear to be traceable to the use of the GNU assembler with the Sun linker. 63 | The former appears to generate a relocation not understood by the latter. 64 | The fix appears to be to use a consistent tool chain. (As a non-Solaris-expert 65 | my solution involved hacking the libtool script, but I'm sure you can 66 | do something less ugly.) 67 | 68 | Hans-J. Boehm 69 | (The above contains my personal opinions, which are probably not shared 70 | by anyone else.) 71 | -------------------------------------------------------------------------------- /fnlz_mlc.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2011 by Hewlett-Packard Company. All rights reserved. 3 | * 4 | * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED 5 | * OR IMPLIED. ANY USE IS AT YOUR OWN RISK. 6 | * 7 | * Permission is hereby granted to use or copy this program 8 | * for any purpose, provided the above notices are retained on all copies. 9 | * Permission to modify the code and to distribute modified code is granted, 10 | * provided the above notices are retained, and a notice that the code was 11 | * modified is included with the above copyright notice. 12 | * 13 | */ 14 | 15 | #include "private/gc_priv.h" 16 | 17 | #ifdef ENABLE_DISCLAIM 18 | 19 | #include "gc_disclaim.h" 20 | #include "gc_inline.h" /* for GC_malloc_kind */ 21 | 22 | STATIC int GC_finalized_kind = 0; 23 | 24 | #if defined(KEEP_BACK_PTRS) || defined(MAKE_BACK_GRAPH) 25 | /* The first bit is already used for a debug purpose. */ 26 | # define FINALIZER_CLOSURE_FLAG 0x2 27 | #else 28 | # define FINALIZER_CLOSURE_FLAG 0x1 29 | #endif 30 | 31 | STATIC int GC_CALLBACK GC_finalized_disclaim(void *obj) 32 | { 33 | word fc_word = *(word *)obj; 34 | 35 | if ((fc_word & FINALIZER_CLOSURE_FLAG) != 0) { 36 | /* The disclaim function may be passed fragments from the */ 37 | /* free-list, on which it should not run finalization. */ 38 | /* To recognize this case, we use the fact that the first word */ 39 | /* on such fragments is always multiple of 4 (a link to the next */ 40 | /* fragment, or NULL). If it is desirable to have a finalizer */ 41 | /* which does not use the first word for storing finalization */ 42 | /* info, GC_reclaim_with_finalization must be extended to clear */ 43 | /* fragments so that the assumption holds for the selected word. */ 44 | const struct GC_finalizer_closure *fc 45 | = (struct GC_finalizer_closure *)(fc_word 46 | & ~(word)FINALIZER_CLOSURE_FLAG); 47 | (*fc->proc)((word *)obj + 1, fc->cd); 48 | } 49 | return 0; 50 | } 51 | 52 | GC_API void GC_CALL GC_init_finalized_malloc(void) 53 | { 54 | DCL_LOCK_STATE; 55 | 56 | GC_init(); /* In case it's not already done. */ 57 | LOCK(); 58 | if (GC_finalized_kind != 0) { 59 | UNLOCK(); 60 | return; 61 | } 62 | 63 | /* The finalizer closure is placed in the first word in order to */ 64 | /* use the lower bits to distinguish live objects from objects on */ 65 | /* the free list. The downside of this is that we need one-word */ 66 | /* offset interior pointers, and that GC_base does not return the */ 67 | /* start of the user region. */ 68 | GC_register_displacement_inner(sizeof(word)); 69 | 70 | GC_finalized_kind = GC_new_kind_inner(GC_new_free_list_inner(), 71 | GC_DS_LENGTH, TRUE, TRUE); 72 | GC_ASSERT(GC_finalized_kind != 0); 73 | GC_register_disclaim_proc(GC_finalized_kind, GC_finalized_disclaim, TRUE); 74 | UNLOCK(); 75 | } 76 | 77 | GC_API void GC_CALL GC_register_disclaim_proc(int kind, GC_disclaim_proc proc, 78 | int mark_unconditionally) 79 | { 80 | GC_ASSERT((unsigned)kind < MAXOBJKINDS); 81 | GC_obj_kinds[kind].ok_disclaim_proc = proc; 82 | GC_obj_kinds[kind].ok_mark_unconditionally = (GC_bool)mark_unconditionally; 83 | } 84 | 85 | GC_API GC_ATTR_MALLOC void * GC_CALL GC_finalized_malloc(size_t lb, 86 | const struct GC_finalizer_closure *fclos) 87 | { 88 | word *op; 89 | 90 | GC_ASSERT(GC_finalized_kind != 0); 91 | op = (word *)GC_malloc_kind(SIZET_SAT_ADD(lb, sizeof(word)), 92 | GC_finalized_kind); 93 | if (EXPECT(NULL == op, FALSE)) 94 | return NULL; 95 | *op = (word)fclos | FINALIZER_CLOSURE_FLAG; 96 | return op + 1; 97 | } 98 | 99 | #endif /* ENABLE_DISCLAIM */ 100 | -------------------------------------------------------------------------------- /README.QUICK: -------------------------------------------------------------------------------- 1 | Copyright 1988, 1989 Hans-J. Boehm, Alan J. Demers 2 | Copyright (c) 1991-1995 by Xerox Corporation. All rights reserved. 3 | Copyright (c) 1996-1999 by Silicon Graphics. All rights reserved. 4 | Copyright (c) 1999-2001 by Hewlett-Packard. All rights reserved. 5 | 6 | THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED 7 | OR IMPLIED. ANY USE IS AT YOUR OWN RISK. 8 | 9 | Permission is hereby granted to use or copy this program 10 | for any purpose, provided the above notices are retained on all copies. 11 | Permission to modify the code and to distribute modified code is granted, 12 | provided the above notices are retained, and a notice that the code was 13 | modified is included with the above copyright notice. 14 | 15 | A few files have other copyright holders. A few of the files needed 16 | to use the GNU-style build procedure come with a modified GPL license 17 | that appears not to significantly restrict use of the collector, though 18 | use of those files for a purpose other than building the collector may 19 | require the resulting code to be covered by the GPL. 20 | 21 | For more details and the names of other contributors, see the README.md, 22 | doc/README.*, AUTHORS and include/gc.h files. These files describe typical 23 | use of the collector on a machine that is already supported. 24 | 25 | For the version number, see README.md or include/gc_version.h files. 26 | 27 | INSTALLATION: 28 | Under UN*X, Linux: 29 | Alternative 1 (the old way): type "make -f Makefile.direct check". 30 | Link against gc.a. 31 | 32 | Alternative 2 (the new way): type 33 | "./configure --prefix=; make; make check; make install". 34 | Link against /lib/libgc.a or /lib/libgc.so. 35 | See doc/README.autoconf for details 36 | 37 | Under Windows 95, 98, Me, NT, or 2000: 38 | copy the appropriate makefile to MAKEFILE, read it, and type "nmake test". 39 | (Under Windows, this assumes you have Microsoft command-line tools 40 | installed, and suitably configured.) 41 | Read the machine specific README.XXX in the doc directory if one exists. 42 | 43 | If you need thread support, you should define GC_THREADS as described in 44 | doc/README.macros (configure defines this implicitly unless --disable-threads 45 | option is given). 46 | 47 | If you wish to use the cord (structured string) library with the stand-alone 48 | Makefile.direct, type "make -f Makefile.direct cords". (You may need to 49 | override CC specified in the Makefile. The CORD_printf implementation in 50 | cordprnt.c is known to be less than perfectly portable. The rest of the 51 | package should still work.) See include/cord.h for the API. 52 | 53 | If you wish to use the collector from C++, type "make c++", or use 54 | --enable-cplusplus with the configure script. With Makefile.direct, 55 | these ones add further files to gc.a and to the include subdirectory. 56 | With the alternate build process, this generates libgccpp. 57 | See include/gc_cpp.h. 58 | 59 | TYPICAL USE: 60 | Include "gc.h" from the include subdirectory. Link against the 61 | appropriate library ("gc.a" under UN*X). Replace calls to malloc 62 | by calls to GC_MALLOC, and calls to realloc by calls to GC_REALLOC. 63 | If the object is known to never contain pointers, use GC_MALLOC_ATOMIC 64 | instead of GC_MALLOC. 65 | 66 | Define GC_DEBUG before including gc.h for additional checking. 67 | 68 | More documentation on the collector interface can be found in README.md, 69 | doc/gcinterface.md, include/gc.h, and other files in the doc directory. 70 | 71 | WARNINGS: 72 | 73 | Do not store the only pointer to an object in memory allocated 74 | with system malloc, since the collector usually does not scan 75 | memory allocated in this way. 76 | 77 | Use with threads may be supported on your system, but requires the 78 | collector to be built with thread support. See Makefile. The collector 79 | does not guarantee to scan thread-local storage (e.g. of the kind 80 | accessed with pthread_getspecific()). The collector does scan 81 | thread stacks though, so generally the best solution is to ensure that 82 | any pointers stored in thread-local storage are also stored on the 83 | thread's stack for the duration of their lifetime. 84 | -------------------------------------------------------------------------------- /windows-untested/vc60/test_libgc.dsp: -------------------------------------------------------------------------------- 1 | # Microsoft Developer Studio Project File - Name="test_libgc" - Package Owner=<4> 2 | # Microsoft Developer Studio Generated Build File, Format Version 6.00 3 | # ** DO NOT EDIT ** 4 | 5 | # TARGTYPE "Win32 (x86) Console Application" 0x0103 6 | 7 | CFG=test_libgc - Win32 Debug 8 | !MESSAGE This is not a valid makefile. To build this project using NMAKE, 9 | !MESSAGE use the Export Makefile command and run 10 | !MESSAGE 11 | !MESSAGE NMAKE /f "test_libgc.mak". 12 | !MESSAGE 13 | !MESSAGE You can specify a configuration when running NMAKE 14 | !MESSAGE by defining the macro CFG on the command line. For example: 15 | !MESSAGE 16 | !MESSAGE NMAKE /f "test_libgc.mak" CFG="test_libgc - Win32 Debug" 17 | !MESSAGE 18 | !MESSAGE Possible choices for configuration are: 19 | !MESSAGE 20 | !MESSAGE "test_libgc - Win32 Release" (based on "Win32 (x86) Console Application") 21 | !MESSAGE "test_libgc - Win32 Debug" (based on "Win32 (x86) Console Application") 22 | !MESSAGE 23 | 24 | # Begin Project 25 | # PROP AllowPerConfigDependencies 0 26 | # PROP Scc_ProjName "" 27 | # PROP Scc_LocalPath "" 28 | CPP=cl.exe 29 | RSC=rc.exe 30 | 31 | !IF "$(CFG)" == "test_libgc - Win32 Release" 32 | 33 | # PROP BASE Use_MFC 0 34 | # PROP BASE Use_Debug_Libraries 0 35 | # PROP BASE Output_Dir "Release" 36 | # PROP BASE Intermediate_Dir "Release" 37 | # PROP BASE Target_Dir "" 38 | # PROP Use_MFC 0 39 | # PROP Use_Debug_Libraries 0 40 | # PROP Output_Dir "..\..\..\bin" 41 | # PROP Intermediate_Dir "..\..\..\obj\Release\test_libgc" 42 | # PROP Ignore_Export_Lib 0 43 | # PROP Target_Dir "" 44 | # ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c 45 | # ADD CPP /nologo /W3 /GX /Zi /O2 /I "..\..\include" /D "NDEBUG" /D "_CONSOLE" /D "WIN32" /D "_MBCS" /FD /c 46 | # SUBTRACT CPP /Fr /YX 47 | # ADD BASE RSC /l 0x409 /d "NDEBUG" 48 | # ADD RSC /l 0x409 /d "NDEBUG" 49 | BSC32=bscmake.exe 50 | # ADD BASE BSC32 /nologo 51 | # ADD BSC32 /nologo 52 | LINK32=link.exe 53 | # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /machine:I386 54 | # ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /nologo /debug /machine:I386 /release /opt:ref 55 | # SUBTRACT LINK32 /pdb:none 56 | 57 | !ELSEIF "$(CFG)" == "test_libgc - Win32 Debug" 58 | 59 | # PROP BASE Use_MFC 0 60 | # PROP BASE Use_Debug_Libraries 1 61 | # PROP BASE Output_Dir "Debug" 62 | # PROP BASE Intermediate_Dir "Debug" 63 | # PROP BASE Target_Dir "" 64 | # PROP Use_MFC 0 65 | # PROP Use_Debug_Libraries 1 66 | # PROP Output_Dir "..\..\..\bin" 67 | # PROP Intermediate_Dir "..\..\..\obj\Debug\test_libgc" 68 | # PROP Ignore_Export_Lib 0 69 | # PROP Target_Dir "" 70 | # ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c 71 | # ADD CPP /nologo /W3 /Gm /GX /Zi /Od /I "..\..\include" /D "_DEBUG" /D "_CONSOLE" /D "WIN32" /D "_MBCS" /YX /FD /GZ /c 72 | # SUBTRACT CPP /Fr 73 | # ADD BASE RSC /l 0x409 /d "_DEBUG" 74 | # ADD RSC /l 0x409 /d "_DEBUG" 75 | BSC32=bscmake.exe 76 | # ADD BASE BSC32 /nologo 77 | # ADD BSC32 /nologo /o"..\..\..\bin/test_libgcd.bsc" 78 | LINK32=link.exe 79 | # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /debug /machine:I386 /pdbtype:sept 80 | # ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /nologo /incremental:no /debug /machine:I386 /out:"..\..\..\bin/test_libgcd.exe" /pdbtype:sept 81 | 82 | !ENDIF 83 | 84 | # Begin Target 85 | 86 | # Name "test_libgc - Win32 Release" 87 | # Name "test_libgc - Win32 Debug" 88 | # Begin Source File 89 | 90 | SOURCE=..\..\tests\test.c 91 | # End Source File 92 | # End Target 93 | # End Project 94 | -------------------------------------------------------------------------------- /windows-untested/vc60/test_gc.dsp: -------------------------------------------------------------------------------- 1 | # Microsoft Developer Studio Project File - Name="test_gc" - Package Owner=<4> 2 | # Microsoft Developer Studio Generated Build File, Format Version 6.00 3 | # ** DO NOT EDIT ** 4 | 5 | # TARGTYPE "Win32 (x86) Console Application" 0x0103 6 | 7 | CFG=test_gc - Win32 Debug 8 | !MESSAGE This is not a valid makefile. To build this project using NMAKE, 9 | !MESSAGE use the Export Makefile command and run 10 | !MESSAGE 11 | !MESSAGE NMAKE /f "test_gc.mak". 12 | !MESSAGE 13 | !MESSAGE You can specify a configuration when running NMAKE 14 | !MESSAGE by defining the macro CFG on the command line. For example: 15 | !MESSAGE 16 | !MESSAGE NMAKE /f "test_gc.mak" CFG="test_gc - Win32 Debug" 17 | !MESSAGE 18 | !MESSAGE Possible choices for configuration are: 19 | !MESSAGE 20 | !MESSAGE "test_gc - Win32 Release" (based on "Win32 (x86) Console Application") 21 | !MESSAGE "test_gc - Win32 Debug" (based on "Win32 (x86) Console Application") 22 | !MESSAGE 23 | 24 | # Begin Project 25 | # PROP AllowPerConfigDependencies 0 26 | # PROP Scc_ProjName "" 27 | # PROP Scc_LocalPath "" 28 | CPP=cl.exe 29 | RSC=rc.exe 30 | 31 | !IF "$(CFG)" == "test_gc - Win32 Release" 32 | 33 | # PROP BASE Use_MFC 0 34 | # PROP BASE Use_Debug_Libraries 0 35 | # PROP BASE Output_Dir "Release" 36 | # PROP BASE Intermediate_Dir "Release" 37 | # PROP BASE Target_Dir "" 38 | # PROP Use_MFC 0 39 | # PROP Use_Debug_Libraries 0 40 | # PROP Output_Dir "..\..\..\bin" 41 | # PROP Intermediate_Dir "..\..\..\obj\Release\test_gc" 42 | # PROP Ignore_Export_Lib 0 43 | # PROP Target_Dir "" 44 | # ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c 45 | # ADD CPP /nologo /MD /W3 /GX /Zi /O2 /I "..\..\include" /D "NDEBUG" /D "_CONSOLE" /D "GC_DLL" /D "WIN32" /D "_MBCS" /D "GC_THREADS" /FD /c 46 | # SUBTRACT CPP /Fr /YX 47 | # ADD BASE RSC /l 0x409 /d "NDEBUG" 48 | # ADD RSC /l 0x409 /d "NDEBUG" 49 | BSC32=bscmake.exe 50 | # ADD BASE BSC32 /nologo 51 | # ADD BSC32 /nologo 52 | LINK32=link.exe 53 | # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /machine:I386 54 | # ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /nologo /debug /machine:I386 /release /opt:ref 55 | # SUBTRACT LINK32 /pdb:none 56 | 57 | !ELSEIF "$(CFG)" == "test_gc - Win32 Debug" 58 | 59 | # PROP BASE Use_MFC 0 60 | # PROP BASE Use_Debug_Libraries 1 61 | # PROP BASE Output_Dir "Debug" 62 | # PROP BASE Intermediate_Dir "Debug" 63 | # PROP BASE Target_Dir "" 64 | # PROP Use_MFC 0 65 | # PROP Use_Debug_Libraries 1 66 | # PROP Output_Dir "..\..\..\bin" 67 | # PROP Intermediate_Dir "..\..\..\obj\Debug\test_gc" 68 | # PROP Ignore_Export_Lib 0 69 | # PROP Target_Dir "" 70 | # ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c 71 | # ADD CPP /nologo /MDd /W3 /Gm /GX /Zi /Od /I "..\..\include" /D "_DEBUG" /D "_CONSOLE" /D "GC_DLL" /D "WIN32" /D "_MBCS" /D "GC_THREADS" /YX /FD /GZ /c 72 | # SUBTRACT CPP /Fr 73 | # ADD BASE RSC /l 0x409 /d "_DEBUG" 74 | # ADD RSC /l 0x409 /d "_DEBUG" 75 | BSC32=bscmake.exe 76 | # ADD BASE BSC32 /nologo 77 | # ADD BSC32 /nologo /o"..\..\..\bin/test_gcd.bsc" 78 | LINK32=link.exe 79 | # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /debug /machine:I386 /pdbtype:sept 80 | # ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /nologo /incremental:no /debug /machine:I386 /out:"..\..\..\bin/test_gcd.exe" /pdbtype:sept 81 | 82 | !ENDIF 83 | 84 | # Begin Target 85 | 86 | # Name "test_gc - Win32 Release" 87 | # Name "test_gc - Win32 Debug" 88 | # Begin Source File 89 | 90 | SOURCE=..\..\tests\test.c 91 | # End Source File 92 | # End Target 93 | # End Project 94 | -------------------------------------------------------------------------------- /windows-untested/vc60/test_libgcmt.dsp: -------------------------------------------------------------------------------- 1 | # Microsoft Developer Studio Project File - Name="test_libgcmt" - Package Owner=<4> 2 | # Microsoft Developer Studio Generated Build File, Format Version 6.00 3 | # ** DO NOT EDIT ** 4 | 5 | # TARGTYPE "Win32 (x86) Console Application" 0x0103 6 | 7 | CFG=test_libgcmt - Win32 Debug 8 | !MESSAGE This is not a valid makefile. To build this project using NMAKE, 9 | !MESSAGE use the Export Makefile command and run 10 | !MESSAGE 11 | !MESSAGE NMAKE /f "test_libgcmt.mak". 12 | !MESSAGE 13 | !MESSAGE You can specify a configuration when running NMAKE 14 | !MESSAGE by defining the macro CFG on the command line. For example: 15 | !MESSAGE 16 | !MESSAGE NMAKE /f "test_libgcmt.mak" CFG="test_libgcmt - Win32 Debug" 17 | !MESSAGE 18 | !MESSAGE Possible choices for configuration are: 19 | !MESSAGE 20 | !MESSAGE "test_libgcmt - Win32 Release" (based on "Win32 (x86) Console Application") 21 | !MESSAGE "test_libgcmt - Win32 Debug" (based on "Win32 (x86) Console Application") 22 | !MESSAGE 23 | 24 | # Begin Project 25 | # PROP AllowPerConfigDependencies 0 26 | # PROP Scc_ProjName "" 27 | # PROP Scc_LocalPath "" 28 | CPP=cl.exe 29 | RSC=rc.exe 30 | 31 | !IF "$(CFG)" == "test_libgcmt - Win32 Release" 32 | 33 | # PROP BASE Use_MFC 0 34 | # PROP BASE Use_Debug_Libraries 0 35 | # PROP BASE Output_Dir "Release" 36 | # PROP BASE Intermediate_Dir "Release" 37 | # PROP BASE Target_Dir "" 38 | # PROP Use_MFC 0 39 | # PROP Use_Debug_Libraries 0 40 | # PROP Output_Dir "..\..\..\bin" 41 | # PROP Intermediate_Dir "..\..\..\obj\Release\test_libgcmt" 42 | # PROP Ignore_Export_Lib 0 43 | # PROP Target_Dir "" 44 | # ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c 45 | # ADD CPP /nologo /MT /W3 /GX /Zi /O2 /I "..\..\include" /D "NDEBUG" /D "_CONSOLE" /D "WIN32" /D "_MBCS" /D "GC_THREADS" /FD /c 46 | # SUBTRACT CPP /Fr /YX 47 | # ADD BASE RSC /l 0x409 /d "NDEBUG" 48 | # ADD RSC /l 0x409 /d "NDEBUG" 49 | BSC32=bscmake.exe 50 | # ADD BASE BSC32 /nologo 51 | # ADD BSC32 /nologo 52 | LINK32=link.exe 53 | # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /machine:I386 54 | # ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /nologo /debug /machine:I386 /release /opt:ref 55 | # SUBTRACT LINK32 /pdb:none 56 | 57 | !ELSEIF "$(CFG)" == "test_libgcmt - Win32 Debug" 58 | 59 | # PROP BASE Use_MFC 0 60 | # PROP BASE Use_Debug_Libraries 1 61 | # PROP BASE Output_Dir "Debug" 62 | # PROP BASE Intermediate_Dir "Debug" 63 | # PROP BASE Target_Dir "" 64 | # PROP Use_MFC 0 65 | # PROP Use_Debug_Libraries 1 66 | # PROP Output_Dir "..\..\..\bin" 67 | # PROP Intermediate_Dir "..\..\..\obj\Debug\test_libgcmt" 68 | # PROP Ignore_Export_Lib 0 69 | # PROP Target_Dir "" 70 | # ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c 71 | # ADD CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /I "..\..\include" /D "_DEBUG" /D "_CONSOLE" /D "WIN32" /D "_MBCS" /D "GC_THREADS" /YX /FD /GZ /c 72 | # SUBTRACT CPP /Fr 73 | # ADD BASE RSC /l 0x409 /d "_DEBUG" 74 | # ADD RSC /l 0x409 /d "_DEBUG" 75 | BSC32=bscmake.exe 76 | # ADD BASE BSC32 /nologo 77 | # ADD BSC32 /nologo /o"..\..\..\bin/test_libgcmtd.bsc" 78 | LINK32=link.exe 79 | # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /debug /machine:I386 /pdbtype:sept 80 | # ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /nologo /incremental:no /debug /machine:I386 /out:"..\..\..\bin/test_libgcmtd.exe" /pdbtype:sept 81 | 82 | !ENDIF 83 | 84 | # Begin Target 85 | 86 | # Name "test_libgcmt - Win32 Release" 87 | # Name "test_libgcmt - Win32 Debug" 88 | # Begin Source File 89 | 90 | SOURCE=..\..\tests\test.c 91 | # End Source File 92 | # End Target 93 | # End Project 94 | -------------------------------------------------------------------------------- /windows-untested/vc60/test_leak_libgc.dsp: -------------------------------------------------------------------------------- 1 | # Microsoft Developer Studio Project File - Name="test_leak_libgc" - Package Owner=<4> 2 | # Microsoft Developer Studio Generated Build File, Format Version 6.00 3 | # ** DO NOT EDIT ** 4 | 5 | # TARGTYPE "Win32 (x86) Console Application" 0x0103 6 | 7 | CFG=test_leak_libgc - Win32 Debug 8 | !MESSAGE This is not a valid makefile. To build this project using NMAKE, 9 | !MESSAGE use the Export Makefile command and run 10 | !MESSAGE 11 | !MESSAGE NMAKE /f "test_leak_libgc.mak". 12 | !MESSAGE 13 | !MESSAGE You can specify a configuration when running NMAKE 14 | !MESSAGE by defining the macro CFG on the command line. For example: 15 | !MESSAGE 16 | !MESSAGE NMAKE /f "test_leak_libgc.mak" CFG="test_leak_libgc - Win32 Debug" 17 | !MESSAGE 18 | !MESSAGE Possible choices for configuration are: 19 | !MESSAGE 20 | !MESSAGE "test_leak_libgc - Win32 Release" (based on "Win32 (x86) Console Application") 21 | !MESSAGE "test_leak_libgc - Win32 Debug" (based on "Win32 (x86) Console Application") 22 | !MESSAGE 23 | 24 | # Begin Project 25 | # PROP AllowPerConfigDependencies 0 26 | # PROP Scc_ProjName "" 27 | # PROP Scc_LocalPath "" 28 | CPP=cl.exe 29 | RSC=rc.exe 30 | 31 | !IF "$(CFG)" == "test_leak_libgc - Win32 Release" 32 | 33 | # PROP BASE Use_MFC 0 34 | # PROP BASE Use_Debug_Libraries 0 35 | # PROP BASE Output_Dir "Release" 36 | # PROP BASE Intermediate_Dir "Release" 37 | # PROP BASE Target_Dir "" 38 | # PROP Use_MFC 0 39 | # PROP Use_Debug_Libraries 0 40 | # PROP Output_Dir "..\..\..\bin" 41 | # PROP Intermediate_Dir "..\..\..\obj\Release\test_leak_libgc" 42 | # PROP Ignore_Export_Lib 0 43 | # PROP Target_Dir "" 44 | # ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c 45 | # ADD CPP /nologo /W3 /GX /Zi /O2 /I "..\..\include" /D "NDEBUG" /D "_CONSOLE" /D "WIN32" /D "_MBCS" /FD /c 46 | # SUBTRACT CPP /Fr /YX 47 | # ADD BASE RSC /l 0x409 /d "NDEBUG" 48 | # ADD RSC /l 0x409 /d "NDEBUG" 49 | BSC32=bscmake.exe 50 | # ADD BASE BSC32 /nologo 51 | # ADD BSC32 /nologo 52 | LINK32=link.exe 53 | # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /machine:I386 54 | # ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /nologo /debug /machine:I386 /release /opt:ref 55 | # SUBTRACT LINK32 /pdb:none 56 | 57 | !ELSEIF "$(CFG)" == "test_leak_libgc - Win32 Debug" 58 | 59 | # PROP BASE Use_MFC 0 60 | # PROP BASE Use_Debug_Libraries 1 61 | # PROP BASE Output_Dir "Debug" 62 | # PROP BASE Intermediate_Dir "Debug" 63 | # PROP BASE Target_Dir "" 64 | # PROP Use_MFC 0 65 | # PROP Use_Debug_Libraries 1 66 | # PROP Output_Dir "..\..\..\bin" 67 | # PROP Intermediate_Dir "..\..\..\obj\Debug\test_leak_libgc" 68 | # PROP Ignore_Export_Lib 0 69 | # PROP Target_Dir "" 70 | # ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c 71 | # ADD CPP /nologo /W3 /Gm /GX /Zi /Od /I "..\..\include" /D "_DEBUG" /D "_CONSOLE" /D "WIN32" /D "_MBCS" /YX /FD /GZ /c 72 | # SUBTRACT CPP /Fr 73 | # ADD BASE RSC /l 0x409 /d "_DEBUG" 74 | # ADD RSC /l 0x409 /d "_DEBUG" 75 | BSC32=bscmake.exe 76 | # ADD BASE BSC32 /nologo 77 | # ADD BSC32 /nologo /o"..\..\..\bin/test_leak_libgcd.bsc" 78 | LINK32=link.exe 79 | # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /debug /machine:I386 /pdbtype:sept 80 | # ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /nologo /incremental:no /debug /machine:I386 /out:"..\..\..\bin/test_leak_libgcd.exe" /pdbtype:sept 81 | 82 | !ENDIF 83 | 84 | # Begin Target 85 | 86 | # Name "test_leak_libgc - Win32 Release" 87 | # Name "test_leak_libgc - Win32 Debug" 88 | # Begin Source File 89 | 90 | SOURCE=..\..\tests\leak_test.c 91 | # End Source File 92 | # End Target 93 | # End Project 94 | -------------------------------------------------------------------------------- /include/gc_tiny_fl.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1999-2005 Hewlett-Packard Development Company, L.P. 3 | * 4 | * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED 5 | * OR IMPLIED. ANY USE IS AT YOUR OWN RISK. 6 | * 7 | * Permission is hereby granted to use or copy this program 8 | * for any purpose, provided the above notices are retained on all copies. 9 | * Permission to modify the code and to distribute modified code is granted, 10 | * provided the above notices are retained, and a notice that the code was 11 | * modified is included with the above copyright notice. 12 | */ 13 | 14 | #ifndef GC_TINY_FL_H 15 | #define GC_TINY_FL_H 16 | /* 17 | * Constants and data structures for "tiny" free lists. 18 | * These are used for thread-local allocation or in-lined allocators. 19 | * Each global free list also essentially starts with one of these. 20 | * However, global free lists are known to the GC. "Tiny" free lists 21 | * are basically private to the client. Their contents are viewed as 22 | * "in use" and marked accordingly by the core of the GC. 23 | * 24 | * Note that inlined code might know about the layout of these and the constants 25 | * involved. Thus any change here may invalidate clients, and such changes should 26 | * be avoided. Hence we keep this as simple as possible. 27 | */ 28 | 29 | /* 30 | * We always set GC_GRANULE_BYTES to twice the length of a pointer. 31 | * This means that all allocation requests are rounded up to the next 32 | * multiple of 16 on 64-bit architectures or 8 on 32-bit architectures. 33 | * This appears to be a reasonable compromise between fragmentation overhead 34 | * and space usage for mark bits (usually mark bytes). 35 | * On many 64-bit architectures some memory references require 16-byte 36 | * alignment, making this necessary anyway. 37 | * For a few 32-bit architecture (e.g. x86), we may also need 16-byte alignment 38 | * for certain memory references. But currently that does not seem to be the 39 | * default for all conventional malloc implementations, so we ignore that 40 | * problem. 41 | * It would always be safe, and often useful, to be able to allocate very 42 | * small objects with smaller alignment. But that would cost us mark bit 43 | * space, so we no longer do so. 44 | */ 45 | #ifndef GC_GRANULE_BYTES 46 | /* GC_GRANULE_BYTES should not be overridden in any instances of the GC */ 47 | /* library that may be shared between applications, since it affects */ 48 | /* the binary interface to the library. */ 49 | # if defined(__LP64__) || defined (_LP64) || defined(_WIN64) \ 50 | || defined(__s390x__) \ 51 | || (defined(__x86_64__) && !defined(__ILP32__)) \ 52 | || defined(__alpha__) || defined(__powerpc64__) \ 53 | || defined(__arch64__) 54 | # define GC_GRANULE_BYTES 16 55 | # define GC_GRANULE_WORDS 2 56 | # else 57 | # define GC_GRANULE_BYTES 8 58 | # define GC_GRANULE_WORDS 2 59 | # endif 60 | #endif /* !GC_GRANULE_BYTES */ 61 | 62 | #if GC_GRANULE_WORDS == 2 63 | # define GC_WORDS_TO_GRANULES(n) ((n)>>1) 64 | #else 65 | # define GC_WORDS_TO_GRANULES(n) ((n)*sizeof(void *)/GC_GRANULE_BYTES) 66 | #endif 67 | 68 | /* A "tiny" free list header contains TINY_FREELISTS pointers to */ 69 | /* singly linked lists of objects of different sizes, the ith one */ 70 | /* containing objects i granules in size. Note that there is a list */ 71 | /* of size zero objects. */ 72 | #ifndef GC_TINY_FREELISTS 73 | # if GC_GRANULE_BYTES == 16 74 | # define GC_TINY_FREELISTS 25 75 | # else 76 | # define GC_TINY_FREELISTS 33 /* Up to and including 256 bytes */ 77 | # endif 78 | #endif /* !GC_TINY_FREELISTS */ 79 | 80 | /* The ith free list corresponds to size i*GC_GRANULE_BYTES */ 81 | /* Internally to the collector, the index can be computed with */ 82 | /* ROUNDED_UP_GRANULES. Externally, we don't know whether */ 83 | /* DONT_ADD_BYTE_AT_END is set, but the client should know. */ 84 | 85 | /* Convert a free list index to the actual size of objects */ 86 | /* on that list, including extra space we added. Not an */ 87 | /* inverse of the above. */ 88 | #define GC_RAW_BYTES_FROM_INDEX(i) ((i) * GC_GRANULE_BYTES) 89 | 90 | #endif /* GC_TINY_FL_H */ 91 | -------------------------------------------------------------------------------- /windows-untested/vc60/test_leak_gc.dsp: -------------------------------------------------------------------------------- 1 | # Microsoft Developer Studio Project File - Name="test_leak_gc" - Package Owner=<4> 2 | # Microsoft Developer Studio Generated Build File, Format Version 6.00 3 | # ** DO NOT EDIT ** 4 | 5 | # TARGTYPE "Win32 (x86) Console Application" 0x0103 6 | 7 | CFG=test_leak_gc - Win32 Debug 8 | !MESSAGE This is not a valid makefile. To build this project using NMAKE, 9 | !MESSAGE use the Export Makefile command and run 10 | !MESSAGE 11 | !MESSAGE NMAKE /f "test_leak_gc.mak". 12 | !MESSAGE 13 | !MESSAGE You can specify a configuration when running NMAKE 14 | !MESSAGE by defining the macro CFG on the command line. For example: 15 | !MESSAGE 16 | !MESSAGE NMAKE /f "test_leak_gc.mak" CFG="test_leak_gc - Win32 Debug" 17 | !MESSAGE 18 | !MESSAGE Possible choices for configuration are: 19 | !MESSAGE 20 | !MESSAGE "test_leak_gc - Win32 Release" (based on "Win32 (x86) Console Application") 21 | !MESSAGE "test_leak_gc - Win32 Debug" (based on "Win32 (x86) Console Application") 22 | !MESSAGE 23 | 24 | # Begin Project 25 | # PROP AllowPerConfigDependencies 0 26 | # PROP Scc_ProjName "" 27 | # PROP Scc_LocalPath "" 28 | CPP=cl.exe 29 | RSC=rc.exe 30 | 31 | !IF "$(CFG)" == "test_leak_gc - Win32 Release" 32 | 33 | # PROP BASE Use_MFC 0 34 | # PROP BASE Use_Debug_Libraries 0 35 | # PROP BASE Output_Dir "Release" 36 | # PROP BASE Intermediate_Dir "Release" 37 | # PROP BASE Target_Dir "" 38 | # PROP Use_MFC 0 39 | # PROP Use_Debug_Libraries 0 40 | # PROP Output_Dir "..\..\..\bin" 41 | # PROP Intermediate_Dir "..\..\..\obj\Release\test_leak_gc" 42 | # PROP Ignore_Export_Lib 0 43 | # PROP Target_Dir "" 44 | # ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c 45 | # ADD CPP /nologo /MD /W3 /GX /Zi /O2 /I "..\..\include" /D "NDEBUG" /D "_CONSOLE" /D "GC_DLL" /D "WIN32" /D "_MBCS" /D "GC_THREADS" /FD /c 46 | # SUBTRACT CPP /Fr /YX 47 | # ADD BASE RSC /l 0x409 /d "NDEBUG" 48 | # ADD RSC /l 0x409 /d "NDEBUG" 49 | BSC32=bscmake.exe 50 | # ADD BASE BSC32 /nologo 51 | # ADD BSC32 /nologo 52 | LINK32=link.exe 53 | # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /machine:I386 54 | # ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /nologo /debug /machine:I386 /release /opt:ref 55 | # SUBTRACT LINK32 /pdb:none 56 | 57 | !ELSEIF "$(CFG)" == "test_leak_gc - Win32 Debug" 58 | 59 | # PROP BASE Use_MFC 0 60 | # PROP BASE Use_Debug_Libraries 1 61 | # PROP BASE Output_Dir "Debug" 62 | # PROP BASE Intermediate_Dir "Debug" 63 | # PROP BASE Target_Dir "" 64 | # PROP Use_MFC 0 65 | # PROP Use_Debug_Libraries 1 66 | # PROP Output_Dir "..\..\..\bin" 67 | # PROP Intermediate_Dir "..\..\..\obj\Debug\test_leak_gc" 68 | # PROP Ignore_Export_Lib 0 69 | # PROP Target_Dir "" 70 | # ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c 71 | # ADD CPP /nologo /MDd /W3 /Gm /GX /Zi /Od /I "..\..\include" /D "_DEBUG" /D "_CONSOLE" /D "GC_DLL" /D "WIN32" /D "_MBCS" /D "GC_THREADS" /YX /FD /GZ /c 72 | # SUBTRACT CPP /Fr 73 | # ADD BASE RSC /l 0x409 /d "_DEBUG" 74 | # ADD RSC /l 0x409 /d "_DEBUG" 75 | BSC32=bscmake.exe 76 | # ADD BASE BSC32 /nologo 77 | # ADD BSC32 /nologo /o"..\..\..\bin/test_leak_gcd.bsc" 78 | LINK32=link.exe 79 | # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /debug /machine:I386 /pdbtype:sept 80 | # ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /nologo /incremental:no /debug /machine:I386 /out:"..\..\..\bin/test_leak_gcd.exe" /pdbtype:sept 81 | 82 | !ENDIF 83 | 84 | # Begin Target 85 | 86 | # Name "test_leak_gc - Win32 Release" 87 | # Name "test_leak_gc - Win32 Debug" 88 | # Begin Source File 89 | 90 | SOURCE=..\..\tests\leak_test.c 91 | # End Source File 92 | # End Target 93 | # End Project 94 | -------------------------------------------------------------------------------- /gc_dlopen.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1991-1994 by Xerox Corporation. All rights reserved. 3 | * Copyright (c) 1997 by Silicon Graphics. All rights reserved. 4 | * Copyright (c) 2000 by Hewlett-Packard Company. All rights reserved. 5 | * 6 | * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED 7 | * OR IMPLIED. ANY USE IS AT YOUR OWN RISK. 8 | * 9 | * Permission is hereby granted to use or copy this program 10 | * for any purpose, provided the above notices are retained on all copies. 11 | * Permission to modify the code and to distribute modified code is granted, 12 | * provided the above notices are retained, and a notice that the code was 13 | * modified is included with the above copyright notice. 14 | */ 15 | 16 | #include "private/gc_priv.h" 17 | 18 | /* This used to be in dyn_load.c. It was extracted into a separate */ 19 | /* file to avoid having to link against libdl.{a,so} if the client */ 20 | /* doesn't call dlopen. Of course this fails if the collector is in */ 21 | /* a dynamic library. -HB */ 22 | #if defined(GC_PTHREADS) && !defined(GC_NO_DLOPEN) 23 | 24 | #undef GC_MUST_RESTORE_REDEFINED_DLOPEN 25 | #if defined(dlopen) && !defined(GC_USE_LD_WRAP) 26 | /* To support various threads pkgs, gc.h interposes on dlopen by */ 27 | /* defining "dlopen" to be "GC_dlopen", which is implemented below. */ 28 | /* However, both GC_FirstDLOpenedLinkMap() and GC_dlopen() use the */ 29 | /* real system dlopen() in their implementation. We first remove */ 30 | /* gc.h's dlopen definition and restore it later, after GC_dlopen(). */ 31 | # undef dlopen 32 | # define GC_MUST_RESTORE_REDEFINED_DLOPEN 33 | #endif 34 | 35 | /* Make sure we're not in the middle of a collection, and make sure we */ 36 | /* don't start any. This is invoked prior to a dlopen call to avoid */ 37 | /* synchronization issues. We can't just acquire the allocation lock, */ 38 | /* since startup code in dlopen may try to allocate. This solution */ 39 | /* risks heap growth (or, even, heap overflow) in the presence of many */ 40 | /* dlopen calls in either a multi-threaded environment, or if the */ 41 | /* library initialization code allocates substantial amounts of GC'ed */ 42 | /* memory. */ 43 | #ifndef USE_PROC_FOR_LIBRARIES 44 | static void disable_gc_for_dlopen(void) 45 | { 46 | DCL_LOCK_STATE; 47 | LOCK(); 48 | while (GC_incremental && GC_collection_in_progress()) { 49 | GC_collect_a_little_inner(1000); 50 | } 51 | ++GC_dont_gc; 52 | UNLOCK(); 53 | } 54 | #endif 55 | 56 | /* Redefine dlopen to guarantee mutual exclusion with */ 57 | /* GC_register_dynamic_libraries. Should probably happen for */ 58 | /* other operating systems, too. */ 59 | 60 | /* This is similar to WRAP/REAL_FUNC() in pthread_support.c. */ 61 | #ifdef GC_USE_LD_WRAP 62 | # define WRAP_DLFUNC(f) __wrap_##f 63 | # define REAL_DLFUNC(f) __real_##f 64 | void * REAL_DLFUNC(dlopen)(const char *, int); 65 | #else 66 | # define WRAP_DLFUNC(f) GC_##f 67 | # define REAL_DLFUNC(f) f 68 | #endif 69 | 70 | GC_API void * WRAP_DLFUNC(dlopen)(const char *path, int mode) 71 | { 72 | void * result; 73 | 74 | # ifndef USE_PROC_FOR_LIBRARIES 75 | /* Disable collections. This solution risks heap growth (or, */ 76 | /* even, heap overflow) but there seems no better solutions. */ 77 | disable_gc_for_dlopen(); 78 | # endif 79 | result = REAL_DLFUNC(dlopen)(path, mode); 80 | # ifndef USE_PROC_FOR_LIBRARIES 81 | GC_enable(); /* undoes disable_gc_for_dlopen */ 82 | # endif 83 | return(result); 84 | } 85 | 86 | #ifdef GC_USE_LD_WRAP 87 | /* Define GC_ function as an alias for the plain one, which will be */ 88 | /* intercepted. This allows files which include gc.h, and hence */ 89 | /* generate references to the GC_ symbol, to see the right symbol. */ 90 | GC_API void *GC_dlopen(const char *path, int mode) 91 | { 92 | return dlopen(path, mode); 93 | } 94 | #endif /* GC_USE_LD_WRAP */ 95 | 96 | #ifdef GC_MUST_RESTORE_REDEFINED_DLOPEN 97 | # define dlopen GC_dlopen 98 | #endif 99 | 100 | #endif /* GC_PTHREADS && !GC_NO_DLOPEN */ 101 | -------------------------------------------------------------------------------- /windows-untested/vc60/test_leak_libgcmt.dsp: -------------------------------------------------------------------------------- 1 | # Microsoft Developer Studio Project File - Name="test_leak_libgcmt" - Package Owner=<4> 2 | # Microsoft Developer Studio Generated Build File, Format Version 6.00 3 | # ** DO NOT EDIT ** 4 | 5 | # TARGTYPE "Win32 (x86) Console Application" 0x0103 6 | 7 | CFG=test_leak_libgcmt - Win32 Debug 8 | !MESSAGE This is not a valid makefile. To build this project using NMAKE, 9 | !MESSAGE use the Export Makefile command and run 10 | !MESSAGE 11 | !MESSAGE NMAKE /f "test_leak_libgcmt.mak". 12 | !MESSAGE 13 | !MESSAGE You can specify a configuration when running NMAKE 14 | !MESSAGE by defining the macro CFG on the command line. For example: 15 | !MESSAGE 16 | !MESSAGE NMAKE /f "test_leak_libgcmt.mak" CFG="test_leak_libgcmt - Win32 Debug" 17 | !MESSAGE 18 | !MESSAGE Possible choices for configuration are: 19 | !MESSAGE 20 | !MESSAGE "test_leak_libgcmt - Win32 Release" (based on "Win32 (x86) Console Application") 21 | !MESSAGE "test_leak_libgcmt - Win32 Debug" (based on "Win32 (x86) Console Application") 22 | !MESSAGE 23 | 24 | # Begin Project 25 | # PROP AllowPerConfigDependencies 0 26 | # PROP Scc_ProjName "" 27 | # PROP Scc_LocalPath "" 28 | CPP=cl.exe 29 | RSC=rc.exe 30 | 31 | !IF "$(CFG)" == "test_leak_libgcmt - Win32 Release" 32 | 33 | # PROP BASE Use_MFC 0 34 | # PROP BASE Use_Debug_Libraries 0 35 | # PROP BASE Output_Dir "Release" 36 | # PROP BASE Intermediate_Dir "Release" 37 | # PROP BASE Target_Dir "" 38 | # PROP Use_MFC 0 39 | # PROP Use_Debug_Libraries 0 40 | # PROP Output_Dir "..\..\..\bin" 41 | # PROP Intermediate_Dir "..\..\..\obj\Release\test_leak_libgcmt" 42 | # PROP Ignore_Export_Lib 0 43 | # PROP Target_Dir "" 44 | # ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c 45 | # ADD CPP /nologo /MT /W3 /GX /Zi /O2 /I "..\..\include" /D "NDEBUG" /D "_CONSOLE" /D "WIN32" /D "_MBCS" /D "GC_THREADS" /FD /c 46 | # SUBTRACT CPP /Fr /YX 47 | # ADD BASE RSC /l 0x409 /d "NDEBUG" 48 | # ADD RSC /l 0x409 /d "NDEBUG" 49 | BSC32=bscmake.exe 50 | # ADD BASE BSC32 /nologo 51 | # ADD BSC32 /nologo 52 | LINK32=link.exe 53 | # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /machine:I386 54 | # ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /nologo /debug /machine:I386 /release /opt:ref 55 | # SUBTRACT LINK32 /pdb:none 56 | 57 | !ELSEIF "$(CFG)" == "test_leak_libgcmt - Win32 Debug" 58 | 59 | # PROP BASE Use_MFC 0 60 | # PROP BASE Use_Debug_Libraries 1 61 | # PROP BASE Output_Dir "Debug" 62 | # PROP BASE Intermediate_Dir "Debug" 63 | # PROP BASE Target_Dir "" 64 | # PROP Use_MFC 0 65 | # PROP Use_Debug_Libraries 1 66 | # PROP Output_Dir "..\..\..\bin" 67 | # PROP Intermediate_Dir "..\..\..\obj\Debug\test_leak_libgcmt" 68 | # PROP Ignore_Export_Lib 0 69 | # PROP Target_Dir "" 70 | # ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c 71 | # ADD CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /I "..\..\include" /D "_DEBUG" /D "_CONSOLE" /D "WIN32" /D "_MBCS" /D "GC_THREADS" /YX /FD /GZ /c 72 | # SUBTRACT CPP /Fr 73 | # ADD BASE RSC /l 0x409 /d "_DEBUG" 74 | # ADD RSC /l 0x409 /d "_DEBUG" 75 | BSC32=bscmake.exe 76 | # ADD BASE BSC32 /nologo 77 | # ADD BSC32 /nologo /o"..\..\..\bin/test_leak_libgcmtd.bsc" 78 | LINK32=link.exe 79 | # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /debug /machine:I386 /pdbtype:sept 80 | # ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /nologo /incremental:no /debug /machine:I386 /out:"..\..\..\bin/test_leak_libgcmtd.exe" /pdbtype:sept 81 | 82 | !ENDIF 83 | 84 | # Begin Target 85 | 86 | # Name "test_leak_libgcmt - Win32 Release" 87 | # Name "test_leak_libgcmt - Win32 Debug" 88 | # Begin Source File 89 | 90 | SOURCE=..\..\tests\leak_test.c 91 | # End Source File 92 | # End Target 93 | # End Project 94 | -------------------------------------------------------------------------------- /include/gc_backptr.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1994 by Xerox Corporation. All rights reserved. 3 | * Copyright (c) 1996 by Silicon Graphics. All rights reserved. 4 | * Copyright (c) 1998 by Fergus Henderson. All rights reserved. 5 | * Copyright (c) 2000-2009 by Hewlett-Packard Development Company. 6 | * All rights reserved. 7 | * 8 | * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED 9 | * OR IMPLIED. ANY USE IS AT YOUR OWN RISK. 10 | * 11 | * Permission is hereby granted to use or copy this program 12 | * for any purpose, provided the above notices are retained on all copies. 13 | * Permission to modify the code and to distribute modified code is granted, 14 | * provided the above notices are retained, and a notice that the code was 15 | * modified is included with the above copyright notice. 16 | */ 17 | 18 | /* 19 | * This is a simple API to implement pointer back tracing, i.e. 20 | * to answer questions such as "who is pointing to this" or 21 | * "why is this object being retained by the collector" 22 | * 23 | * Most of these calls yield useful information on only after 24 | * a garbage collection. Usually the client will first force 25 | * a full collection and then gather information, preferably 26 | * before much intervening allocation. 27 | * 28 | * The implementation of the interface is only about 99.9999% 29 | * correct. It is intended to be good enough for profiling, 30 | * but is not intended to be used with production code. 31 | * 32 | * Results are likely to be much more useful if all allocation is 33 | * accomplished through the debugging allocators. 34 | * 35 | * The implementation idea is due to A. Demers. 36 | */ 37 | 38 | #ifndef GC_BACKPTR_H 39 | #define GC_BACKPTR_H 40 | 41 | #ifndef GC_H 42 | # include "gc.h" 43 | #endif 44 | 45 | #ifdef __cplusplus 46 | extern "C" { 47 | #endif 48 | 49 | /* Store information about the object referencing dest in *base_p */ 50 | /* and *offset_p. */ 51 | /* If multiple objects or roots point to dest, the one reported */ 52 | /* will be the last on used by the garbage collector to trace the */ 53 | /* object. */ 54 | /* source is root ==> *base_p = address, *offset_p = 0 */ 55 | /* source is heap object ==> *base_p != 0, *offset_p = offset */ 56 | /* Returns 1 on success, 0 if source couldn't be determined. */ 57 | /* Dest can be any address within a heap object. */ 58 | typedef enum { 59 | GC_UNREFERENCED, /* No reference info available. */ 60 | GC_NO_SPACE, /* Dest not allocated with debug alloc. */ 61 | GC_REFD_FROM_ROOT, /* Referenced directly by root *base_p. */ 62 | GC_REFD_FROM_REG, /* Referenced from a register, i.e. */ 63 | /* a root without an address. */ 64 | GC_REFD_FROM_HEAP, /* Referenced from another heap obj. */ 65 | GC_FINALIZER_REFD /* Finalizable and hence accessible. */ 66 | } GC_ref_kind; 67 | 68 | GC_API GC_ref_kind GC_CALL GC_get_back_ptr_info(void * /* dest */, 69 | void ** /* base_p */, size_t * /* offset_p */) 70 | GC_ATTR_NONNULL(1); 71 | 72 | /* Generate a random heap address. */ 73 | /* The resulting address is in the heap, but */ 74 | /* not necessarily inside a valid object. */ 75 | GC_API void * GC_CALL GC_generate_random_heap_address(void); 76 | 77 | /* Generate a random address inside a valid marked heap object. */ 78 | GC_API void * GC_CALL GC_generate_random_valid_address(void); 79 | 80 | /* Force a garbage collection and generate a backtrace from a */ 81 | /* random heap address. */ 82 | /* This uses the GC logging mechanism (GC_printf) to produce */ 83 | /* output. It can often be called from a debugger. The */ 84 | /* source in dbg_mlc.c also serves as a sample client. */ 85 | GC_API void GC_CALL GC_generate_random_backtrace(void); 86 | 87 | /* Print a backtrace from a specific address. Used by the */ 88 | /* above. The client should call GC_gcollect() immediately */ 89 | /* before invocation. */ 90 | GC_API void GC_CALL GC_print_backtrace(void *) GC_ATTR_NONNULL(1); 91 | 92 | #ifdef __cplusplus 93 | } /* extern "C" */ 94 | #endif 95 | 96 | #endif /* GC_BACKPTR_H */ 97 | -------------------------------------------------------------------------------- /windows-untested/vc60/gc.dsw: -------------------------------------------------------------------------------- 1 | Microsoft Developer Studio Workspace File, Format Version 6.00 2 | # WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! 3 | 4 | ############################################################################### 5 | 6 | Project: "all"=".\all.dsp" - Package Owner=<4> 7 | 8 | Package=<5> 9 | {{{ 10 | }}} 11 | 12 | Package=<4> 13 | {{{ 14 | Begin Project Dependency 15 | Project_Dep_Name gc 16 | End Project Dependency 17 | Begin Project Dependency 18 | Project_Dep_Name libgc 19 | End Project Dependency 20 | Begin Project Dependency 21 | Project_Dep_Name libgcmt 22 | End Project Dependency 23 | }}} 24 | 25 | ############################################################################### 26 | 27 | Project: "gc"=".\gc.dsp" - Package Owner=<4> 28 | 29 | Package=<5> 30 | {{{ 31 | }}} 32 | 33 | Package=<4> 34 | {{{ 35 | }}} 36 | 37 | ############################################################################### 38 | 39 | Project: "libgc"=".\libgc.dsp" - Package Owner=<4> 40 | 41 | Package=<5> 42 | {{{ 43 | }}} 44 | 45 | Package=<4> 46 | {{{ 47 | }}} 48 | 49 | ############################################################################### 50 | 51 | Project: "libgcmt"=".\libgcmt.dsp" - Package Owner=<4> 52 | 53 | Package=<5> 54 | {{{ 55 | }}} 56 | 57 | Package=<4> 58 | {{{ 59 | }}} 60 | 61 | ############################################################################### 62 | 63 | Project: "test"=".\test.dsp" - Package Owner=<4> 64 | 65 | Package=<5> 66 | {{{ 67 | }}} 68 | 69 | Package=<4> 70 | {{{ 71 | Begin Project Dependency 72 | Project_Dep_Name test_gc 73 | End Project Dependency 74 | Begin Project Dependency 75 | Project_Dep_Name test_libgc 76 | End Project Dependency 77 | Begin Project Dependency 78 | Project_Dep_Name test_libgcmt 79 | End Project Dependency 80 | Begin Project Dependency 81 | Project_Dep_Name test_leak_gc 82 | End Project Dependency 83 | Begin Project Dependency 84 | Project_Dep_Name test_leak_libgc 85 | End Project Dependency 86 | Begin Project Dependency 87 | Project_Dep_Name test_leak_libgcmt 88 | End Project Dependency 89 | }}} 90 | 91 | ############################################################################### 92 | 93 | Project: "test_gc"=".\test_gc.dsp" - Package Owner=<4> 94 | 95 | Package=<5> 96 | {{{ 97 | }}} 98 | 99 | Package=<4> 100 | {{{ 101 | Begin Project Dependency 102 | Project_Dep_Name gc 103 | End Project Dependency 104 | }}} 105 | 106 | ############################################################################### 107 | 108 | Project: "test_leak_gc"=".\test_leak_gc.dsp" - Package Owner=<4> 109 | 110 | Package=<5> 111 | {{{ 112 | }}} 113 | 114 | Package=<4> 115 | {{{ 116 | Begin Project Dependency 117 | Project_Dep_Name gc 118 | End Project Dependency 119 | }}} 120 | 121 | ############################################################################### 122 | 123 | Project: "test_leak_libgc"=".\test_leak_libgc.dsp" - Package Owner=<4> 124 | 125 | Package=<5> 126 | {{{ 127 | }}} 128 | 129 | Package=<4> 130 | {{{ 131 | Begin Project Dependency 132 | Project_Dep_Name libgc 133 | End Project Dependency 134 | }}} 135 | 136 | ############################################################################### 137 | 138 | Project: "test_leak_libgcmt"=".\test_leak_libgcmt.dsp" - Package Owner=<4> 139 | 140 | Package=<5> 141 | {{{ 142 | }}} 143 | 144 | Package=<4> 145 | {{{ 146 | Begin Project Dependency 147 | Project_Dep_Name libgcmt 148 | End Project Dependency 149 | }}} 150 | 151 | ############################################################################### 152 | 153 | Project: "test_libgc"=".\test_libgc.dsp" - Package Owner=<4> 154 | 155 | Package=<5> 156 | {{{ 157 | }}} 158 | 159 | Package=<4> 160 | {{{ 161 | Begin Project Dependency 162 | Project_Dep_Name libgc 163 | End Project Dependency 164 | }}} 165 | 166 | ############################################################################### 167 | 168 | Project: "test_libgcmt"=".\test_libgcmt.dsp" - Package Owner=<4> 169 | 170 | Package=<5> 171 | {{{ 172 | }}} 173 | 174 | Package=<4> 175 | {{{ 176 | Begin Project Dependency 177 | Project_Dep_Name libgcmt 178 | End Project Dependency 179 | }}} 180 | 181 | ############################################################################### 182 | 183 | Global: 184 | 185 | Package=<5> 186 | {{{ 187 | }}} 188 | 189 | Package=<3> 190 | {{{ 191 | }}} 192 | 193 | ############################################################################### 194 | 195 | -------------------------------------------------------------------------------- /include/private/specific.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This is a reimplementation of a subset of the pthread_getspecific/setspecific 3 | * interface. This appears to outperform the standard linuxthreads one 4 | * by a significant margin. 5 | * The major restriction is that each thread may only make a single 6 | * pthread_setspecific call on a single key. (The current data structure 7 | * doesn't really require that. The restriction should be easily removable.) 8 | * We don't currently support the destruction functions, though that 9 | * could be done. 10 | * We also currently assume that only one pthread_setspecific call 11 | * can be executed at a time, though that assumption would be easy to remove 12 | * by adding a lock. 13 | */ 14 | 15 | #include 16 | 17 | EXTERN_C_BEGIN 18 | 19 | /* Called during key creation or setspecific. */ 20 | /* For the GC we already hold lock. */ 21 | /* Currently allocated objects leak on thread exit. */ 22 | /* That's hard to fix, but OK if we allocate garbage */ 23 | /* collected memory. */ 24 | #define MALLOC_CLEAR(n) GC_INTERNAL_MALLOC(n, NORMAL) 25 | 26 | #define TS_CACHE_SIZE 1024 27 | #define CACHE_HASH(n) ((((n) >> 8) ^ (n)) & (TS_CACHE_SIZE - 1)) 28 | 29 | #define TS_HASH_SIZE 1024 30 | #define HASH(p) \ 31 | ((unsigned)((((word)(p)) >> 8) ^ (word)(p)) & (TS_HASH_SIZE - 1)) 32 | 33 | /* An entry describing a thread-specific value for a given thread. */ 34 | /* All such accessible structures preserve the invariant that if either */ 35 | /* thread is a valid pthread id or qtid is a valid "quick thread id" */ 36 | /* for a thread, then value holds the corresponding thread specific */ 37 | /* value. This invariant must be preserved at ALL times, since */ 38 | /* asynchronous reads are allowed. */ 39 | typedef struct thread_specific_entry { 40 | volatile AO_t qtid; /* quick thread id, only for cache */ 41 | void * value; 42 | struct thread_specific_entry *next; 43 | pthread_t thread; 44 | } tse; 45 | 46 | /* We represent each thread-specific datum as two tables. The first is */ 47 | /* a cache, indexed by a "quick thread identifier". The "quick" thread */ 48 | /* identifier is an easy to compute value, which is guaranteed to */ 49 | /* determine the thread, though a thread may correspond to more than */ 50 | /* one value. We typically use the address of a page in the stack. */ 51 | /* The second is a hash table, indexed by pthread_self(). It is used */ 52 | /* only as a backup. */ 53 | 54 | /* Return the "quick thread id". Default version. Assumes page size, */ 55 | /* or at least thread stack separation, is at least 4K. */ 56 | /* Must be defined so that it never returns 0. (Page 0 can't really be */ 57 | /* part of any stack, since that would make 0 a valid stack pointer.) */ 58 | #define quick_thread_id() (((word)GC_approx_sp()) >> 12) 59 | 60 | #define INVALID_QTID ((word)0) 61 | #define INVALID_THREADID ((pthread_t)0) 62 | 63 | union ptse_ao_u { 64 | tse *p; 65 | volatile AO_t ao; 66 | }; 67 | 68 | typedef struct thread_specific_data { 69 | tse * volatile cache[TS_CACHE_SIZE]; 70 | /* A faster index to the hash table */ 71 | union ptse_ao_u hash[TS_HASH_SIZE]; 72 | pthread_mutex_t lock; 73 | } tsd; 74 | 75 | typedef tsd * GC_key_t; 76 | 77 | #define GC_key_create(key, d) GC_key_create_inner(key) 78 | GC_INNER int GC_key_create_inner(tsd ** key_ptr); 79 | GC_INNER int GC_setspecific(tsd * key, void * value); 80 | #define GC_remove_specific(key) \ 81 | GC_remove_specific_after_fork(key, pthread_self()) 82 | GC_INNER void GC_remove_specific_after_fork(tsd * key, pthread_t t); 83 | 84 | /* An internal version of getspecific that assumes a cache miss. */ 85 | GC_INNER void * GC_slow_getspecific(tsd * key, word qtid, 86 | tse * volatile * cache_entry); 87 | 88 | /* GC_INLINE is defined in gc_priv.h. */ 89 | GC_INLINE void * GC_getspecific(tsd * key) 90 | { 91 | word qtid = quick_thread_id(); 92 | tse * volatile * entry_ptr = &key->cache[CACHE_HASH(qtid)]; 93 | tse * entry = *entry_ptr; /* Must be loaded only once. */ 94 | 95 | GC_ASSERT(qtid != INVALID_QTID); 96 | if (EXPECT(entry -> qtid == qtid, TRUE)) { 97 | GC_ASSERT(entry -> thread == pthread_self()); 98 | return entry -> value; 99 | } 100 | return GC_slow_getspecific(key, qtid, entry_ptr); 101 | } 102 | 103 | EXTERN_C_END 104 | -------------------------------------------------------------------------------- /include/private/gc_atomic_ops.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017 Ivan Maidanski 3 | * 4 | * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED 5 | * OR IMPLIED. ANY USE IS AT YOUR OWN RISK. 6 | * 7 | * Permission is hereby granted to use or copy this program 8 | * for any purpose, provided the above notices are retained on all copies. 9 | * Permission to modify the code and to distribute modified code is granted, 10 | * provided the above notices are retained, and a notice that the code was 11 | * modified is included with the above copyright notice. 12 | */ 13 | 14 | /* This is a private GC header which provides an implementation of */ 15 | /* libatomic_ops subset primitives sufficient for GC assuming that C11 */ 16 | /* atomic intrinsics are available (and have correct implementation). */ 17 | /* This is enabled by defining GC_BUILTIN_ATOMIC macro. Otherwise, */ 18 | /* libatomic_ops library is used to define the primitives. */ 19 | 20 | #ifndef GC_ATOMIC_OPS_H 21 | #define GC_ATOMIC_OPS_H 22 | 23 | #ifdef GC_BUILTIN_ATOMIC 24 | 25 | # include "gc.h" /* for GC_word */ 26 | 27 | # ifdef __cplusplus 28 | extern "C" { 29 | # endif 30 | 31 | typedef GC_word AO_t; 32 | 33 | # ifdef GC_PRIVATE_H /* have GC_INLINE */ 34 | # define AO_INLINE GC_INLINE 35 | # else 36 | # define AO_INLINE static __inline 37 | # endif 38 | 39 | typedef unsigned char AO_TS_t; 40 | # define AO_TS_CLEAR 0 41 | # define AO_TS_INITIALIZER (AO_TS_t)AO_TS_CLEAR 42 | # if defined(__GCC_ATOMIC_TEST_AND_SET_TRUEVAL) && !defined(CPPCHECK) 43 | # define AO_TS_SET __GCC_ATOMIC_TEST_AND_SET_TRUEVAL 44 | # else 45 | # define AO_TS_SET (AO_TS_t)1 /* true */ 46 | # endif 47 | # define AO_CLEAR(p) __atomic_clear(p, __ATOMIC_RELEASE) 48 | # define AO_test_and_set_acquire(p) __atomic_test_and_set(p, __ATOMIC_ACQUIRE) 49 | # define AO_HAVE_test_and_set_acquire 50 | 51 | # define AO_compiler_barrier() __atomic_signal_fence(__ATOMIC_SEQ_CST) 52 | # define AO_nop_full() __atomic_thread_fence(__ATOMIC_SEQ_CST) 53 | # define AO_HAVE_nop_full 54 | 55 | # define AO_fetch_and_add(p, v) __atomic_fetch_add(p, v, __ATOMIC_RELAXED) 56 | # define AO_HAVE_fetch_and_add 57 | # define AO_fetch_and_add1(p) AO_fetch_and_add(p, 1) 58 | # define AO_HAVE_fetch_and_add1 59 | 60 | # define AO_or(p, v) (void)__atomic_or_fetch(p, v, __ATOMIC_RELAXED) 61 | # define AO_HAVE_or 62 | 63 | # define AO_load(p) __atomic_load_n(p, __ATOMIC_RELAXED) 64 | # define AO_HAVE_load 65 | # define AO_load_acquire(p) __atomic_load_n(p, __ATOMIC_ACQUIRE) 66 | # define AO_HAVE_load_acquire 67 | # define AO_load_acquire_read(p) AO_load_acquire(p) 68 | # define AO_HAVE_load_acquire_read 69 | 70 | # define AO_store(p, v) __atomic_store_n(p, v, __ATOMIC_RELAXED) 71 | # define AO_HAVE_store 72 | # define AO_store_release(p, v) __atomic_store_n(p, v, __ATOMIC_RELEASE) 73 | # define AO_HAVE_store_release 74 | # define AO_store_release_write(p, v) AO_store_release(p, v) 75 | # define AO_HAVE_store_release_write 76 | 77 | # define AO_char_load(p) __atomic_load_n(p, __ATOMIC_RELAXED) 78 | # define AO_HAVE_char_load 79 | # define AO_char_store(p, v) __atomic_store_n(p, v, __ATOMIC_RELAXED) 80 | # define AO_HAVE_char_store 81 | 82 | # ifdef AO_REQUIRE_CAS 83 | AO_INLINE int 84 | AO_compare_and_swap(volatile AO_t *p, AO_t ov, AO_t nv) 85 | { 86 | return (int)__atomic_compare_exchange_n(p, &ov, nv, 0, 87 | __ATOMIC_RELAXED, __ATOMIC_RELAXED); 88 | } 89 | 90 | AO_INLINE int 91 | AO_compare_and_swap_release(volatile AO_t *p, AO_t ov, AO_t nv) 92 | { 93 | return (int)__atomic_compare_exchange_n(p, &ov, nv, 0, 94 | __ATOMIC_RELEASE, __ATOMIC_RELAXED); 95 | } 96 | # define AO_HAVE_compare_and_swap_release 97 | # endif 98 | 99 | # ifdef __cplusplus 100 | } /* extern "C" */ 101 | # endif 102 | 103 | #elif !defined(NN_PLATFORM_CTR) 104 | /* Fallback to libatomic_ops. */ 105 | # include "atomic_ops.h" 106 | 107 | /* AO_compiler_barrier, AO_load and AO_store should be defined for */ 108 | /* all targets; the rest of the primitives are guaranteed to exist */ 109 | /* only if AO_REQUIRE_CAS is defined (or if the corresponding */ 110 | /* AO_HAVE_x macro is defined). x86/x64 targets have AO_nop_full, */ 111 | /* AO_load_acquire, AO_store_release, at least. */ 112 | # if !defined(AO_HAVE_load) || !defined(AO_HAVE_store) 113 | # error AO_load or AO_store is missing; probably old version of atomic_ops 114 | # endif 115 | 116 | #endif /* !GC_BUILTIN_ATOMIC */ 117 | 118 | #endif /* GC_ATOMIC_OPS_H */ 119 | -------------------------------------------------------------------------------- /include/gc_pthread_redirects.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1994 by Xerox Corporation. All rights reserved. 3 | * Copyright (c) 1996 by Silicon Graphics. All rights reserved. 4 | * Copyright (c) 1998 by Fergus Henderson. All rights reserved. 5 | * Copyright (c) 2000-2010 by Hewlett-Packard Development Company. 6 | * All rights reserved. 7 | * 8 | * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED 9 | * OR IMPLIED. ANY USE IS AT YOUR OWN RISK. 10 | * 11 | * Permission is hereby granted to use or copy this program 12 | * for any purpose, provided the above notices are retained on all copies. 13 | * Permission to modify the code and to distribute modified code is granted, 14 | * provided the above notices are retained, and a notice that the code was 15 | * modified is included with the above copyright notice. 16 | */ 17 | 18 | /* Our pthread support normally needs to intercept a number of thread */ 19 | /* calls. We arrange to do that here, if appropriate. */ 20 | 21 | /* Included from gc.h only. Included only if GC_PTHREADS. */ 22 | #if defined(GC_H) && defined(GC_PTHREADS) 23 | 24 | /* We need to intercept calls to many of the threads primitives, so */ 25 | /* that we can locate thread stacks and stop the world. */ 26 | /* Note also that the collector cannot always see thread specific data. */ 27 | /* Thread specific data should generally consist of pointers to */ 28 | /* uncollectible objects (allocated with GC_malloc_uncollectable, */ 29 | /* not the system malloc), which are deallocated using the destructor */ 30 | /* facility in thr_keycreate. Alternatively, keep a redundant pointer */ 31 | /* to thread specific data on the thread stack. */ 32 | 33 | #ifndef GC_PTHREAD_REDIRECTS_ONLY 34 | 35 | # include 36 | # ifndef GC_NO_DLOPEN 37 | # include 38 | # endif 39 | # ifndef GC_NO_PTHREAD_SIGMASK 40 | # include /* needed anyway for proper redirection */ 41 | # endif 42 | 43 | # ifdef __cplusplus 44 | extern "C" { 45 | # endif 46 | 47 | # ifndef GC_SUSPEND_THREAD_ID 48 | # define GC_SUSPEND_THREAD_ID pthread_t 49 | # endif 50 | 51 | # ifndef GC_NO_DLOPEN 52 | GC_API void *GC_dlopen(const char * /* path */, int /* mode */); 53 | # endif /* !GC_NO_DLOPEN */ 54 | 55 | # ifndef GC_NO_PTHREAD_SIGMASK 56 | # if defined(GC_PTHREAD_SIGMASK_NEEDED) \ 57 | || defined(_BSD_SOURCE) || defined(_GNU_SOURCE) \ 58 | || (_POSIX_C_SOURCE >= 199506L) || (_XOPEN_SOURCE >= 500) 59 | GC_API int GC_pthread_sigmask(int /* how */, const sigset_t *, 60 | sigset_t * /* oset */); 61 | # endif 62 | # endif /* !GC_NO_PTHREAD_SIGMASK */ 63 | 64 | # ifndef GC_PTHREAD_CREATE_CONST 65 | /* This is used for pthread_create() only. */ 66 | # define GC_PTHREAD_CREATE_CONST const 67 | # endif 68 | 69 | GC_API int GC_pthread_create(pthread_t *, 70 | GC_PTHREAD_CREATE_CONST pthread_attr_t *, 71 | void *(*)(void *), void * /* arg */); 72 | GC_API int GC_pthread_join(pthread_t, void ** /* retval */); 73 | GC_API int GC_pthread_detach(pthread_t); 74 | 75 | # ifndef GC_NO_PTHREAD_CANCEL 76 | GC_API int GC_pthread_cancel(pthread_t); 77 | # endif 78 | 79 | # if defined(GC_HAVE_PTHREAD_EXIT) && !defined(GC_PTHREAD_EXIT_DECLARED) 80 | # define GC_PTHREAD_EXIT_DECLARED 81 | GC_API void GC_pthread_exit(void *) GC_PTHREAD_EXIT_ATTRIBUTE; 82 | # endif 83 | 84 | # ifdef __cplusplus 85 | } /* extern "C" */ 86 | # endif 87 | 88 | #endif /* !GC_PTHREAD_REDIRECTS_ONLY */ 89 | 90 | #if !defined(GC_NO_THREAD_REDIRECTS) && !defined(GC_USE_LD_WRAP) 91 | /* Unless the compiler supports #pragma extern_prefix, the Tru64 */ 92 | /* UNIX redefines some POSIX thread functions to use */ 93 | /* mangled names. Anyway, it's safe to undef them before redefining. */ 94 | # undef pthread_create 95 | # undef pthread_join 96 | # undef pthread_detach 97 | # define pthread_create GC_pthread_create 98 | # define pthread_join GC_pthread_join 99 | # define pthread_detach GC_pthread_detach 100 | 101 | # ifndef GC_NO_PTHREAD_SIGMASK 102 | # undef pthread_sigmask 103 | # define pthread_sigmask GC_pthread_sigmask 104 | # endif 105 | # ifndef GC_NO_DLOPEN 106 | # undef dlopen 107 | # define dlopen GC_dlopen 108 | # endif 109 | # ifndef GC_NO_PTHREAD_CANCEL 110 | # undef pthread_cancel 111 | # define pthread_cancel GC_pthread_cancel 112 | # endif 113 | # ifdef GC_HAVE_PTHREAD_EXIT 114 | # undef pthread_exit 115 | # define pthread_exit GC_pthread_exit 116 | # endif 117 | #endif /* !GC_NO_THREAD_REDIRECTS */ 118 | 119 | #endif /* GC_PTHREADS */ 120 | -------------------------------------------------------------------------------- /tests/subthread_create.c: -------------------------------------------------------------------------------- 1 | 2 | #ifdef HAVE_CONFIG_H 3 | /* For PARALLEL_MARK */ 4 | # include "config.h" 5 | #endif 6 | 7 | #ifndef GC_THREADS 8 | # define GC_THREADS 9 | #endif 10 | #include "gc.h" 11 | 12 | #ifdef PARALLEL_MARK 13 | # define AO_REQUIRE_CAS 14 | #endif 15 | #include "private/gc_atomic_ops.h" 16 | 17 | #include 18 | 19 | #ifdef AO_HAVE_fetch_and_add1 20 | 21 | #ifdef GC_PTHREADS 22 | # include 23 | #else 24 | # include 25 | #endif 26 | 27 | #if defined(__HAIKU__) 28 | # include 29 | #endif 30 | 31 | #include 32 | #include 33 | 34 | #ifndef NTHREADS 35 | # define NTHREADS 31 /* number of initial threads */ 36 | #endif 37 | 38 | #ifndef MAX_SUBTHREAD_DEPTH 39 | # define MAX_ALIVE_THREAD_COUNT 55 40 | # define MAX_SUBTHREAD_DEPTH 7 41 | # define MAX_SUBTHREAD_COUNT 200 42 | #endif 43 | 44 | #ifndef DECAY_NUMER 45 | # define DECAY_NUMER 15 46 | # define DECAY_DENOM 16 47 | #endif 48 | 49 | volatile AO_t thread_created_cnt = 0; 50 | volatile AO_t thread_ended_cnt = 0; 51 | 52 | #ifdef GC_PTHREADS 53 | void *entry(void *arg) 54 | #else 55 | DWORD WINAPI entry(LPVOID arg) 56 | #endif 57 | { 58 | int thread_num = AO_fetch_and_add1(&thread_created_cnt); 59 | GC_word my_depth = (GC_word)arg + 1; 60 | 61 | if (my_depth <= MAX_SUBTHREAD_DEPTH 62 | && thread_num < MAX_SUBTHREAD_COUNT 63 | && (thread_num % DECAY_DENOM) < DECAY_NUMER 64 | && thread_num - (int)AO_load(&thread_ended_cnt) 65 | <= MAX_ALIVE_THREAD_COUNT) { 66 | # ifdef GC_PTHREADS 67 | int err; 68 | pthread_t th; 69 | 70 | err = pthread_create(&th, NULL, entry, (void *)my_depth); 71 | if (err != 0) { 72 | fprintf(stderr, "Thread #%d creation failed: %s\n", thread_num, 73 | strerror(err)); 74 | exit(2); 75 | } 76 | err = pthread_detach(th); 77 | if (err != 0) { 78 | fprintf(stderr, "Thread #%d detach failed: %s\n", thread_num, 79 | strerror(err)); 80 | exit(2); 81 | } 82 | # else 83 | HANDLE th; 84 | DWORD thread_id; 85 | 86 | th = CreateThread(NULL, 0, entry, (LPVOID)my_depth, 0, &thread_id); 87 | if (th == NULL) { 88 | fprintf(stderr, "Thread #%d creation failed: %d\n", thread_num, 89 | (int)GetLastError()); 90 | exit(2); 91 | } 92 | CloseHandle(th); 93 | # endif 94 | } 95 | 96 | (void)AO_fetch_and_add1(&thread_ended_cnt); 97 | return 0; 98 | } 99 | 100 | int main(void) 101 | { 102 | #if NTHREADS > 0 103 | int i; 104 | # ifdef GC_PTHREADS 105 | int err; 106 | pthread_t th[NTHREADS]; 107 | # else 108 | HANDLE th[NTHREADS]; 109 | # endif 110 | 111 | GC_INIT(); 112 | for (i = 0; i < NTHREADS; ++i) { 113 | # ifdef GC_PTHREADS 114 | err = pthread_create(&th[i], NULL, entry, 0); 115 | if (err) { 116 | fprintf(stderr, "Thread creation failed: %s\n", strerror(err)); 117 | exit(1); 118 | } 119 | # else 120 | DWORD thread_id; 121 | th[i] = CreateThread(NULL, 0, entry, 0, 0, &thread_id); 122 | if (th[i] == NULL) { 123 | fprintf(stderr, "Thread creation failed: %d\n", 124 | (int)GetLastError()); 125 | exit(1); 126 | } 127 | # endif 128 | } 129 | 130 | for (i = 0; i < NTHREADS; ++i) { 131 | # ifdef GC_PTHREADS 132 | void *res; 133 | err = pthread_join(th[i], &res); 134 | if (err) { 135 | fprintf(stderr, "Failed to join thread: %s\n", strerror(err)); 136 | # if defined(__HAIKU__) 137 | /* The error is just ignored (and the test is ended) to */ 138 | /* workaround some bug in Haiku pthread_join. */ 139 | /* TODO: The thread is not deleted from GC_threads. */ 140 | if (ESRCH == err) break; 141 | # endif 142 | exit(1); 143 | } 144 | # else 145 | if (WaitForSingleObject(th[i], INFINITE) != WAIT_OBJECT_0) { 146 | fprintf(stderr, "Failed to join thread: %d\n", 147 | (int)GetLastError()); 148 | CloseHandle(th[i]); 149 | exit(1); 150 | } 151 | CloseHandle(th[i]); 152 | # endif 153 | } 154 | #endif 155 | printf("subthread_create: created %d threads (%d ended)\n", 156 | (int)AO_load(&thread_created_cnt), (int)AO_load(&thread_ended_cnt)); 157 | return 0; 158 | } 159 | 160 | #else 161 | 162 | int main(void) 163 | { 164 | printf("subthread_create test skipped\n"); 165 | return 0; 166 | } 167 | 168 | #endif /* !AO_HAVE_fetch_and_add1 */ 169 | --------------------------------------------------------------------------------