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
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 */
/* 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
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,
# 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");
}
}
# 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: