summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorIvan Maidanski <ivmai@mail.ru>2015-08-28 01:37:33 +0300
committerIvan Maidanski <ivmai@mail.ru>2015-08-28 11:20:47 +0300
commit86991cba3cbce83bfd3a0619f11f86cc1ee56917 (patch)
tree5523311ce472f5d7141b769876c3ea9c402e09e6 /include
parent467b279de834a48f9d5ba731727f75949afa4000 (diff)
downloadbdwgc-86991cba3cbce83bfd3a0619f11f86cc1ee56917.tar.gz
Code refactoring of toggle-ref support
* alloc.c (GC_stopped_mark): Move GC_process_togglerefs() call from GC_stop_world; do not call it if GC_NO_FINALIZATION or GC_TOGGLE_REFS_NOT_NEEDED. * darwin_stop_world.c (GC_stop_world): Remove GC_process_togglerefs() call. * pthread_stop_world.c (GC_stop_world): Likewise. * doc/README.macros (GC_TOGGLE_REFS_NOT_NEEDED): Document. * finalize.c (GCToggleRef, GC_process_togglerefs, push_and_mark_object, GC_clear_togglerefs, GC_toggleref_add): Replace GC_PTR with void*. * include/gc.h (GC_toggleref_add): Likewise. * finalize.c (GCToggleRef, GC_toggleref_callback, GC_toggleref_arr, GC_toggleref_array_size, GC_toggleref_array_capacity, GC_process_togglerefs, push_and_mark_object, GC_mark_togglerefs, GC_clear_togglerefs, GC_set_toggleref_func, ensure_toggleref_capacity, GC_toggleref_add): Do not defined if GC_TOGGLE_REFS_NOT_NEEDED. * finalize.c (GCToggleRef): Add comment. * finalize.c (GC_toggleref_array): Rename to GC_toggleref_arr. * finalize.c (GC_toggleref_callback, GC_toggleref_array, GC_toggleref_array_size, GC_toggleref_array_capacity): Make it STATIC (instead "static"). * finalize.c (GC_process_togglerefs): Decorate with GC_INNER; remove "toggle_ref_counts", "res" local variables; rename "w" local variable to "new_size"; add assertion on lock state; use GC_TOGGLE_REF_* enum element in switch statement; use BZERO to clear moved elements of GC_toggleref_arr. * finalize.c (GC_normal_finalize_mark_proc): Declare (before use). * finalize.c (push_and_mark_object): Replace PUSH_OBJ with GC_normal_finalize_mark_proc call. * finalize.c (GC_mark_togglerefs, GC_clear_togglerefs): Remove "object" local variable. * finalize.c (GC_toggleref_register_callback): Rename to GC_set_toggleref_func; change argument to GC_toggleref_func (which returns GC_ToggleRefStatus instead of int). * finalize.c (GC_toggleref_register_callback, GC_toggleref_add): Decorate with GC_API and GC_CALL. * include/gc.h (GC_toggleref_register_callback): Likewise. * finalize.c (GC_set_toggleref_func): Acquire allocation lock. * finalize.c (GC_get_toggleref_func): New API function. * finalize.c (ensure_toggleref_capacity): Rename "capacity" argument to "capacity_inc"; add assertion on argument value; rename "tmp" local variable to "new_array"; remove unused "old_capacity" variable; replace memcpy() with BCOPY() call. * finalize.c (GC_toggleref_add): Rename "strong_ref" argument to "is_strong_ref". * finalize.c (GC_finalize): Do not call GC_clear_togglerefs and GC_mark_togglerefs if GC_TOGGLE_REFS_NOT_NEEDED. * include/gc.h (GC_ToggleRefStatus, GC_toggleref_func): New type. * include/gc.h (GC_toggleref_register_callback): Add comment (including about locking). * include/gc.h (GC_get_toggleref_func): New API function declaration. * include/gc.h (GC_toggleref_add): Decorate with GC_CALL; add comment; add GC_ATTR_NONNULL attribute. * include/private/gc_priv.h (GC_process_togglerefs): Do not declare if GC_TOGGLE_REFS_NOT_NEEDED; decorate with GC_INNER.
Diffstat (limited to 'include')
-rw-r--r--include/gc.h40
-rw-r--r--include/private/gc_priv.h21
2 files changed, 47 insertions, 14 deletions
diff --git a/include/gc.h b/include/gc.h
index 5a407cba..83f724c8 100644
--- a/include/gc.h
+++ b/include/gc.h
@@ -1172,10 +1172,42 @@ GC_API int GC_CALL GC_unregister_long_link(void ** /* link */);
/* Similar to GC_unregister_disappearing_link but for a */
/* registration by either of the above two routines. */
-
-/* toggleref support */
-GC_API void GC_toggleref_register_callback (int (*proccess_toggleref) (GC_PTR obj));
-GC_API int GC_toggleref_add (GC_PTR object, int strong_ref);
+/* Support of toggle-ref style of external memory management */
+/* without hooking up to the host retain/release machinery. */
+/* The idea of toggle-ref is that an external reference to */
+/* an object is kept and it can be either a strong or weak */
+/* reference; a weak reference is used when the external peer */
+/* has no interest in the object, and a strong otherwise. */
+typedef enum {
+ GC_TOGGLE_REF_DROP,
+ GC_TOGGLE_REF_STRONG,
+ GC_TOGGLE_REF_WEAK
+} GC_ToggleRefStatus;
+
+/* The callback is to decide (return) the new state of a given */
+/* object. Invoked by the collector for all objects registered */
+/* for toggle-ref processing. Invoked with the allocation lock */
+/* held (but the "world" is running). */
+typedef GC_ToggleRefStatus (GC_CALLBACK *GC_toggleref_func)(void * /* obj */);
+
+/* Set (register) a callback that decides the state of a given */
+/* object (by, probably, inspecting its native state). */
+/* The argument may be 0 (means no callback). Both the setter */
+/* and the getter acquire the allocation lock (to avoid data */
+/* races). */
+GC_API void GC_CALL GC_set_toggleref_func(GC_toggleref_func);
+GC_API GC_toggleref_func GC_CALL GC_get_toggleref_func(void);
+
+/* Register a given object for toggle-ref processing. It will */
+/* be stored internally and the toggle-ref callback will be */
+/* invoked on the object until the callback returns */
+/* GC_TOGGLE_REF_DROP or the object is collected. If is_strong */
+/* is true then the object is registered with a strong ref, */
+/* a weak one otherwise. Returns GC_SUCCESS if registration */
+/* succeeded (or no callback registered yet), GC_NO_MEMORY if */
+/* it failed for lack of memory. */
+GC_API int GC_CALL GC_toggleref_add(void * /* obj */, int /* is_strong */)
+ GC_ATTR_NONNULL(1);
/* Finalizer callback support. Invoked by the collector (with */
/* the allocation lock held) for each unreachable object */
diff --git a/include/private/gc_priv.h b/include/private/gc_priv.h
index 14b02ad7..ed9fc566 100644
--- a/include/private/gc_priv.h
+++ b/include/private/gc_priv.h
@@ -255,29 +255,30 @@ typedef char * ptr_t; /* A generic pointer to which we can add */
#ifndef GC_NO_FINALIZATION
-# define GC_INVOKE_FINALIZERS() GC_notify_or_invoke_finalizers()
- GC_INNER void GC_notify_or_invoke_finalizers(void);
+# define GC_INVOKE_FINALIZERS() GC_notify_or_invoke_finalizers()
+ GC_INNER void GC_notify_or_invoke_finalizers(void);
/* If GC_finalize_on_demand is not set, invoke */
/* eligible finalizers. Otherwise: */
/* Call *GC_finalizer_notifier if there are */
/* finalizers to be run, and we haven't called */
/* this procedure yet this GC cycle. */
- GC_INNER void GC_finalize(void);
+ GC_INNER void GC_finalize(void);
/* Perform all indicated finalization actions */
/* on unmarked objects. */
/* Unreachable finalizable objects are enqueued */
/* for processing by GC_invoke_finalizers. */
/* Invoked with lock. */
- void GC_process_togglerefs (void);
- /*Process the togglerefs before GC starts */
-
-# ifndef SMALL_CONFIG
- GC_INNER void GC_print_finalization_stats(void);
-# endif
+# ifndef GC_TOGGLE_REFS_NOT_NEEDED
+ GC_INNER void GC_process_togglerefs(void);
+ /* Process the toggle-refs before GC starts. */
+# endif
+# ifndef SMALL_CONFIG
+ GC_INNER void GC_print_finalization_stats(void);
+# endif
#else
-# define GC_INVOKE_FINALIZERS() (void)0
+# define GC_INVOKE_FINALIZERS() (void)0
#endif /* GC_NO_FINALIZATION */
#if !defined(DONT_ADD_BYTE_AT_END)