diff -up ./byterun/sys.h.orig ./byterun/sys.h --- ./byterun/sys.h.orig 2007-02-25 13:38:36.000000000 +0100 +++ ./byterun/sys.h 2007-10-03 15:42:18.000000000 +0200 @@ -27,4 +27,6 @@ CAMLextern value caml_sys_exit (value); extern char * caml_exe_name; +double caml_tick (void); + #endif /* CAML_SYS_H */ diff -up ./byterun/minor_gc.c.orig ./byterun/minor_gc.c --- ./byterun/minor_gc.c.orig 2005-09-22 16:21:50.000000000 +0200 +++ ./byterun/minor_gc.c 2007-10-03 15:42:18.000000000 +0200 @@ -27,6 +27,9 @@ #include "roots.h" #include "signals.h" +#include "alloc.h" +#include "sys.h" + asize_t caml_minor_heap_size; CAMLexport char *caml_young_start = NULL, *caml_young_end = NULL; CAMLexport char *caml_young_ptr = NULL, *caml_young_limit = NULL; @@ -35,6 +38,20 @@ CAMLexport value **caml_ref_table_ptr = static asize_t ref_table_size, ref_table_reserve; int caml_in_minor_collection = 0; +static int caml_gc_timing; +double caml_gc_time = 0.; + +CAMLprim value caml_get_gc_time (value unit) +{ + return caml_copy_double (caml_gc_time); +} + +CAMLprim value caml_set_gc_timing (value v) +{ + caml_gc_timing = Bool_val (v); + return Val_unit; +} + void caml_set_minor_heap_size (asize_t size) { char *new_heap; @@ -217,8 +234,13 @@ void caml_empty_minor_heap (void) */ CAMLexport void caml_minor_collection (void) { + double t_start, t_end; + intnat prev_alloc_words = caml_allocated_words; + if (caml_gc_timing) + t_start = caml_tick (); + caml_empty_minor_heap (); caml_stat_promoted_words += caml_allocated_words - prev_alloc_words; @@ -229,6 +251,12 @@ CAMLexport void caml_minor_collection (v caml_final_do_calls (); caml_empty_minor_heap (); + + if (caml_gc_timing) + { + t_end = caml_tick (); + caml_gc_time += t_end - t_start; + } } CAMLexport value caml_check_urgent_gc (value extra_root) diff -up ./byterun/sys.c.orig ./byterun/sys.c --- ./byterun/sys.c.orig 2007-03-01 14:37:39.000000000 +0100 +++ ./byterun/sys.c 2007-10-03 15:42:18.000000000 +0200 @@ -344,3 +344,54 @@ CAMLprim value caml_sys_read_directory(v caml_ext_table_free(&tbl, 1); CAMLreturn(result); } + + +#include +static long dumb_gettime (clockid_t i, struct timespec *ts) +{ + double t = clock () / (double) CLOCKS_PER_SEC; + ts->tv_sec = t; + ts->tv_nsec = (t - floor(t)) * 1e9; + return 0; +} + +static long (* gettime)(clockid_t, struct timespec *); + +#include +static void init_gettime () +{ + void *h; + h = dlopen ("librt.so", RTLD_LAZY); + if (! h) + goto fail; + dlerror (); + *(void **)(&gettime) = dlsym (h, "clock_gettime"); + if (dlerror () != NULL) + { + dlclose (h); + goto fail; + } + return; + + fail: + gettime = dumb_gettime; +} + + +double caml_tick () +{ + struct timespec tp; + + if (! gettime) + init_gettime(); + + if (gettime (CLOCK_PROCESS_CPUTIME_ID, &tp)) + abort(); + + return tp.tv_sec + (1.e-9) * tp.tv_nsec; +} + +CAMLprim value caml_get_tick (value unit) +{ + return caml_copy_double (caml_tick ()); +}