summaryrefslogtreecommitdiff
path: root/libguile/gc.c
diff options
context:
space:
mode:
Diffstat (limited to 'libguile/gc.c')
-rw-r--r--libguile/gc.c94
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);