diff options
Diffstat (limited to 'libguile')
-rw-r--r-- | libguile/gc-malloc.c | 4 | ||||
-rw-r--r-- | libguile/gc.c | 35 | ||||
-rw-r--r-- | libguile/gc.h | 2 |
3 files changed, 40 insertions, 1 deletions
diff --git a/libguile/gc-malloc.c b/libguile/gc-malloc.c index c64ea2f33..a7dab2a7e 100644 --- a/libguile/gc-malloc.c +++ b/libguile/gc-malloc.c @@ -89,12 +89,14 @@ scm_realloc (void *mem, size_t size) { void *ptr; + scm_gc_register_allocation (size); + SCM_SYSCALL (ptr = realloc (mem, size)); if (ptr) return ptr; /* Time is hard: trigger a full, ``stop-the-world'' GC, and try again. */ - GC_gcollect (); + GC_gcollect_and_unmap (); SCM_SYSCALL (ptr = realloc (mem, size)); if (ptr) diff --git a/libguile/gc.c b/libguile/gc.c index 6d420c8a6..c03c23982 100644 --- a/libguile/gc.c +++ b/libguile/gc.c @@ -787,6 +787,10 @@ get_image_size (void) return ret; } +/* These are discussed later. */ +static size_t bytes_until_gc; +static scm_i_pthread_mutex_t bytes_until_gc_lock = SCM_I_PTHREAD_MUTEX_INITIALIZER; + /* Make GC run more frequently when the process image size is growing, measured against the number of bytes allocated through the GC. @@ -832,6 +836,10 @@ adjust_gc_frequency (void * hook_data SCM_UNUSED, size_t image_size; size_t bytes_alloced; + scm_i_pthread_mutex_lock (&bytes_until_gc_lock); + bytes_until_gc = GC_get_heap_size (); + scm_i_pthread_mutex_unlock (&bytes_until_gc_lock); + image_size = get_image_size (); bytes_alloced = GC_get_total_bytes (); @@ -895,6 +903,33 @@ adjust_gc_frequency (void * hook_data SCM_UNUSED, return NULL; } +/* The adjust_gc_frequency routine handles transients in the process + image size. It can't handle instense non-GC-managed steady-state + allocation though, as it decays the FSD at steady-state down to its + minimum value. + + The only real way to handle continuous, high non-GC allocation is to + let the GC know about it. This routine can handle non-GC allocation + rates that are similar in size to the GC-managed heap size. + */ + +void +scm_gc_register_allocation (size_t size) +{ + scm_i_pthread_mutex_lock (&bytes_until_gc_lock); + if (bytes_until_gc - size > bytes_until_gc) + { + bytes_until_gc = GC_get_heap_size (); + scm_i_pthread_mutex_unlock (&bytes_until_gc_lock); + GC_gcollect (); + } + else + { + bytes_until_gc -= size; + scm_i_pthread_mutex_unlock (&bytes_until_gc_lock); + } +} + diff --git a/libguile/gc.h b/libguile/gc.h index a19b9de87..310569d29 100644 --- a/libguile/gc.h +++ b/libguile/gc.h @@ -182,6 +182,8 @@ SCM_INTERNAL void scm_i_gc (const char *what); SCM_API void scm_gc_mark (SCM p); SCM_API void scm_gc_sweep (void); +SCM_API void scm_gc_register_allocation (size_t size); + SCM_API void *scm_malloc (size_t size) SCM_MALLOC; SCM_API void *scm_calloc (size_t size) SCM_MALLOC; SCM_API void *scm_realloc (void *mem, size_t size); |