~ chicken-core (chicken-5) a68c580475ded09cc716e5777a2a63cc29ba26ec


commit a68c580475ded09cc716e5777a2a63cc29ba26ec
Author:     Peter Bex <peter@more-magic.net>
AuthorDate: Sat Jan 2 17:24:37 2016 +0100
Commit:     Evan Hanson <evhan@foldling.org>
CommitDate: Sat Jan 16 19:23:11 2016 +1300

    Fix statistical percentage chicken-profile output
    
    Now both profiling types write a header in the first line to indicate
    the type of file, so that chicken-profiles knows whether to take the
    highest or the total of the run time as 100% when dividing.
    
    Signed-off-by: Evan Hanson <evhan@foldling.org>

diff --git a/chicken-profile.scm b/chicken-profile.scm
index 61ec0050..7e70236f 100644
--- a/chicken-profile.scm
+++ b/chicken-profile.scm
@@ -159,8 +159,10 @@ EOF
   (make-vector symbol-table-size '()))
 
 (define (read-profile)
-  (let ((hash (make-symbol-table)))
-    (do ((line (read) (read)))
+  (let* ((hash (make-symbol-table))
+	 (header (read))
+	 (type (if (symbol? header) header 'instrumented)))
+    (do ((line (if (symbol? header) (read) header) (read)))
 	((eof-object? line))
       (##sys#hash-table-set!
        hash (first line)
@@ -172,7 +174,7 @@ EOF
        (lambda (sym counts)
 	 (set! alist (alist-cons sym counts alist)))
        hash)
-      alist)))
+      (cons type alist))))
 
 (define (format-string str cols #!optional right (padc #\space))
   (let* ((len (string-length str))
@@ -195,17 +197,26 @@ EOF
 
 (define (write-profile)
   (print "reading `" file "' ...\n")
-  (let* ((data0 (with-input-from-file file read-profile))
-	 (max-t (foldl (lambda (r t) (max r (third t))) 0 data0))
+  (let* ((type&data0 (with-input-from-file file read-profile))
+	 (type  (car type&data0))
+	 (data0 (cdr type&data0))
+	 ;; Instrumented profiling results in total runtime being
+	 ;; counted for the outermost "main" procedure, while
+	 ;; statistical counts time spent only inside the procedure
+	 ;; itself.  Ideally we'd have both, but that's tricky to do.
+	 (total-t (foldl (if (eq? type 'instrumented)
+			     (lambda (r t) (max r (third t)))
+			     (lambda (r t) (+ r (third t))))
+			 0 data0))
 	 (data (sort (map
 		      (lambda (t)
 			(append
 			 t
 			 (let ((c (second t)) ; count
-			       (t (third t))) ; total time
+			       (t (third t))) ; time tallied to procedure
 			   (list (or (and c (> c 0) (/ t c)) ; time / count
 				     0)
-				 (or (and (> max-t 0) (* (/ t max-t) 100)) ; % of max-time
+				 (or (and (> total-t 0) (* (/ t total-t) 100)) ; % of total-time
 				     0)
 				 ))))
 		      data0)
diff --git a/profiler.scm b/profiler.scm
index 621f4ed4..f39f807d 100644
--- a/profiler.scm
+++ b/profiler.scm
@@ -37,6 +37,10 @@
 
 (define-constant profile-info-entry-size 5)
 
+(define empty-file?
+  (foreign-lambda* bool ((scheme-object p))
+    "C_return(ftell(C_port_file(p)) == 0);"))
+
 
 ;;; Globals:
 
@@ -122,7 +126,10 @@
 	(##sys#print "[debug] writing profile...\n" #f ##sys#standard-error) )
       (apply
        with-output-to-file ##sys#profile-name
-       (lambda () 
+       (lambda ()
+	 (when (empty-file? (current-output-port)) ; header needed?
+	   (write 'instrumented)
+	   (write-char #\newline))
 	 (for-each
 	  (lambda (vec)
 	    (let ([len (##sys#size vec)])
diff --git a/runtime.c b/runtime.c
index 460c0cfc..b4ab27ed 100644
--- a/runtime.c
+++ b/runtime.c
@@ -13234,6 +13234,7 @@ C_word C_i_dump_statistical_profile()
   if (fp == NULL)
     panic(C_text("could not write profile!"));
 
+  C_fputs(C_text("statistical\n"), fp);
   for(n = 0; n < PROFILE_TABLE_SIZE; ++n) {
     for(b = bp[ n ]; b != NULL; b = b2) {
       b2 = b->next;
Trap