summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
Diffstat (limited to 'include')
-rw-r--r--include/gc.h48
-rw-r--r--include/gc_mark.h16
-rw-r--r--include/private/gc_priv.h86
-rw-r--r--include/private/gcconfig.h18
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. */