mirror of
https://git.savannah.gnu.org/git/guile.git
synced 2025-05-20 03:30:27 +02:00
attempt to handle steady-state mallocations better
* libguile/gc-malloc.c (scm_realloc): Call the new scm_gc_register_allocation() here. If we have to collect, do a GC_gcollect_and_unmap. * libguile/gc.c (scm_gc_register_allocation): Add a routine to track steady-state mallocation, and cause gc to run if there is a high mallocation rate. (adjust_gc_frequency): Reset the bytes-until-GC countdown timer.
This commit is contained in:
parent
9f7537dcab
commit
fd51e66190
3 changed files with 40 additions and 1 deletions
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue