+2009-06-12 Hans Boehm <Hans.Boehm@hp.com> (Really Ivan Maidanski)
+ (diff96_cvs, partly from diff45 and diff75)
+
+ * misc.c (GC_set_oom_fn, GC_set_all_interior_pointers,
+ GC_set_finalize_on_demand, GC_set_java_finalization,
+ GC_set_finalizer_notifier, GC_set_dont_expand, GC_set_full_freq,
+ GC_set_no_dls, GC_set_free_space_divisor, GC_set_max_retries,
+ GC_set_dont_precollect, GC_set_time_limit, GC_set_warn_proc):
+ Change return type to void (these API functions no longer return
+ the old value).
+ * include/gc.h: Ditto (for prototypes).
+ * tests/test.c (main, WinMain, test): Remove explicit cast to void
+ for GC_set_warn_proc().
+ * misc.c (GC_get_oom_fn, GC_get_all_interior_pointers,
+ GC_get_finalize_on_demand, GC_get_java_finalization,
+ GC_get_finalizer_notifier, GC_get_dont_expand, GC_get_full_freq,
+ GC_get_no_dls, GC_get_free_space_divisor, GC_get_max_retries,
+ GC_get_dont_precollect, GC_get_time_limit, GC_get_warn_proc): New
+ API functions (to get the current value of the corresponding R/W
+ public variables).
+ * include/gc.h: Ditto (for prototypes).
+ * include/gc.h (GC_set_warn_proc, GC_set_free_space_divisor):
+ Update the comment.
+ * misc.c (GC_ignore_warn_proc): New API call-back function.
+ * include/gc.h (GC_ignore_warn_proc): Ditto (for the prototype).
+ * misc.c (GC_set_find_leak, GC_get_find_leak, GC_set_non_gc_bytes,
+ GC_get_non_gc_bytes): New API setter and getter functions (for the
+ public GC_find_leak and GC_non_gc_bytes variables, respectively).
+ * include/gc.h: Ditto (for prototypes).
+ * include/gc.h (GC_memalign): Add proto to GC API.
+ * mallocx.c (GC_memalign): Use GC_API, GC_CALL for the definition.
+ * tests/test.c (run_one_test): Test GC_memalign() on Win32 too,
+ remove GC_memalign() proto.
+ * misc.c (GC_write): Use multi-byte (A) variants of Win32
+ GetModuleFileName() and CreateFile().
+ * tests/test.c (main): Replace K&R-style function definition with the
+ ANSI C one.
+
2009-06-12 Hans Boehm <Hans.Boehm@hp.com> (Really Ivan Maidanski and George Talbot)
(diff95_cvs)
* include/private/gcconfig.h (PLATFORM_ANDROID): New macro
/* If it returns, it must return 0 or a valid */
/* pointer to a previously allocated heap */
/* object. */
-GC_API GC_oom_func GC_CALL GC_set_oom_fn(GC_oom_func);
+GC_API void GC_CALL GC_set_oom_fn(GC_oom_func);
+GC_API GC_oom_func GC_CALL GC_get_oom_fn(void);
GC_API int GC_find_leak;
/* Do not actually garbage collect, but simply */
/* report inaccessible memory that was not */
/* deallocated with GC_free. Initial value */
/* is determined by FIND_LEAK macro. */
+GC_API void GC_CALL GC_set_find_leak(int);
+GC_API int GC_CALL GC_get_find_leak(void);
GC_API int GC_all_interior_pointers;
/* Arrange for pointers to object interiors to */
/* at least a byte to allow "off the end" */
/* pointer recognition. */
/* MUST BE 0 or 1. */
-GC_API int GC_CALL GC_set_all_interior_pointers(int);
+GC_API void GC_CALL GC_set_all_interior_pointers(int);
+GC_API int GC_CALL GC_get_all_interior_pointers(void);
GC_API int GC_finalize_on_demand;
/* If nonzero, finalizers will only be run in */
/* call. The default is determined by whether */
/* the FINALIZE_ON_DEMAND macro is defined */
/* when the collector is built. */
-GC_API int GC_CALL GC_set_finalize_on_demand(int);
+GC_API void GC_CALL GC_set_finalize_on_demand(int);
+GC_API int GC_CALL GC_get_finalize_on_demand(void);
GC_API int GC_java_finalization;
/* Mark objects reachable from finalizable */
/* determined by JAVA_FINALIZATION macro. */
/* Enables register_finalizer_unreachable to */
/* work correctly. */
-GC_API int GC_CALL GC_set_java_finalization(int);
+GC_API void GC_CALL GC_set_java_finalization(int);
+GC_API int GC_CALL GC_get_java_finalization(void);
typedef void (GC_CALLBACK * GC_finalizer_notifier_proc)(void);
GC_API GC_finalizer_notifier_proc GC_finalizer_notifier;
/* Typically this will notify a finalization */
/* thread, which will call GC_invoke_finalizers */
/* in response. */
-GC_API GC_finalizer_notifier_proc GC_CALL GC_set_finalizer_notifier(
- GC_finalizer_notifier_proc);
+GC_API void GC_CALL GC_set_finalizer_notifier(GC_finalizer_notifier_proc);
+GC_API GC_finalizer_notifier_proc GC_CALL GC_get_finalizer_notifier(void);
GC_API int GC_dont_gc; /* != 0 ==> Dont collect. In versions 6.2a1+, */
/* this overrides explicit GC_gcollect() calls. */
GC_API int GC_dont_expand;
/* Dont expand heap unless explicitly requested */
/* or forced to. */
-GC_API int GC_CALL GC_set_dont_expand(int);
+GC_API void GC_CALL GC_set_dont_expand(int);
+GC_API int GC_CALL GC_get_dont_expand(void);
GC_API int GC_use_entire_heap;
/* Causes the non-incremental collector to use the */
/* blocks. Values in the tens are now */
/* perfectly reasonable, unlike for */
/* earlier GC versions. */
-GC_API int GC_CALL GC_set_full_freq(int value);
+GC_API void GC_CALL GC_set_full_freq(int);
+GC_API int GC_CALL GC_get_full_freq(void);
GC_API GC_word GC_non_gc_bytes;
/* Bytes not considered candidates for collection. */
/* Used only to control scheduling of collections. */
/* Updated by GC_malloc_uncollectable and GC_free. */
/* Wizards only. */
+GC_API void GC_CALL GC_set_non_gc_bytes(GC_word);
+GC_API GC_word GC_CALL GC_get_non_gc_bytes(void);
GC_API int GC_no_dls;
/* Don't register dynamic library data segments. */
/* In Microsoft Windows environments, this will */
/* usually also prevent registration of the */
/* main data segment as part of the root set. */
-GC_API int GC_CALL GC_set_no_dls(int);
+GC_API void GC_CALL GC_set_no_dls(int);
+GC_API int GC_CALL GC_get_no_dls(void);
GC_API GC_word GC_free_space_divisor;
/* We try to make sure that we allocate at */
/* but more collection time. Decreasing it */
/* will appreciably decrease collection time */
/* at the expense of space. */
+GC_API void GC_CALL GC_set_free_space_divisor(GC_word);
+GC_API GC_word GC_CALL GC_get_free_space_divisor(void);
GC_API GC_word GC_max_retries;
/* The maximum number of GCs attempted before */
/* reporting out of memory after heap */
/* expansion fails. Initially 0. */
-GC_API GC_word GC_CALL GC_set_max_retries(GC_word);
+GC_API void GC_CALL GC_set_max_retries(GC_word);
+GC_API GC_word GC_CALL GC_get_max_retries(void);
GC_API char *GC_stackbottom; /* Cool end of user stack. */
/* before the first collection. */
/* Interferes with blacklisting. */
/* Wizards only. */
-GC_API int GC_CALL GC_set_dont_precollect(int);
+GC_API void GC_CALL GC_set_dont_precollect(int);
+GC_API int GC_CALL GC_get_dont_precollect(void);
GC_API unsigned long GC_time_limit;
/* If incremental collection is enabled, */
/* Setting GC_time_limit to this value */
/* will disable the "pause time exceeded"*/
/* tests. */
-GC_API unsigned long GC_CALL GC_set_time_limit(unsigned long value);
+GC_API void GC_CALL GC_set_time_limit(unsigned long);
+GC_API unsigned long GC_CALL GC_get_time_limit(void);
/* Public procedures */
GC_API void * GC_CALL GC_malloc_uncollectable(size_t size_in_bytes);
GC_API void * GC_CALL GC_malloc_stubborn(size_t size_in_bytes);
+/* GC_memalign() is not well tested. */
+GC_API void * GC_CALL GC_memalign(size_t align, size_t lb);
+
/* The following is only defined if the library has been suitably */
/* compiled: */
GC_API void * GC_CALL GC_malloc_atomic_uncollectable(size_t size_in_bytes);
/* GC_set_warn_proc can be used to redirect or filter warning messages. */
/* p may not be a NULL pointer. */
typedef void (GC_CALLBACK * GC_warn_proc) (char *msg, GC_word arg);
-GC_API GC_warn_proc GC_CALL GC_set_warn_proc(GC_warn_proc p);
- /* Returns old warning procedure. */
- /* With 0 argument, current warn_proc remains unchanged. */
- /* (Only true for GC7.2+) */
-
-GC_API GC_word GC_CALL GC_set_free_space_divisor(GC_word value);
- /* Set free_space_divisor. See above for definition. */
- /* Returns old value. */
- /* With -1 argument, nothing is changed, but old value is */
- /* returned. (Only true for GC7.2+) */
-
+GC_API void GC_CALL GC_set_warn_proc(GC_warn_proc p);
+/* GC_get_warn_proc returns the current warn_proc. */
+GC_API GC_warn_proc GC_CALL GC_get_warn_proc(void);
+
+ /* GC_ignore_warn_proc may be used as an argument for */
+ /* GC_set_warn_proc() to suppress all warnings (unless */
+ /* statistics printing is turned on). */
+GC_API void GC_CALLBACK GC_ignore_warn_proc(char *msg, GC_word arg);
+
/* The following is intended to be used by a higher level */
/* (e.g. Java-like) finalization facility. It is expected */
/* that finalization code will arrange for hidden pointers to */
/* Debug version is tricky and currently missing. */
#include <limits.h>
-void * GC_memalign(size_t align, size_t lb)
+GC_API void * GC_CALL GC_memalign(size_t align, size_t lb)
{
size_t new_lb;
size_t offset;
# ifdef OLD_WIN32_LOG_FILE
strcpy(logPath, LOG_FILE);
# else
- GetModuleFileName(NULL, logPath, _MAX_PATH);
+ GetModuleFileNameA(NULL, logPath, _MAX_PATH);
strcat(logPath, ".log");
# endif
file_name = logPath;
}
- GC_stdout = CreateFile(file_name, GENERIC_WRITE,
+ GC_stdout = CreateFileA(file_name, GENERIC_WRITE,
FILE_SHARE_READ,
NULL, CREATE_ALWAYS, FILE_FLAG_WRITE_THROUGH,
NULL);
GC_warn_proc GC_current_warn_proc = GC_default_warn_proc;
-GC_API GC_warn_proc GC_CALL GC_set_warn_proc(GC_warn_proc p)
+/* This is recommended for production code (release). */
+GC_API void GC_CALLBACK GC_ignore_warn_proc(char *msg, GC_word arg)
{
- GC_warn_proc result;
+ if (GC_print_stats) {
+ /* Don't ignore warnings if stats printing is on. */
+ GC_default_warn_proc(msg, arg);
+ }
+}
+GC_API void GC_CALL GC_set_warn_proc(GC_warn_proc p)
+{
+ GC_ASSERT(p != 0);
# ifdef GC_WIN32_THREADS
# ifdef CYGWIN32
/* Need explicit GC_INIT call */
# endif
# endif
LOCK();
- result = GC_current_warn_proc;
- if (p != (GC_warn_proc)0)
- GC_current_warn_proc = p;
+ GC_current_warn_proc = p;
UNLOCK();
- return(result);
}
-GC_API GC_word GC_CALL GC_set_free_space_divisor (GC_word value)
+GC_API GC_warn_proc GC_CALL GC_get_warn_proc(void)
{
- GC_word old = GC_free_space_divisor;
- if (value != ~(GC_word)0)
- GC_free_space_divisor = value;
- return old;
+ GC_warn_proc result;
+ LOCK();
+ result = GC_current_warn_proc;
+ UNLOCK();
+ return(result);
}
#if !defined(PCR) && !defined(SMALL_CONFIG)
return GC_parallel;
}
-GC_API GC_oom_func GC_CALL GC_set_oom_fn(GC_oom_func fn)
+/* Setter and getter functions for the public R/W variables. */
+
+GC_API void GC_CALL GC_set_oom_fn(GC_oom_func fn)
+{
+ GC_ASSERT(fn != 0);
+ GC_oom_fn = fn;
+}
+
+GC_API GC_oom_func GC_CALL GC_get_oom_fn(void)
{
- GC_oom_func ofn = GC_oom_fn;
- if (fn != (GC_oom_func)0)
- GC_oom_fn = fn;
- return ofn;
+ return GC_oom_fn;
}
-GC_API GC_finalizer_notifier_proc GC_CALL GC_set_finalizer_notifier(
- GC_finalizer_notifier_proc fn)
+GC_API void GC_CALL GC_set_finalizer_notifier(GC_finalizer_notifier_proc fn)
{
- GC_finalizer_notifier_proc ofn = GC_finalizer_notifier;
- if (fn != (GC_finalizer_notifier_proc)((signed_word)-1))
- GC_finalizer_notifier = fn;
- return ofn;
+ GC_finalizer_notifier = fn;
}
-GC_API int GC_CALL GC_set_all_interior_pointers(int value)
+GC_API GC_finalizer_notifier_proc GC_CALL GC_get_finalizer_notifier(void)
{
- int ovalue = GC_all_interior_pointers;
- if (value != -1) {
- GC_ASSERT(!GC_is_initialized || value == ovalue);
- GC_ASSERT(value == 0 || value == 1);
- GC_all_interior_pointers = value;
- }
- return ovalue;
+ return GC_finalizer_notifier;
+}
+
+GC_API void GC_CALL GC_set_find_leak(int value)
+{
+ /* value is of boolean type. */
+ GC_find_leak = value;
+}
+
+GC_API int GC_CALL GC_get_find_leak(void)
+{
+ return GC_find_leak;
+}
+
+GC_API void GC_CALL GC_set_all_interior_pointers(int value)
+{
+ GC_ASSERT(!GC_is_initialized || value == GC_all_interior_pointers);
+ GC_ASSERT(value == 0 || value == 1);
+ GC_all_interior_pointers = value;
+}
+
+GC_API int GC_CALL GC_get_all_interior_pointers(void)
+{
+ return GC_all_interior_pointers;
+}
+
+GC_API void GC_CALL GC_set_finalize_on_demand(int value)
+{
+ GC_ASSERT(value != -1);
+ /* value is of boolean type. */
+ GC_finalize_on_demand = value;
+}
+
+GC_API int GC_CALL GC_get_finalize_on_demand(void)
+{
+ return GC_finalize_on_demand;
+}
+
+GC_API void GC_CALL GC_set_java_finalization(int value)
+{
+ GC_ASSERT(value != -1);
+ /* value is of boolean type. */
+ GC_java_finalization = value;
+}
+
+GC_API int GC_CALL GC_get_java_finalization(void)
+{
+ return GC_java_finalization;
+}
+
+GC_API void GC_CALL GC_set_dont_expand(int value)
+{
+ GC_ASSERT(value != -1);
+ /* value is of boolean type. */
+ GC_dont_expand = value;
+}
+
+GC_API int GC_CALL GC_get_dont_expand(void)
+{
+ return GC_dont_expand;
+}
+
+GC_API void GC_CALL GC_set_no_dls(int value)
+{
+ GC_ASSERT(value != -1);
+ /* value is of boolean type. */
+ GC_no_dls = value;
+}
+
+GC_API int GC_CALL GC_get_no_dls(void)
+{
+ return GC_no_dls;
+}
+
+GC_API void GC_CALL GC_set_non_gc_bytes(GC_word value)
+{
+ GC_non_gc_bytes = value;
+}
+
+GC_API GC_word GC_CALL GC_get_non_gc_bytes(void)
+{
+ return GC_non_gc_bytes;
+}
+
+GC_API void GC_CALL GC_set_free_space_divisor(GC_word value)
+{
+ GC_ASSERT(value > 0);
+ GC_free_space_divisor = value;
+}
+
+GC_API GC_word GC_CALL GC_get_free_space_divisor(void)
+{
+ return GC_free_space_divisor;
}
-GC_API int GC_CALL GC_set_finalize_on_demand(int value)
+GC_API void GC_CALL GC_set_max_retries(GC_word value)
{
- int ovalue = GC_finalize_on_demand;
- if (value != -1)
- GC_finalize_on_demand = value;
- return ovalue;
+ GC_ASSERT(value != ~(GC_word)0);
+ GC_max_retries = value;
}
-GC_API int GC_CALL GC_set_java_finalization(int value)
+GC_API GC_word GC_CALL GC_get_max_retries(void)
{
- int ovalue = GC_java_finalization;
- if (value != -1)
- GC_java_finalization = value;
- return ovalue;
+ return GC_max_retries;
}
-GC_API int GC_CALL GC_set_dont_expand(int value)
+GC_API void GC_CALL GC_set_dont_precollect(int value)
{
- int ovalue = GC_dont_expand;
- if (value != -1)
- GC_dont_expand = value;
- return ovalue;
+ GC_ASSERT(value != -1);
+ /* value is of boolean type. */
+ GC_dont_precollect = value;
}
-GC_API int GC_CALL GC_set_no_dls(int value)
+GC_API int GC_CALL GC_get_dont_precollect(void)
{
- int ovalue = GC_no_dls;
- if (value != -1)
- GC_no_dls = value;
- return ovalue;
+ return GC_dont_precollect;
}
-GC_API GC_word GC_CALL GC_set_max_retries(GC_word value)
+GC_API void GC_CALL GC_set_full_freq(int value)
{
- GC_word ovalue = GC_max_retries;
- if (value != ~(GC_word)0)
- GC_max_retries = value;
- return ovalue;
+ GC_ASSERT(value >= 0);
+ GC_full_freq = value;
}
-GC_API int GC_CALL GC_set_dont_precollect(int value)
+GC_API int GC_CALL GC_get_full_freq(void)
{
- int ovalue = GC_dont_precollect;
- if (value != -1)
- GC_dont_precollect = value;
- return ovalue;
+ return GC_full_freq;
}
-GC_API int GC_CALL GC_set_full_freq(int value)
+GC_API void GC_CALL GC_set_time_limit(unsigned long value)
{
- int ovalue = GC_full_freq;
- if (value != -1)
- GC_full_freq = value;
- return ovalue;
+ GC_ASSERT(value != (unsigned long)-1L);
+ GC_time_limit = value;
}
-GC_API unsigned long GC_CALL GC_set_time_limit(unsigned long value)
+GC_API unsigned long GC_CALL GC_get_time_limit(void)
{
- unsigned long ovalue = GC_time_limit;
- if (value != (unsigned long)-1L)
- GC_time_limit = value;
- return ovalue;
+ return GC_time_limit;
}
"GC_is_valid_displacement produced incorrect result\n");
FAIL;
}
-# if !defined(MSWIN32) && !defined(MSWINCE)
- /* Harder to test under Windows without a gc.h declaration. */
+# if !defined(MSWINCE)
{
size_t i;
- extern void *GC_memalign();
GC_malloc(17);
for (i = sizeof(GC_word); i < 512; i *= 2) {
GC_enable_incremental();
# endif
InitializeCriticalSection(&incr_cs);
- (void) GC_set_warn_proc(warn_proc);
+ GC_set_warn_proc(warn_proc);
# ifdef MSWINCE
win_created_h = CreateEvent(NULL, FALSE, FALSE, NULL);
if (win_created_h == (HANDLE)NULL) {
n_tests = 0;
/* GC_enable_incremental(); */
- (void) GC_set_warn_proc(warn_proc);
+ GC_set_warn_proc(warn_proc);
th1 = PCR_Th_Fork(run_one_test, 0);
th2 = PCR_Th_Fork(run_one_test, 0);
run_one_test();
# define GC_free GC_debug_free
#endif
-int main()
+int main(void)
{
pthread_t th[NTHREADS];
pthread_attr_t attr;
# endif
# endif
# endif
- (void) GC_set_warn_proc(warn_proc);
+ GC_set_warn_proc(warn_proc);
if ((code = pthread_key_create(&fl_key, 0)) != 0) {
(void)GC_printf("Key creation failed %d\n", code);
FAIL;