Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/mono.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/libgc
diff options
context:
space:
mode:
authorIvan Maidanski <ivmai@mail.ru>2015-11-13 00:47:52 +0300
committerIvan Maidanski <ivmai@mail.ru>2015-11-18 01:05:26 +0300
commitb0e91acb611bd7e6c39bc8756b38b41809a727a3 (patch)
treee1ad7e4e78f9c7f963ae5ef7f21f8576fc60d67f /libgc
parent5c2596af27fcf66f201962a130923153d2463ca1 (diff)
[boehm] Match BDWGC v7 API
Mono-specific libgc functionality has been recently added to BDWGC. This commit changes API of included Boehm GC to match that of the external GC. * Renaming: - GCEventType -> GC_EventType - GC_get_restart_signal -> GC_get_thr_restart_signal - GC_toggleref_register_callback -> GC_set_toggleref_func - GC_set_finalizer_notify_proc -> GC_set_await_finalize_proc * Replace global variable with a setter: - GC_notify_event -> GC_set_on_collection_event() (acquires GC lock) * Foreign threads registration: - add GC_allow_register_threads() (no-op for GC v6, called by mono_gc_base_init) - add GC_SUCCESS, GC_DUPLICATE, GC_NO_MEMORY, GC_UNIMPLEMENTED macros - add struct GC_stack_base - replace GC_thread_register_foreign(void*) with GC_register_my_thread(struct GC_stack_base) - define GC_register_my_thread also for Solaris and Win32 - GC_register_my_thread returns GC_DUPLICATE if already registered * Toggle-ref callback declaration change: - add GC_ToggleRefStatus (enum type) - callback returns GC_ToggleRefStatus instead of int * Toggle-ref addition status checked: - GC_toggleref_add return type changed from void to int - GC_toggleref_add returns GC_SUCCESS or GC_NO_MEMORY - static ensure_toggleref_capacity() returns FALSE if GC MALLOC failed - call g_error() if GC_toggleref_add failed * Conditional public function declaration: - wrap GC_DllMain declaration into ifdef GC_INSIDE_DLL - define GC_INSIDE_DLL prior to include gc.h
Diffstat (limited to 'libgc')
-rw-r--r--libgc/alloc.c10
-rw-r--r--libgc/finalize.c30
-rw-r--r--libgc/include/gc.h44
-rw-r--r--libgc/include/private/gc_priv.h2
-rw-r--r--libgc/misc.c2
-rw-r--r--libgc/pthread_support.c18
-rw-r--r--libgc/solaris_threads.c9
-rw-r--r--libgc/win32_threads.c16
8 files changed, 103 insertions, 28 deletions
diff --git a/libgc/alloc.c b/libgc/alloc.c
index b6bc1832c99..2ffafd441d7 100644
--- a/libgc/alloc.c
+++ b/libgc/alloc.c
@@ -644,9 +644,17 @@ GC_stop_func stop_func;
}
}
-void (*GC_notify_event) GC_PROTO((GCEventType e));
+void (*GC_notify_event) GC_PROTO((GC_EventType e));
void (*GC_on_heap_resize) GC_PROTO((size_t new_size));
+GC_API void GC_set_on_collection_event (void (*fn) (GC_EventType))
+{
+ DCL_LOCK_STATE;
+ LOCK();
+ GC_notify_event = fn;
+ UNLOCK();
+}
+
/* Finish up a collection. Assumes lock is held, signals are disabled, */
/* but the world is otherwise running. */
void GC_finish_collection()
diff --git a/libgc/finalize.c b/libgc/finalize.c
index 5626e872137..39224f94ed6 100644
--- a/libgc/finalize.c
+++ b/libgc/finalize.c
@@ -313,7 +313,7 @@ typedef struct {
GC_hidden_pointer weak_ref;
} GCToggleRef;
-static int (*GC_toggleref_callback) (GC_PTR obj);
+static GC_ToggleRefStatus (*GC_toggleref_callback) (GC_PTR obj);
static GCToggleRef *GC_toggleref_array;
static int GC_toggleref_array_size;
static int GC_toggleref_array_capacity;
@@ -326,7 +326,7 @@ GC_process_togglerefs (void)
int toggle_ref_counts [3] = { 0, 0, 0 };
for (i = w = 0; i < GC_toggleref_array_size; ++i) {
- int res;
+ GC_ToggleRefStatus res;
GCToggleRef r = GC_toggleref_array [i];
GC_PTR obj;
@@ -341,14 +341,14 @@ GC_process_togglerefs (void)
res = GC_toggleref_callback (obj);
++toggle_ref_counts [res];
switch (res) {
- case 0:
+ case GC_TOGGLE_REF_DROP:
break;
- case 1:
+ case GC_TOGGLE_REF_STRONG:
GC_toggleref_array [w].strong_ref = obj;
GC_toggleref_array [w].weak_ref = (GC_hidden_pointer)NULL;
++w;
break;
- case 2:
+ case GC_TOGGLE_REF_WEAK:
GC_toggleref_array [w].strong_ref = NULL;
GC_toggleref_array [w].weak_ref = HIDE_POINTER (obj);
++w;
@@ -370,7 +370,7 @@ GC_process_togglerefs (void)
static void (*GC_object_finalized_proc) (GC_PTR obj);
void
-GC_set_finalizer_notify_proc (void (*proc) (GC_PTR obj))
+GC_set_await_finalize_proc (void (*proc) (GC_PTR obj))
{
GC_object_finalized_proc = proc;
}
@@ -423,17 +423,19 @@ static void GC_clear_togglerefs ()
-void GC_toggleref_register_callback(int (*proccess_toggleref) (GC_PTR obj))
+void GC_set_toggleref_func(GC_ToggleRefStatus (*proccess_toggleref) (GC_PTR obj))
{
GC_toggleref_callback = proccess_toggleref;
}
-static void
+static GC_bool
ensure_toggleref_capacity (int capacity)
{
if (!GC_toggleref_array) {
GC_toggleref_array_capacity = 32;
GC_toggleref_array = (GCToggleRef *) GC_INTERNAL_MALLOC_IGNORE_OFF_PAGE (GC_toggleref_array_capacity * sizeof (GCToggleRef), NORMAL);
+ if (!GC_toggleref_array)
+ return FALSE;
}
if (GC_toggleref_array_size + capacity >= GC_toggleref_array_capacity) {
GCToggleRef *tmp;
@@ -442,15 +444,19 @@ ensure_toggleref_capacity (int capacity)
GC_toggleref_array_capacity *= 2;
tmp = (GCToggleRef *) GC_INTERNAL_MALLOC_IGNORE_OFF_PAGE (GC_toggleref_array_capacity * sizeof (GCToggleRef), NORMAL);
+ if (!tmp)
+ return FALSE;
memcpy (tmp, GC_toggleref_array, GC_toggleref_array_size * sizeof (GCToggleRef));
GC_INTERNAL_FREE (GC_toggleref_array);
GC_toggleref_array = tmp;
}
+ return TRUE;
}
-void
+int
GC_toggleref_add (GC_PTR object, int strong_ref)
{
+ int res = GC_SUCCESS;
DCL_LOCK_STATE;
# ifdef THREADS
DISABLE_SIGNALS();
@@ -460,7 +466,10 @@ GC_toggleref_add (GC_PTR object, int strong_ref)
if (!GC_toggleref_callback)
goto end;
- ensure_toggleref_capacity (1);
+ if (!ensure_toggleref_capacity (1)) {
+ res = GC_NO_MEMORY;
+ goto end;
+ }
GC_toggleref_array [GC_toggleref_array_size].strong_ref = strong_ref ? object : NULL;
GC_toggleref_array [GC_toggleref_array_size].weak_ref = strong_ref ? (GC_hidden_pointer)NULL : HIDE_POINTER (object);
++GC_toggleref_array_size;
@@ -470,6 +479,7 @@ end:
UNLOCK();
ENABLE_SIGNALS();
# endif
+ return res;
}
diff --git a/libgc/include/gc.h b/libgc/include/gc.h
index dd7fb7a86c8..e7929918ad0 100644
--- a/libgc/include/gc.h
+++ b/libgc/include/gc.h
@@ -104,11 +104,11 @@ typedef enum {
GC_EVENT_POST_STOP_WORLD,
GC_EVENT_PRE_START_WORLD,
GC_EVENT_POST_START_WORLD
-} GCEventType;
+} GC_EventType;
-GC_API void (*GC_notify_event) GC_PROTO((GCEventType event_type));
- /* Invoked at specific points during every collection.
- */
+GC_API void GC_set_on_collection_event GC_PROTO((void (*) (GC_EventType)));
+ /* Set callback invoked at specific points */
+ /* during every collection. */
GC_API void (*GC_on_heap_resize) GC_PROTO((size_t new_size));
/* Invoked when the heap grows or shrinks */
@@ -431,7 +431,10 @@ int GC_get_suspend_signal GC_PROTO((void));
/* Return the signal used by the gc to resume threads on posix platforms. */
/* Return -1 otherwise. */
-int GC_get_restart_signal GC_PROTO((void));
+int GC_get_thr_restart_signal GC_PROTO((void));
+
+/* Explicitly enable GC_register_my_thread() invocation. */
+GC_API void GC_allow_register_threads GC_PROTO((void));
/* Disable garbage collection. Even GC_gcollect calls will be */
/* ineffective. */
@@ -773,13 +776,21 @@ GC_API int GC_unregister_disappearing_link GC_PROTO((GC_PTR * /* link */));
GC_API int GC_register_long_link GC_PROTO((GC_PTR * /* link */, GC_PTR obj));
GC_API int GC_unregister_long_link GC_PROTO((GC_PTR * /* link */));
+typedef enum {
+ GC_TOGGLE_REF_DROP,
+ GC_TOGGLE_REF_STRONG,
+ GC_TOGGLE_REF_WEAK
+} GC_ToggleRefStatus;
/* toggleref support */
-GC_API void GC_toggleref_register_callback GC_PROTO((int (*proccess_toggleref) (GC_PTR obj)));
-GC_API void GC_toggleref_add (GC_PTR object, int strong_ref);
+GC_API void GC_set_toggleref_func GC_PROTO(
+ (GC_ToggleRefStatus (*proccess_toggleref) (GC_PTR obj)));
+GC_API int GC_toggleref_add (GC_PTR object, int strong_ref);
+ /* Returns GC_SUCCESS if registration succeeded (or no callback */
+ /* registered yet), GC_NO_MEMORY if failed for lack of memory. */
/* finalizer callback support */
-GC_API void GC_set_finalizer_notify_proc GC_PROTO((void (*object_finalized) (GC_PTR obj)));
+GC_API void GC_set_await_finalize_proc GC_PROTO((void (*object_finalized) (GC_PTR obj)));
/* Returns !=0 if GC_invoke_finalizers has something to do. */
@@ -859,6 +870,21 @@ GC_API GC_PTR GC_is_visible GC_PROTO((GC_PTR p));
/* Always returns its argument. */
GC_API GC_PTR GC_is_valid_displacement GC_PROTO((GC_PTR p));
+#define GC_SUCCESS 0
+#define GC_DUPLICATE 1 /* Was already registered. */
+#define GC_NO_MEMORY 2 /* Failure due to lack of memory. */
+#define GC_UNIMPLEMENTED 3 /* Not yet implemented on the platform. */
+
+/* Structure representing the base of a thread stack. */
+struct GC_stack_base {
+ void * mem_base; /* Base of memory stack. */
+};
+
+/* Register the current thread, with the indicated stack base. */
+/* Returns GC_SUCCESS on success, GC_DUPLICATE if already registered. */
+/* On some platforms it returns GC_UNIMPLEMENTED. */
+GC_API int GC_register_my_thread GC_PROTO((struct GC_stack_base *));
+
/* Returns 1 if the calling thread is registered with the GC, 0 otherwise */
GC_API int GC_thread_is_registered GC_PROTO((void));
@@ -949,7 +975,9 @@ extern void GC_thr_init(void); /* Needed for Solaris/X86 */
#if defined(GC_WIN32_THREADS) && !defined(__CYGWIN32__) && !defined(__CYGWIN__)
# include <windows.h>
+# ifdef GC_INSIDE_DLL
BOOL WINAPI GC_DllMain(HINSTANCE inst, ULONG reason, LPVOID reserved);
+# endif
/*
* All threads must be created using GC_CreateThread, so that they will be
diff --git a/libgc/include/private/gc_priv.h b/libgc/include/private/gc_priv.h
index 10c095e7d2f..ab77402e4cd 100644
--- a/libgc/include/private/gc_priv.h
+++ b/libgc/include/private/gc_priv.h
@@ -1214,6 +1214,8 @@ extern long GC_large_alloc_warn_suppressed;
extern GC_bool GC_world_stopped;
#endif
+extern void (*GC_notify_event) GC_PROTO((GC_EventType));
+
/* Operations */
# ifndef abs
# define abs(x) ((x) < 0? (-(x)) : (x))
diff --git a/libgc/misc.c b/libgc/misc.c
index 3fa00a8b063..480759c57b9 100644
--- a/libgc/misc.c
+++ b/libgc/misc.c
@@ -480,7 +480,7 @@ int GC_get_suspend_signal GC_PROTO(())
#endif
}
-int GC_get_restart_signal GC_PROTO(())
+int GC_get_thr_restart_signal GC_PROTO(())
{
#if defined(SIG_THR_RESTART) && defined(GC_PTHREADS) && !defined(GC_MACOSX_THREADS) && !defined(GC_OPENBSD_THREADS)
return SIG_THR_RESTART;
diff --git a/libgc/pthread_support.c b/libgc/pthread_support.c
index a8c8b330a36..d2fec41c448 100644
--- a/libgc/pthread_support.c
+++ b/libgc/pthread_support.c
@@ -1462,13 +1462,18 @@ void * GC_start_routine_head(void * arg, void *base_addr,
return me;
}
-int GC_thread_register_foreign (void *base_addr)
+void GC_allow_register_threads (void)
+{
+ /* No-op for GC pre-v7. */
+}
+
+int GC_register_my_thread (struct GC_stack_base *sb)
{
struct start_info si = { 0, }; /* stacked for legibility & locking */
GC_thread me;
# ifdef DEBUG_THREADS
- GC_printf1( "GC_thread_register_foreign %p\n", &si );
+ GC_printf1( "GC_register_my_thread %p\n", &si );
# endif
si.flags = FOREIGN_THREAD;
@@ -1476,12 +1481,13 @@ int GC_thread_register_foreign (void *base_addr)
if (!parallel_initialized) GC_init_parallel();
LOCK();
if (!GC_thr_initialized) GC_thr_init();
-
+ me = GC_lookup_thread(pthread_self());
UNLOCK();
+ if (me != NULL)
+ return GC_DUPLICATE;
- me = GC_start_routine_head(&si, base_addr, NULL, NULL);
-
- return me != NULL;
+ (void)GC_start_routine_head(&si, sb -> mem_base, NULL, NULL);
+ return GC_SUCCESS;
}
void * GC_start_routine(void * arg)
diff --git a/libgc/solaris_threads.c b/libgc/solaris_threads.c
index 8ca8fa3b3a2..e67c514c798 100644
--- a/libgc/solaris_threads.c
+++ b/libgc/solaris_threads.c
@@ -642,10 +642,15 @@ int GC_thread_is_registered (void)
return ptr ? 1 : 0;
}
-int GC_thread_register_foreign (void *base_addr)
+void GC_allow_register_threads (void)
+{
+ /* No-op for GC pre-v7. */
+}
+
+int GC_register_my_thread (struct GC_stack_base *sb)
{
/* FIXME: */
- return 0;
+ return GC_UNIMPLEMENTED;
}
void GC_register_altstack (void *stack, int stack_size, void *altstack, int altstack_size)
diff --git a/libgc/win32_threads.c b/libgc/win32_threads.c
index a60363b4d6f..16a6fb6d003 100644
--- a/libgc/win32_threads.c
+++ b/libgc/win32_threads.c
@@ -85,6 +85,22 @@ int GC_thread_is_registered (void)
#endif
}
+void GC_allow_register_threads (void)
+{
+ /* No-op for GC pre-v7. */
+}
+
+int GC_register_my_thread (struct GC_stack_base *sb)
+{
+# if defined(GC_DLL) || defined(GC_INSIDE_DLL)
+ /* Registered by DllMain. */
+ return GC_DUPLICATE;
+# else
+ /* TODO: Implement. */
+ return GC_UNIMPLEMENTED;
+# endif
+}
+
void GC_register_altstack (void *stack, int stack_size, void *altstack, int altstack_size)
{
}