* gc.c (scm_igc): Check for scm_mallocated underflow. Otherwise,
authorJim Blandy <jimb@red-bean.com>
Wed, 9 Jun 1999 12:18:40 +0000 (12:18 +0000)
committerJim Blandy <jimb@red-bean.com>
Wed, 9 Jun 1999 12:18:40 +0000 (12:18 +0000)
it shows up as terrible performance, as we GC constantly.
* gc.c (scm_init_storage): install an atexit proc to flush the
ports.
(cleanup): the new proc.  it sets a global variable which can be
checked by the ptob flush procs to avoid trying to throw
exceptions during exit.  not very pleasant but it seems more reliable.
* fports.c (local_fflush): check terminating variable and if set
don't throw exception.
* CHECKME: that the atexit proc is installed if unexec used.

libguile/gc.c

index d80e711..572d8fc 100644 (file)
@@ -448,6 +448,18 @@ scm_igc (what)
 
   /* fprintf (stderr, "gc: %s\n", what); */
 
+  if (scm_mallocated > ((unsigned long) 0 - (1 << 24)))
+    {
+      /* It is extremely unlikely that you have allocated all but 16 Mb
+        (one sixteenth of 2^32) of your address space.  It is much more
+        likely that you have forgotten to report the sizes of objects
+        you have allocated via scm_done_malloc, or some such.  When the
+        GC freed them, it subtracted their size from scm_mallocated,
+        which underflowed.  Since it's unsigned, this looks like a
+        really big number, so we start GC'ing all the time.  */
+      abort ();
+    }
+
   scm_gc_start (what);
   if (!scm_stack_base || scm_block_gc)
     {
@@ -1866,6 +1878,14 @@ scm_unprotect_object (obj)
   return obj;
 }
 
+int terminating;
+
+/* called on process termination.  */
+static void cleanup (void)
+{
+  terminating = 1;
+  scm_flush_all_ports ();
+}
 
 \f
 int
@@ -1907,6 +1927,7 @@ scm_init_storage (scm_sizet init_heap_size)
   if (!scm_port_table)
     return 1;
 
+  atexit (cleanup);
 
   scm_undefineds = scm_cons (SCM_UNDEFINED, SCM_EOL);
   SCM_SETCDR (scm_undefineds, scm_undefineds);