From: Ivan Maidanski Date: Sat, 2 Jun 2012 16:21:18 +0000 (+0400) Subject: Add public setter and getter for GC_push_other_roots X-Git-Tag: gc7_4_0~283 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=857e7a04a3ecf46e2ca7de09ef8b092d9f030be5;p=gc Add public setter and getter for GC_push_other_roots * include/gc_mark.h (GC_push_other_roots_proc): New type. * include/gc_mark.h (GC_set_push_other_roots, GC_get_push_other_roots): New API function (unsynchronized). * os_dep.c (GC_set_push_other_roots, GC_get_push_other_roots): Likewise. * include/private/gc_priv.h (GC_push_other_roots): Declare using GC_push_other_roots_proc type . * os_dep.c (GC_push_other_roots): Likewise. * os_dep.c (GC_default_push_other_roots): Use GC_CALLBACK calling convention. --- diff --git a/include/gc_mark.h b/include/gc_mark.h index 8b9b8c33..508fb2cc 100644 --- a/include/gc_mark.h +++ b/include/gc_mark.h @@ -243,6 +243,14 @@ GC_API void GC_CALL GC_push_all(char * /* bottom */, char * /* top */); GC_API void GC_CALL GC_push_conditional(char * /* bottom */, char * /* top */, int /* bool all */); +/* Set and get the client push-other-roots procedure. A client */ +/* supplied procedure should also call the original procedure. */ +/* Note that both the setter and getter require some external */ +/* synchronization to avoid data race. */ +typedef void (GC_CALLBACK * GC_push_other_roots_proc)(void); +GC_API void GC_CALL GC_set_push_other_roots(GC_push_other_roots_proc); +GC_API GC_push_other_roots_proc GC_CALL GC_get_push_other_roots(void); + #ifdef __cplusplus } /* end of extern "C" */ #endif diff --git a/include/private/gc_priv.h b/include/private/gc_priv.h index 827091a6..2809f063 100644 --- a/include/private/gc_priv.h +++ b/include/private/gc_priv.h @@ -1536,7 +1536,7 @@ GC_INNER void GC_push_all_eager(ptr_t b, ptr_t t); GC_INNER void GC_push_roots(GC_bool all, ptr_t cold_gc_frame); /* Push all or dirty roots. */ -GC_API_PRIV void (*GC_push_other_roots)(void); +GC_API_PRIV GC_push_other_roots_proc GC_push_other_roots; /* Push system or application specific roots */ /* onto the mark stack. In some environments */ /* (e.g. threads environments) this is */ diff --git a/os_dep.c b/os_dep.c index 57cf8edf..3dea9482 100644 --- a/os_dep.c +++ b/os_dep.c @@ -2560,7 +2560,7 @@ GC_INNER void GC_unmap_gap(ptr_t start1, size_t bytes1, ptr_t start2, /* environment, this is also responsible for marking from */ /* thread stacks. */ #ifndef THREADS - void (*GC_push_other_roots)(void) = 0; + GC_push_other_roots_proc GC_push_other_roots = 0; #else /* THREADS */ # ifdef PCR @@ -2587,7 +2587,7 @@ PCR_ERes GC_push_old_obj(void *p, size_t size, PCR_Any data) extern struct PCR_MM_ProcsRep * GC_old_allocator; /* defined in pcr_interface.c. */ -STATIC void GC_default_push_other_roots(void) +STATIC void GC_CALLBACK GC_default_push_other_roots(void) { /* Traverse data allocated by previous memory managers. */ if ((*(GC_old_allocator->mmp_enumerate))(PCR_Bool_false, @@ -2606,14 +2606,14 @@ STATIC void GC_default_push_other_roots(void) # endif /* PCR */ # if defined(GC_PTHREADS) || defined(GC_WIN32_THREADS) - STATIC void GC_default_push_other_roots(void) + STATIC void GC_CALLBACK GC_default_push_other_roots(void) { GC_push_all_stacks(); } # endif /* GC_WIN32_THREADS || GC_PTHREADS */ # ifdef SN_TARGET_PS3 - STATIC void GC_default_push_other_roots(void) + STATIC void GC_CALLBACK GC_default_push_other_roots(void) { ABORT("GC_default_push_other_roots is not implemented"); } @@ -2624,9 +2624,19 @@ STATIC void GC_default_push_other_roots(void) } # endif /* SN_TARGET_PS3 */ - void (*GC_push_other_roots)(void) = GC_default_push_other_roots; + GC_push_other_roots_proc GC_push_other_roots = GC_default_push_other_roots; #endif /* THREADS */ +GC_API void GC_CALL GC_set_push_other_roots(GC_push_other_roots_proc fn) +{ + GC_push_other_roots = fn; +} + +GC_API GC_push_other_roots_proc GC_CALL GC_get_push_other_roots(void) +{ + return GC_push_other_roots; +} + /* * Routines for accessing dirty bits on virtual pages. * There are six ways to maintain this information: