pike.git / src / gc.c

version» Context lines:

pike.git/src/gc.c:1:   /*   || This file is part of Pike. For copyright information see COPYRIGHT.   || Pike is distributed under GPL, LGPL and MPL. See the file COPYING   || for more information. - || $Id: gc.c,v 1.244 2004/03/16 18:34:43 mast Exp $ + || $Id: gc.c,v 1.245 2004/03/17 19:27:23 mast Exp $   */      #include "global.h"      struct callback *gc_evaluator_callback=0;      #include "array.h"   #include "multiset.h"   #include "mapping.h"   #include "object.h"
pike.git/src/gc.c:26:   #include "interpret.h"   #include "bignum.h"   #include "pike_threadlib.h"      #include "gc.h"   #include "main.h"   #include <math.h>      #include "block_alloc.h"    - RCSID("$Id: gc.c,v 1.244 2004/03/16 18:34:43 mast Exp $"); + RCSID("$Id: gc.c,v 1.245 2004/03/17 19:27:23 mast Exp $");      int gc_enabled = 1;      /* These defaults are only guesses and hardly tested at all. Please improve. */   double gc_garbage_ratio_low = 0.2;   double gc_time_ratio = 0.05;   double gc_garbage_ratio_high = 0.5;      /* This slowness factor approximately corresponds to the average over    * the last ten gc rounds. (0.9 == 1 - 1/10) */
pike.git/src/gc.c:95:   #if defined(GC_VERBOSE) && !defined(PIKE_DEBUG)   #undef GC_VERBOSE   #endif   #ifdef GC_VERBOSE   #define GC_VERBOSE_DO(X) X   #else   #define GC_VERBOSE_DO(X)   #endif      int num_objects = 3; /* Account for *_empty_array. */ - int num_allocs =0; - ptrdiff_t alloc_threshold = GC_MIN_ALLOC_THRESHOLD; + unsigned LONGEST num_allocs =0; + unsigned LONGEST alloc_threshold = GC_MIN_ALLOC_THRESHOLD;   PMOD_EXPORT int Pike_in_gc = 0;   int gc_generation = 0;   time_t last_gc;   int gc_trace = 0, gc_debug = 0;   #ifdef DO_PIKE_CLEANUP   int gc_destruct_everything = 0;   #endif      struct gc_frame   {
pike.git/src/gc.c:2693:    }    if (!p) break;    }    }       CALL_AND_UNSET_ONERROR(tmp);   }      size_t do_gc(void *ignored, int explicit_call)   { -  size_t start_num_objs, start_allocs, unreferenced; +  unsigned LONGEST start_allocs; +  size_t start_num_objs, unreferenced;    cpu_time_t gc_start_time;    ptrdiff_t objs, pre_kill_objs;   #if defined (PIKE_DEBUG) || defined (DO_PIKE_CLEANUP)    unsigned destroy_count;   #endif   #ifdef PIKE_DEBUG    unsigned obj_count;    ONERROR uwp;   #endif   
pike.git/src/gc.c:2743:    if(gc_evaluator_callback)    {    remove_callback(gc_evaluator_callback);    gc_evaluator_callback=0;    }       objs=num_objects;    last_cycle = 0;       if(GC_VERBOSE_DO(1 ||) gc_trace) { -  fprintf(stderr,"Garbage collecting ... "); +  if (gc_destruct_everything) +  fprintf (stderr, "Destructing all objects... "); +  else +  fprintf(stderr,"Garbage collecting... ");    GC_VERBOSE_DO(fprintf(stderr, "\n"));    }   #ifdef PIKE_DEBUG    if(num_objects < 0)    Pike_fatal("Panic, less than zero objects!\n");   #endif       last_gc=TIME(0);    start_num_objs = num_objects;    start_allocs = num_allocs;
pike.git/src/gc.c:3117:    {    double multiplier, new_threshold;    cpu_time_t last_non_gc_time, last_gc_time;       /* If we're at an automatic and timely gc then start_allocs ==    * alloc_threshold and we're using gc_average_slowness in the    * decaying average calculation. Otherwise this is either an    * explicit call (start_allocs < alloc_threshold) or the gc has    * been delayed past its due time (start_allocs >    * alloc_threshold), and in those cases we adjust the multiplier -  * to appropriately weight this last instance. */ +  * to give the appropriate weight to this last instance. */    multiplier=pow(gc_average_slowness,    (double) start_allocs / (double) alloc_threshold);       /* Comparisons to avoid that overflows mess up the statistics. */    if (gc_start_time > last_gc_end_time) {    last_non_gc_time = gc_start_time - last_gc_end_time;    non_gc_time = non_gc_time * multiplier +    last_non_gc_time * (1.0 - multiplier);    }    else last_non_gc_time = (cpu_time_t) -1;
pike.git/src/gc.c:3179: Inside #if 0
   /* Afaics this is to limit the growth of the threshold to avoid    * that a single sudden allocation spike causes a very long gc    * interval the next time. Now when the bug in the decaying    * average calculation is fixed there should be no risk for that,    * at least not in any case when this would help. /mast */    if(alloc_threshold + start_allocs < new_threshold)    new_threshold = (double)(alloc_threshold + start_allocs);   #endif       if(new_threshold < GC_MIN_ALLOC_THRESHOLD) -  new_threshold = (double) GC_MIN_ALLOC_THRESHOLD; +  alloc_threshold = GC_MIN_ALLOC_THRESHOLD;    else if(new_threshold > GC_MAX_ALLOC_THRESHOLD) -  new_threshold = (double) GC_MAX_ALLOC_THRESHOLD; +  alloc_threshold = GC_MAX_ALLOC_THRESHOLD; +  else +  alloc_threshold = (unsigned LONGEST) new_threshold;    -  alloc_threshold = (ptrdiff_t)new_threshold; -  +     if (!explicit_call && last_gc_time != (cpu_time_t) -1) {   #if CPU_TIME_IS_THREAD_LOCAL == PIKE_YES    Pike_interpreter.thread_state->auto_gc_time += last_gc_time;   #elif CPU_TIME_IS_THREAD_LOCAL == PIKE_NO    auto_gc_time += last_gc_time;   #endif    }       if(GC_VERBOSE_DO(1 ||) gc_trace)    { -  +  char timestr[40];    if (last_gc_time != (cpu_time_t) -1) -  fprintf(stderr, "done (%"PRINTSIZET"d of %"PRINTSIZET"d " -  "was unreferenced), %ld ms.\n", -  unreferenced, start_num_objs, +  sprintf (timestr, ", %ld ms",    (long) (last_gc_time / (CPU_TIME_TICKS / 1000)));    else -  +  timestr[0] = 0; + #ifdef DO_PIKE_CLEANUP +  if (gc_destruct_everything) +  fprintf(stderr, "done (%"PRINTSIZET"d was destructed)%s\n", +  destroy_count, timestr); +  else + #endif    fprintf(stderr, "done (%"PRINTSIZET"d of %"PRINTSIZET"d " -  "was unreferenced)\n", -  unreferenced, start_num_objs); +  "was unreferenced)%s\n", +  unreferenced, start_num_objs, timestr);    }    }      #ifdef PIKE_DEBUG    UNSET_ONERROR (uwp);    if (max_gc_frames > max_tot_gc_frames) max_tot_gc_frames = max_gc_frames;    tot_cycle_checked += cycle_checked;    tot_live_rec += live_rec, tot_frame_rot += frame_rot;   #endif   
pike.git/src/gc.c:3282:   {    int size = 0;       pop_n_elems(args);       push_constant_text("num_objects");    push_int(num_objects);    size++;       push_constant_text("num_allocs"); -  push_int(num_allocs); +  push_int64(num_allocs);    size++;       push_constant_text("alloc_threshold");    push_int64(alloc_threshold);    size++;       push_constant_text("projected_garbage");    push_float(DO_NOT_WARN((FLOAT_TYPE)(objects_freed * (double) num_allocs /    (double) alloc_threshold)));    size++;
pike.git/src/gc.c:3334:    push_constant_text("last_gc");    push_int64(last_gc);    size++;       f_aggregate_mapping(size * 2);   }      void dump_gc_info(void)   {    fprintf(stderr,"Current number of things : %d\n",num_objects); -  fprintf(stderr,"Allocations since last gc : %d\n",num_allocs); -  fprintf(stderr,"Threshold for next gc : %"PRINTPTRDIFFT"d\n",alloc_threshold); +  fprintf(stderr,"Allocations since last gc : %"PRINTLONGEST"u\n",num_allocs); +  fprintf(stderr,"Threshold for next gc : %"PRINTLONGEST"u\n",alloc_threshold);    fprintf(stderr,"Projected current garbage : %f\n",    objects_freed * (double) num_allocs / (double) alloc_threshold);       fprintf(stderr,"Avg allocs between gc : %f\n",objects_alloced);    fprintf(stderr,"Avg frees per gc : %f\n",objects_freed);    fprintf(stderr,"Garbage ratio in last gc : %f\n", last_garbage_ratio);       fprintf(stderr,"Avg cpu "CPU_TIME_UNIT" between gc : %f\n", non_gc_time);    fprintf(stderr,"Avg cpu "CPU_TIME_UNIT" in gc : %f\n", gc_time);    fprintf(stderr,"Avg time ratio in gc : %f\n", gc_time / non_gc_time);