diff options
Diffstat (limited to 'libguile/gc.c')
-rw-r--r-- | libguile/gc.c | 94 |
1 files changed, 38 insertions, 56 deletions
diff --git a/libguile/gc.c b/libguile/gc.c index 0f3c98c18..9ff2d41ee 100644 --- a/libguile/gc.c +++ b/libguile/gc.c @@ -15,6 +15,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +#define _GNU_SOURCE /* #define DEBUGINFO */ @@ -52,6 +53,7 @@ extern unsigned long * __libc_ia64_register_backing_store_base; #include "libguile/validate.h" #include "libguile/deprecation.h" #include "libguile/gc.h" +#include "libguile/dynwind.h" #ifdef GUILE_DEBUG_MALLOC #include "libguile/debug-malloc.h" @@ -71,7 +73,7 @@ unsigned int scm_gc_running_p = 0; /* Lock this mutex before doing lazy sweeping. */ -scm_t_rec_mutex scm_i_sweep_mutex; +scm_i_pthread_mutex_t scm_i_sweep_mutex = SCM_I_PTHREAD_RECURSIVE_MUTEX_INITIALIZER; /* Set this to != 0 if every cell that is accessed shall be checked: */ @@ -206,9 +208,6 @@ SCM_DEFINE (scm_set_debug_cell_accesses_x, "set-debug-cell-accesses!", 1, 0, 0, -scm_t_key scm_i_freelist; -scm_t_key scm_i_freelist2; - /* scm_mtrigger * is the number of bytes of malloc allocation needed to trigger gc. @@ -327,7 +326,7 @@ SCM_DEFINE (scm_gc_stats, "gc-stats", 0, 0, 0, SCM answer; unsigned long *bounds = 0; int table_size = scm_i_heap_segment_table_size; - SCM_DEFER_INTS; + SCM_CRITICAL_SECTION_START; /* temporarily store the numbers, so as not to cause GC. @@ -399,7 +398,7 @@ SCM_DEFINE (scm_gc_stats, "gc-stats", 0, 0, 0, scm_from_ulong (local_protected_obj_count)), scm_cons (sym_heap_segments, heap_segs), SCM_UNDEFINED); - SCM_ALLOW_INTS; + SCM_CRITICAL_SECTION_END; free (bounds); return answer; @@ -474,7 +473,7 @@ scm_gc_for_newcell (scm_t_cell_type_statistics *freelist, SCM *free_cells) { SCM cell; - scm_rec_mutex_lock (&scm_i_sweep_mutex); + scm_i_scm_pthread_mutex_lock (&scm_i_sweep_mutex); *free_cells = scm_i_sweep_some_segments (freelist); if (*free_cells == SCM_EOL && scm_i_gc_grow_heap_p (freelist)) @@ -516,7 +515,7 @@ scm_gc_for_newcell (scm_t_cell_type_statistics *freelist, SCM *free_cells) *free_cells = SCM_FREE_CELL_CDR (cell); - scm_rec_mutex_unlock (&scm_i_sweep_mutex); + scm_i_pthread_mutex_unlock (&scm_i_sweep_mutex); return cell; } @@ -531,7 +530,14 @@ scm_t_c_hook scm_after_gc_c_hook; void scm_igc (const char *what) { - scm_rec_mutex_lock (&scm_i_sweep_mutex); + if (scm_block_gc) + return; + + scm_i_scm_pthread_mutex_lock (&scm_i_sweep_mutex); + + /* During the critical section, only the current thread may run. */ + scm_i_thread_put_to_sleep (); + ++scm_gc_running_p; scm_c_hook_run (&scm_before_gc_c_hook, 0); @@ -544,15 +550,6 @@ scm_igc (const char *what) : (scm_is_null (*SCM_FREELIST_LOC (scm_i_freelist2)) ? "o" : "m")); #endif - /* During the critical section, only the current thread may run. */ - scm_i_thread_put_to_sleep (); - - if (!scm_root || !scm_stack_base || scm_block_gc) - { - --scm_gc_running_p; - return; - } - gc_start_stats (what); @@ -637,14 +634,14 @@ scm_igc (const char *what) scm_c_hook_run (&scm_after_sweep_c_hook, 0); gc_end_stats (); + --scm_gc_running_p; scm_i_thread_wake_up (); /* See above. */ - --scm_gc_running_p; + scm_i_pthread_mutex_unlock (&scm_i_sweep_mutex); scm_c_hook_run (&scm_after_gc_c_hook, 0); - scm_rec_mutex_unlock (&scm_i_sweep_mutex); /* For debugging purposes, you could do @@ -731,9 +728,11 @@ scm_return_first_int (int i, ...) SCM scm_permanent_object (SCM obj) { - SCM_REDEFER_INTS; - scm_permobjs = scm_cons (obj, scm_permobjs); - SCM_REALLOW_INTS; + SCM cell = scm_cons (obj, SCM_EOL); + SCM_CRITICAL_SECTION_START; + SCM_SETCDR (cell, scm_permobjs); + scm_permobjs = cell; + SCM_CRITICAL_SECTION_END; return obj; } @@ -760,14 +759,14 @@ scm_gc_protect_object (SCM obj) SCM handle; /* This critical section barrier will be replaced by a mutex. */ - SCM_REDEFER_INTS; + SCM_CRITICAL_SECTION_START; handle = scm_hashq_create_handle_x (scm_protects, obj, scm_from_int (0)); SCM_SETCDR (handle, scm_sum (SCM_CDR (handle), scm_from_int (1))); protected_obj_count ++; - SCM_REALLOW_INTS; + SCM_CRITICAL_SECTION_END; return obj; } @@ -783,7 +782,7 @@ scm_gc_unprotect_object (SCM obj) SCM handle; /* This critical section barrier will be replaced by a mutex. */ - SCM_REDEFER_INTS; + SCM_CRITICAL_SECTION_START; if (scm_gc_running_p) { @@ -808,7 +807,7 @@ scm_gc_unprotect_object (SCM obj) } protected_obj_count --; - SCM_REALLOW_INTS; + SCM_CRITICAL_SECTION_END; return obj; } @@ -820,13 +819,13 @@ scm_gc_register_root (SCM *p) SCM key = scm_from_ulong ((unsigned long) p); /* This critical section barrier will be replaced by a mutex. */ - SCM_REDEFER_INTS; + SCM_CRITICAL_SECTION_START; handle = scm_hashv_create_handle_x (scm_gc_registered_roots, key, scm_from_int (0)); SCM_SETCDR (handle, scm_sum (SCM_CDR (handle), scm_from_int (1))); - SCM_REALLOW_INTS; + SCM_CRITICAL_SECTION_END; } void @@ -836,7 +835,7 @@ scm_gc_unregister_root (SCM *p) SCM key = scm_from_ulong ((unsigned long) p); /* This critical section barrier will be replaced by a mutex. */ - SCM_REDEFER_INTS; + SCM_CRITICAL_SECTION_START; handle = scm_hashv_get_handle (scm_gc_registered_roots, key); @@ -854,7 +853,7 @@ scm_gc_unregister_root (SCM *p) SCM_SETCDR (handle, count); } - SCM_REALLOW_INTS; + SCM_CRITICAL_SECTION_END; } void @@ -875,25 +874,6 @@ scm_gc_unregister_roots (SCM *b, unsigned long n) int scm_i_terminating; -/* called on process termination. */ -#ifdef HAVE_ATEXIT -static void -cleanup (void) -#else -#ifdef HAVE_ON_EXIT -extern int on_exit (void (*procp) (), int arg); - -static void -cleanup (int status, void *arg) -#else -#error Dont know how to setup a cleanup handler on your system. -#endif -#endif -{ - scm_i_terminating = 1; - scm_flush_all_ports (); -} - @@ -926,18 +906,13 @@ scm_storage_prehistory () scm_c_hook_init (&scm_after_gc_c_hook, 0, SCM_C_HOOK_NORMAL); } -scm_t_mutex scm_i_gc_admin_mutex; +scm_i_pthread_mutex_t scm_i_gc_admin_mutex = SCM_I_PTHREAD_MUTEX_INITIALIZER; int scm_init_storage () { size_t j; - /* Fixme: Should use mutexattr from the low-level API. */ - scm_rec_mutex_init (&scm_i_sweep_mutex, &scm_i_plugin_rec_mutex); - - scm_i_plugin_mutex_init (&scm_i_gc_admin_mutex, &scm_i_plugin_mutex); - j = SCM_NUM_PROTECTS; while (j) scm_sys_protects[--j] = SCM_BOOL_F; @@ -955,6 +930,10 @@ scm_init_storage () if (!scm_i_port_table) return 1; +#if 0 + /* We can't have a cleanup handler since we have no thread to run it + in. */ + #ifdef HAVE_ATEXIT atexit (cleanup); #else @@ -963,6 +942,8 @@ scm_init_storage () #endif #endif +#endif + scm_stand_in_procs = scm_c_make_hash_table (257); scm_permobjs = SCM_EOL; scm_protects = scm_c_make_hash_table (31); @@ -1023,6 +1004,7 @@ mark_gc_async (void * hook_data SCM_UNUSED, * collection hooks and the execution count of the scheme level * after-gc-hook. */ + #if (SCM_DEBUG_CELL_ACCESSES == 1) if (scm_debug_cells_gc_interval == 0) scm_system_async_mark (gc_async); |