From: hboehm <hboehm> Date: Fri, 12 Jun 2009 22:06:47 +0000 (+0000) Subject: 2009-06-12 Hans Boehm <Hans.Boehm@hp.com> (Really Ivan Maidanski) X-Git-Tag: gc7_2alpha2~4 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=2dd4ee71d0aac96610194d274862d582b28b6d4b;p=gc 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. --- diff --git a/ChangeLog b/ChangeLog index 07f7a184..85551c29 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,41 @@ +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 diff --git a/include/gc.h b/include/gc.h index c5d2b3ef..9aa3f4bf 100644 --- a/include/gc.h +++ b/include/gc.h @@ -96,13 +96,16 @@ GC_API GC_oom_func GC_oom_fn; /* 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 */ @@ -115,7 +118,8 @@ GC_API int GC_all_interior_pointers; /* 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 */ @@ -123,7 +127,8 @@ GC_API int GC_finalize_on_demand; /* 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 */ @@ -133,7 +138,8 @@ GC_API int GC_java_finalization; /* 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; @@ -144,8 +150,8 @@ 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. */ @@ -159,7 +165,8 @@ GC_API int GC_dont_gc; /* != 0 ==> Dont collect. In versions 6.2a1+, */ 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 */ @@ -181,13 +188,16 @@ GC_API int GC_full_freq; /* Number of partial collections between */ /* 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. */ @@ -196,7 +206,8 @@ GC_API int GC_no_dls; /* 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 */ @@ -211,12 +222,15 @@ GC_API GC_word GC_free_space_divisor; /* 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. */ @@ -238,7 +252,8 @@ GC_API int GC_dont_precollect; /* Don't collect as part of */ /* 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, */ @@ -253,7 +268,8 @@ GC_API unsigned long GC_time_limit; /* 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 */ @@ -283,6 +299,9 @@ GC_API char * GC_CALL GC_strdup (const char *str); 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); @@ -834,17 +853,15 @@ GC_API int GC_CALL GC_invoke_finalizers(void); /* 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 */ diff --git a/mallocx.c b/mallocx.c index 54ae1c4a..a86601d9 100644 --- a/mallocx.c +++ b/mallocx.c @@ -492,7 +492,7 @@ GC_API void * GC_CALL GC_malloc_uncollectable(size_t lb) /* 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; diff --git a/misc.c b/misc.c index 9bb8a165..ed9574b2 100644 --- a/misc.c +++ b/misc.c @@ -895,12 +895,12 @@ out: # 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); @@ -1067,10 +1067,18 @@ STATIC void GC_CALLBACK GC_default_warn_proc(char *msg, GC_word arg) 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 */ @@ -1080,19 +1088,17 @@ GC_API GC_warn_proc GC_CALL GC_set_warn_proc(GC_warn_proc p) # 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) @@ -1237,94 +1243,162 @@ GC_API int GC_CALL GC_get_parallel(void) 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; } diff --git a/tests/test.c b/tests/test.c index cb992e62..79ea8a04 100644 --- a/tests/test.c +++ b/tests/test.c @@ -1103,11 +1103,9 @@ void run_one_test(void) "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) { @@ -1518,7 +1516,7 @@ int APIENTRY WinMain(HINSTANCE instance, HINSTANCE prev, LPSTR cmd, int n) 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) { @@ -1573,7 +1571,7 @@ int test(void) 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(); @@ -1601,7 +1599,7 @@ void * thr_run_one_test(void * arg) # define GC_free GC_debug_free #endif -int main() +int main(void) { pthread_t th[NTHREADS]; pthread_attr_t attr; @@ -1647,7 +1645,7 @@ int main() # 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;