diff options
Diffstat (limited to 'include')
-rw-r--r-- | include/gc.h | 48 | ||||
-rw-r--r-- | include/gc_mark.h | 16 | ||||
-rw-r--r-- | include/private/gc_priv.h | 86 | ||||
-rw-r--r-- | include/private/gcconfig.h | 18 |
4 files changed, 120 insertions, 48 deletions
diff --git a/include/gc.h b/include/gc.h index 83444af4..7b9cbfe4 100644 --- a/include/gc.h +++ b/include/gc.h @@ -365,12 +365,29 @@ GC_API int GC_CALL GC_get_pages_executable(void); /* Overrides the default handle-fork mode. Non-zero value means GC */ /* should install proper pthread_atfork handlers. Has effect only if */ -/* called before GC_INIT. Clients should invoke GC_set_handle_fork(1) */ -/* only if going to use fork with GC functions called in the forked */ -/* child. (Note that such client and atfork handlers activities are */ -/* not fully POSIX-compliant.) */ +/* called before GC_INIT. Clients should invoke GC_set_handle_fork */ +/* with non-zero argument if going to use fork with GC functions called */ +/* in the forked child. (Note that such client and atfork handlers */ +/* activities are not fully POSIX-compliant.) GC_set_handle_fork */ +/* instructs GC_init to setup GC fork handlers using pthread_atfork, */ +/* the latter might fail (or, even, absent on some targets) causing */ +/* abort at GC initialization. Starting from 7.3alpha3, problems with */ +/* missing (or failed) pthread_atfork() could be avoided by invocation */ +/* of GC_set_handle_fork(-1) at application start-up and surrounding */ +/* each fork() with the relevant GC_atfork_prepare/parent/child calls. */ GC_API void GC_CALL GC_set_handle_fork(int); +/* Routines to handle POSIX fork() manually (no-op if handled */ +/* automatically). GC_atfork_prepare should be called immediately */ +/* before fork(); GC_atfork_parent should be invoked just after fork in */ +/* the branch that corresponds to parent process (i.e., fork result is */ +/* non-zero); GC_atfork_child is to be called immediately in the child */ +/* branch (i.e., fork result is 0). Note that GC_atfork_child() call */ +/* should, of course, precede GC_start_mark_threads call (if any). */ +GC_API void GC_CALL GC_atfork_prepare(void); +GC_API void GC_CALL GC_atfork_parent(void); +GC_API void GC_CALL GC_atfork_child(void); + /* Initialize the collector. Portable clients should call GC_INIT() */ /* from the main program instead. */ GC_API void GC_CALL GC_init(void); @@ -1243,6 +1260,10 @@ GC_API void * GC_CALL GC_call_with_stack_base(GC_stack_base_func /* fn */, /* systems. Return -1 otherwise. */ GC_API int GC_CALL GC_get_thr_restart_signal(void); + /* Restart marker threads after POSIX fork in child. Meaningless in */ + /* other situations. Should not be called if fork followed by exec. */ + GC_API void GC_CALL GC_start_mark_threads(void); + /* Explicitly enable GC_register_my_thread() invocation. */ /* Done implicitly if a GC thread-creation function is called (or */ /* implicit thread registration is activated). Otherwise, it must */ @@ -1451,7 +1472,7 @@ GC_API void GC_CALL GC_register_has_static_roots_callback( /* Note: for Cygwin and win32-pthread, this is skipped */ /* unless windows.h is included before gc.h. */ -# ifndef GC_NO_THREAD_DECLS +# if !defined(GC_NO_THREAD_DECLS) || defined(GC_BUILD) # ifdef __cplusplus } /* Including windows.h in an extern "C" context no longer works. */ @@ -1483,6 +1504,14 @@ GC_API void GC_CALL GC_register_has_static_roots_callback( LPVOID /* reserved */); # endif /* GC_INSIDE_DLL */ +# if !defined(_UINTPTR_T) && !defined(_UINTPTR_T_DEFINED) \ + && !defined(UINTPTR_MAX) + typedef GC_word GC_uintptr_t; +# else + typedef uintptr_t GC_uintptr_t; +# endif +# define GC_WIN32_SIZE_T GC_uintptr_t + /* All threads must be created using GC_CreateThread or */ /* GC_beginthreadex, or must explicitly call GC_register_my_thread */ /* (and call GC_unregister_my_thread before thread termination), so */ @@ -1495,7 +1524,7 @@ GC_API void GC_CALL GC_register_has_static_roots_callback( /* so that the thread is properly unregistered. */ GC_API HANDLE WINAPI GC_CreateThread( LPSECURITY_ATTRIBUTES /* lpThreadAttributes */, - DWORD /* dwStackSize */, + GC_WIN32_SIZE_T /* dwStackSize */, LPTHREAD_START_ROUTINE /* lpStartAddress */, LPVOID /* lpParameter */, DWORD /* dwCreationFlags */, LPDWORD /* lpThreadId */); @@ -1509,13 +1538,6 @@ GC_API void GC_CALL GC_register_has_static_roots_callback( DWORD /* dwExitCode */); # if !defined(_WIN32_WCE) && !defined(__CEGCC__) -# if !defined(_UINTPTR_T) && !defined(_UINTPTR_T_DEFINED) \ - && !defined(UINTPTR_MAX) - typedef GC_word GC_uintptr_t; -# else - typedef uintptr_t GC_uintptr_t; -# endif - GC_API GC_uintptr_t GC_CALL GC_beginthreadex( void * /* security */, unsigned /* stack_size */, unsigned (__stdcall *)(void *), diff --git a/include/gc_mark.h b/include/gc_mark.h index 508fb2cc..4c003c03 100644 --- a/include/gc_mark.h +++ b/include/gc_mark.h @@ -183,14 +183,24 @@ GC_API unsigned GC_CALL GC_new_kind_inner(void ** /* free_list */, GC_API unsigned GC_CALL GC_new_proc(GC_mark_proc); GC_API unsigned GC_CALL GC_new_proc_inner(GC_mark_proc); -/* Allocate an object of a given kind. Note that in multithreaded */ +/* Allocate an object of a given kind. By default, there are only */ +/* a few kinds: composite (pointer-free), atomic, uncollectable, etc. */ +/* We claim it is possible for clever client code that understands the */ +/* GC internals to add more, e.g. to communicate object layout */ +/* information to the collector. Note that in the multi-threaded */ /* contexts, this is usually unsafe for kinds that have the descriptor */ /* in the object itself, since there is otherwise a window in which */ /* the descriptor is not correct. Even in the single-threaded case, */ /* we need to be sure that cleared objects on a free list don't */ /* cause a GC crash if they are accidentally traced. */ -GC_API GC_ATTR_MALLOC void * GC_CALL - GC_generic_malloc(size_t /* lb */, int /* k */); +GC_API GC_ATTR_MALLOC void * GC_CALL GC_generic_malloc(size_t /* lb */, + int /* k */); + +GC_API GC_ATTR_MALLOC void * GC_CALL GC_generic_malloc_ignore_off_page( + size_t /* lb */, int /* k */); + /* As above, but pointers to past the */ + /* first page of the resulting object */ + /* are ignored. */ typedef void (GC_CALLBACK * GC_describe_type_fn)(void * /* p */, char * /* out_buf */); diff --git a/include/private/gc_priv.h b/include/private/gc_priv.h index 6352267d..c3125170 100644 --- a/include/private/gc_priv.h +++ b/include/private/gc_priv.h @@ -476,9 +476,10 @@ typedef char * ptr_t; /* A generic pointer to which we can add */ # elif defined(MSWINCE) && defined(NO_DEBUGGING) # define ABORT(msg) (GC_on_abort(msg), ExitProcess(-1)) # elif defined(MSWIN32) || defined(MSWINCE) -# define ABORT(msg) (GC_on_abort(msg), DebugBreak()) - /* Note that on a WinCE box, this could be silently */ - /* ignored (i.e., the program is not aborted). */ +# define ABORT(msg) { GC_on_abort(msg); DebugBreak(); } + /* Note that: on a WinCE box, this could be silently */ + /* ignored (i.e., the program is not aborted); */ + /* DebugBreak is a statement in some toolchains. */ # else # define ABORT(msg) (GC_on_abort(msg), abort()) # endif /* !MSWIN32 */ @@ -1027,7 +1028,11 @@ struct roots { # define MAX_HEAP_SECTS 768 /* Separately added heap sections. */ # endif # elif defined(SMALL_CONFIG) && !defined(USE_PROC_FOR_LIBRARIES) -# define MAX_HEAP_SECTS 128 /* Roughly 256MB (128*2048*1K) */ +# if defined(PARALLEL_MARK) && (defined(MSWIN32) || defined(CYGWIN32)) +# define MAX_HEAP_SECTS 384 +# else +# define MAX_HEAP_SECTS 128 /* Roughly 256MB (128*2048*1K) */ +# endif # elif CPP_WORDSZ > 32 # define MAX_HEAP_SECTS 1024 /* Roughly 8GB */ # else @@ -1764,23 +1769,10 @@ GC_INNER void GC_collect_a_little_inner(int n); /* collection work, if appropriate. */ /* A unit is an amount appropriate for */ /* HBLKSIZE bytes of allocation. */ -/* void * GC_generic_malloc(size_t lb, int k); */ - /* Allocate an object of the given */ - /* kind. By default, there are only */ - /* a few kinds: composite(pointerfree), */ - /* atomic, uncollectable, etc. */ - /* We claim it's possible for clever */ - /* client code that understands GC */ - /* internals to add more, e.g. to */ - /* communicate object layout info */ - /* to the collector. */ - /* The actual decl is in gc_mark.h. */ -GC_INNER void * GC_generic_malloc_ignore_off_page(size_t b, int k); - /* As above, but pointers past the */ - /* first page of the resulting object */ - /* are ignored. */ + GC_INNER void * GC_generic_malloc_inner(size_t lb, int k); - /* Ditto, but I already hold lock, etc. */ + /* Allocate an object of the given */ + /* kind but assuming lock already held. */ GC_INNER void * GC_generic_malloc_inner_ignore_off_page(size_t lb, int k); /* Allocate an object, where */ /* the client guarantees that there */ @@ -1885,16 +1877,25 @@ GC_EXTERN GC_bool GC_have_errors; /* We saw a smashed or leaked object. */ /* occasionally. It is ok to read it */ /* without acquiring the lock. */ +#define VERBOSE 2 #ifndef SMALL_CONFIG /* GC_print_stats should be visible to extra/MacOS.c. */ - extern int GC_print_stats; /* Nonzero generates basic GC log. */ +# ifndef GC_ANDROID_LOG + extern int GC_print_stats; /* Nonzero generates basic GC log. */ /* VERBOSE generates add'l messages. */ -#else +# define GC_real_print_stats GC_print_stats +# else +# ifndef GC_print_stats +# define GC_print_stats VERBOSE +# endif + extern int GC_real_print_stats; + /* Influences logging only if redirected to a file. */ +# endif +#else /* SMALL_CONFIG */ # define GC_print_stats 0 /* Will this remove the message character strings from the executable? */ /* With a particular level of optimizations, it should... */ #endif -#define VERBOSE 2 #ifdef KEEP_BACK_PTRS GC_EXTERN long GC_backtraces; @@ -1948,7 +1949,20 @@ GC_EXTERN GC_bool GC_print_back_height; #endif #ifdef CAN_HANDLE_FORK - GC_EXTERN GC_bool GC_handle_fork; + GC_EXTERN int GC_handle_fork; + /* Fork-handling mode: */ + /* 0 means no fork handling requested (but client could */ + /* anyway call fork() provided it is surrounded with */ + /* GC_atfork_prepare/parent/child calls); */ + /* -1 means GC tries to use pthread_at_fork if it is */ + /* available (if it succeeds then GC_handle_fork value */ + /* is changed to 1), client should nonetheless surround */ + /* fork() with GC_atfork_prepare/parent/child (for the */ + /* case of pthread_at_fork failure or absence); */ + /* 1 (or other values) means client fully relies on */ + /* pthread_at_fork (so if it is missing or failed then */ + /* abort occurs in GC_init), GC_atfork_prepare and the */ + /* accompanying routines are no-op in such a case. */ #endif #ifndef GC_DISABLE_INCREMENTAL @@ -2018,7 +2032,8 @@ GC_API void GC_CALL GC_noop1(word); /* Logging and diagnostic output: */ /* GC_printf is used typically on client explicit print requests. */ -/* It's recommended to put "\n" at 'format' string end (for atomicity). */ +/* For all GC_X_printf routines, it is recommended to put "\n" at */ +/* 'format' string end (for output atomicity). */ GC_API_PRIV void GC_printf(const char * format, ...) GC_ATTR_FORMAT_PRINTF(1, 2); /* A version of printf that doesn't allocate, */ @@ -2028,20 +2043,33 @@ GC_API_PRIV void GC_printf(const char * format, ...) GC_API_PRIV void GC_err_printf(const char * format, ...) GC_ATTR_FORMAT_PRINTF(1, 2); +/* Basic logging routine. Typically, GC_log_printf is called directly */ +/* only inside various DEBUG_x blocks. */ #if defined(__cplusplus) && defined(SYMBIAN) extern "C" { #endif -/* Logging routine. Typically called only if GC_print_stats. It is */ -/* recommended to put "\n" at 'format' string end (for atomicity). */ GC_API_PRIV void GC_log_printf(const char * format, ...) GC_ATTR_FORMAT_PRINTF(1, 2); #if defined(__cplusplus) && defined(SYMBIAN) } #endif -#define GC_COND_LOG_PRINTF if (!GC_print_stats) {} else GC_log_printf +#ifndef GC_ANDROID_LOG + /* GC_stats_log_printf should be called only if GC_print_stats. */ +# define GC_stats_log_printf GC_log_printf + /* GC_verbose_log_printf is called only if GC_print_stats is VERBOSE. */ +# define GC_verbose_log_printf GC_log_printf +#else + GC_INNER void GC_stats_log_printf(const char *format, ...) + GC_ATTR_FORMAT_PRINTF(1, 2); + GC_INNER void GC_verbose_log_printf(const char *format, ...) + GC_ATTR_FORMAT_PRINTF(1, 2); +#endif /* GC_ANDROID_LOG */ + +/* Convenient macros for GC_stats/verbose_log_printf invocation. */ +#define GC_COND_LOG_PRINTF if (!GC_print_stats) {} else GC_stats_log_printf #define GC_VERBOSE_LOG_PRINTF \ - if (GC_print_stats != VERBOSE) {} else GC_log_printf + if (GC_print_stats != VERBOSE) {} else GC_verbose_log_printf void GC_err_puts(const char *s); /* Write s to stderr, don't buffer, don't add */ diff --git a/include/private/gcconfig.h b/include/private/gcconfig.h index a35f4edb..c21c38ca 100644 --- a/include/private/gcconfig.h +++ b/include/private/gcconfig.h @@ -2656,15 +2656,27 @@ #endif #if !defined(CAN_HANDLE_FORK) && !defined(NO_HANDLE_FORK) \ - && ((defined(GC_PTHREADS) && !defined(HURD) && !defined(NACL) \ - && !defined(PLATFORM_ANDROID) && !defined(GC_WIN32_PTHREADS) \ - && !defined(USE_WINALLOC)) \ + && !defined(HAVE_NO_FORK) \ + && ((defined(GC_PTHREADS) && !defined(NACL) \ + && !defined(GC_WIN32_PTHREADS) && !defined(USE_WINALLOC)) \ || (defined(DARWIN) && defined(MPROTECT_VDB)) || defined(HANDLE_FORK)) /* Attempts (where supported and requested) to make GC_malloc work in */ /* a child process fork'ed from a multi-threaded parent. */ # define CAN_HANDLE_FORK #endif +#if defined(CAN_HANDLE_FORK) && !defined(CAN_CALL_ATFORK) \ + && !defined(HURD) && !defined(PLATFORM_ANDROID) + /* Have working pthread_atfork(). */ +# define CAN_CALL_ATFORK +#endif + +#if !defined(CAN_HANDLE_FORK) && !defined(HAVE_NO_FORK) \ + && (defined(MSWIN32) || defined(MSWINCE) || defined(DOS4GW) \ + || defined(OS2) || defined(SYMBIAN) /* and probably others ... */) +# define HAVE_NO_FORK +#endif + #if !defined(USE_MARK_BITS) && !defined(USE_MARK_BYTES) \ && defined(PARALLEL_MARK) /* Minimize compare-and-swap usage. */ |