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.331 2008/10/12 22:41:16 mast Exp $ + || $Id: gc.c,v 1.332 2009/11/11 20:05:06 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:114: Inside #if defined(DO_PIKE_CLEANUP)
  int gc_trace = 0, gc_debug = 0;   #ifdef DO_PIKE_CLEANUP   int gc_destruct_everything = 0;   #endif   size_t gc_ext_weak_refs;      static double objects_alloced = 0.0;   static double objects_freed = 0.0;   static double gc_time = 0.0, non_gc_time = 0.0;   static cpu_time_t last_gc_end_time = 0; - #ifdef CPU_TIME_MIGHT_NOT_BE_THREAD_LOCAL +    cpu_time_t auto_gc_time = 0; - #endif + cpu_time_t auto_gc_real_time = 0;      struct link_frame /* See cycle checking blurb below. */   {    void *data;    struct link_frame *prev; /* Previous frame in the link stack. */    gc_cycle_check_cb *checkfn; /* Function to call to recurse the thing. */    int weak; /* Weak flag to checkfn. */   };      struct gc_rec_frame /* See cycle checking blurb below. */
pike.git/src/gc.c:3334:    }   #endif       CALL_AND_UNSET_ONERROR(tmp);   }      size_t do_gc(void *ignored, int explicit_call)   {    ALLOC_COUNT_TYPE start_allocs;    size_t start_num_objs, unreferenced; -  cpu_time_t gc_start_time; +  cpu_time_t gc_start_time, gc_start_real_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       if(Pike_in_gc) return 0;
pike.git/src/gc.c:3364:    }      #ifdef DEBUG_MALLOC    if(debug_options & GC_RESET_DMALLOC)    reset_debug_malloc();   #endif    init_gc();    gc_generation++;    Pike_in_gc=GC_PASS_PREPARE;    gc_start_time = get_cpu_time(); +  gc_start_real_time = get_real_time();    gc_debug = d_flag;   #ifdef PIKE_DEBUG    SET_ONERROR(uwp, fatal_on_error, "Shouldn't get an exception inside the gc.\n");    if (gc_is_watching)    fprintf(stderr, "## Doing gc while watching for %d things.\n", gc_is_watching);   #endif       destruct_objects_to_destruct();       if(gc_evaluator_callback)
pike.git/src/gc.c:3846:    new_threshold = (double)(alloc_threshold + start_allocs);   #endif       if(new_threshold < GC_MIN_ALLOC_THRESHOLD)    alloc_threshold = GC_MIN_ALLOC_THRESHOLD;    else if(new_threshold > GC_MAX_ALLOC_THRESHOLD)    alloc_threshold = GC_MAX_ALLOC_THRESHOLD;    else    alloc_threshold = (ALLOC_COUNT_TYPE) new_threshold;    -  if (!explicit_call && last_gc_time != (cpu_time_t) -1) { +  if (!explicit_call) { +  auto_gc_real_time += get_real_time() - gc_start_real_time; +  +  if (last_gc_time != (cpu_time_t) -1) {   #ifdef CPU_TIME_MIGHT_BE_THREAD_LOCAL    if (cpu_time_is_thread_local   #ifdef PIKE_DEBUG    /* At high debug levels, the gc may get called before    * the threads are initialized.    */    && Pike_interpreter.thread_state   #endif    )    Pike_interpreter.thread_state->auto_gc_time += last_gc_time; -  else +    #endif -  { - #ifdef CPU_TIME_MIGHT_NOT_BE_THREAD_LOCAL +     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)    sprintf (timestr, ", %ld ms",    (long) (last_gc_time / (CPU_TIME_TICKS / 1000)));    else
pike.git/src/gc.c:3953:    *! Decaying average over the CPU milliseconds spent inside the    *! garbage collector.    *! @member string "last_garbage_strategy"    *! The garbage accumulation goal that the gc aimed for when    *! setting "alloc_threshold" in the last run. The value is    *! either "garbage_ratio_low" or "garbage_ratio_high", which    *! corresponds to the gc parameters with the same names in    *! @[Pike.gc_parameters].    *! @member int "last_gc"    *! Time when the garbage-collector last ran. +  *! @member int "total_gc_cpu_time" +  *! The total amount of CPU time that has been consumed in +  *! implicit GC runs, in nanoseconds. 0 on systems where Pike +  *! lacks support for CPU time measurement. +  *! @member int "total_gc_real_time" +  *! The total amount of real time that has been spent in +  *! implicit GC runs, in nanoseconds.    *! @endmapping    *!    *! @seealso -  *! @[gc()], @[Pike.gc_parameters()] +  *! @[gc()], @[Pike.gc_parameters()], @[Pike.implicit_gc_real_time]    */   void f__gc_status(INT32 args)   {    int size = 0;       pop_n_elems(args);       push_constant_text("num_objects");    push_int(num_objects);    size++;
pike.git/src/gc.c:4015: Inside #if defined(PIKE_DEBUG)
  #ifdef PIKE_DEBUG    default: Pike_fatal ("Unknown last_garbage_strategy %d\n", last_garbage_strategy);   #endif    }    size++;       push_constant_text("last_gc");    push_int64(last_gc);    size++;    +  push_constant_text ("total_gc_cpu_time"); +  push_int64 (auto_gc_time); + #ifndef LONG_CPU_TIME +  push_int (1000000000 / CPU_TIME_TICKS); +  o_multiply(); + #endif +  size++; +  +  push_constant_text ("total_gc_real_time"); +  push_int64 (auto_gc_real_time); + #ifndef LONG_CPU_TIME +  push_int (1000000000 / CPU_TIME_TICKS); +  o_multiply(); + #endif +  size++; +    #ifdef PIKE_DEBUG    push_constant_text ("max_rec_frames");    push_int64 (DO_NOT_WARN ((INT64) tot_max_rec_frames));    size++;       push_constant_text ("max_link_frames");    push_int64 (DO_NOT_WARN ((INT64) tot_max_link_frames));    size++;       push_constant_text ("max_free_extra_frames");    push_int64 (DO_NOT_WARN ((INT64) tot_max_free_extra_frames));    size++;   #endif       f_aggregate_mapping(size * 2);   }    -  + /*! @decl int implicit_gc_real_time() +  *! @belongs Pike +  *! +  *! Returns the total amount of real time that has been spent in +  *! implicit GC runs, in nanoseconds. +  *! +  *! @seealso +  *! @[Debug.gc_status] +  */ + void f_implicit_gc_real_time (INT32 args) + { +  pop_n_elems (args); +  push_int64 (auto_gc_real_time); + #ifndef LONG_CPU_TIME +  push_int (1000000000 / CPU_TIME_TICKS); +  o_multiply(); + #endif + } +    void dump_gc_info(void)   {    fprintf(stderr,"Current number of things : %d\n",num_objects);    fprintf(stderr,"Allocations since last gc : "PRINT_ALLOC_COUNT_TYPE"\n",    num_allocs);    fprintf(stderr,"Threshold for next gc : "PRINT_ALLOC_COUNT_TYPE"\n",    alloc_threshold);    fprintf(stderr,"Projected current garbage : %f\n",    objects_freed * (double) num_allocs / (double) alloc_threshold);