diff --git a/collects/future-visualizer/private/visualizer-data.rkt b/collects/future-visualizer/private/visualizer-data.rkt index 85a9aedb68..e74ffa2c57 100644 --- a/collects/future-visualizer/private/visualizer-data.rkt +++ b/collects/future-visualizer/private/visualizer-data.rkt @@ -399,7 +399,7 @@ gc-evts)]))) (define ngcs (length gcs)) ;If we have any GC events, the 0th element of 'data' contains them; - ;don't buid a timeline for it in the usual manner + ;don't build a timeline for it in the usual manner (define tls (build-timelines (if (zero? ngcs) data (vector-drop data 1)))) (define gc-timeline (process-timeline 'gc 'gc @@ -412,19 +412,20 @@ (event-or-gc-time gc) (gc-info-end-real-time gc) 'gc - i - #f + 'gc #f + (if (gc-info-major? gc) 'major 'minor) 'gc #f (event-pos-description i ngcs) #f #f #f #f #f #f #f #f)))) - (define all-evts (sort (flatten (append (process-timeline-events gc-timeline) - (for/list ([tl (in-list tls)]) (process-timeline-events tl)))) - #:key event-index + (define all-evts (sort (append (flatten (for/list ([tl (in-list tls)]) (process-timeline-events tl))) + (process-timeline-events gc-timeline)) + #:key event-index <)) + (define non-gc-evts (filter (λ (e) (not (gc-event? e))) all-evts)) (define future-tl-hash (let ([h (make-hash)]) - (for ([evt (in-list all-evts)]) + (for ([evt (in-list non-gc-evts)]) (let* ([fid (event-future-id evt)] [existing (hash-ref h fid '())]) (hash-set! h fid (cons evt existing)))) @@ -451,7 +452,7 @@ (build-creation-graph future-tl-hash))) (connect-event-chains! tr) (connect-target-fid-events! tr) - tr) + tr) ;;build-rtcall-hash : (listof event) -> (values (blocking_prim -o-> count) (sync_prim -o-> count) (fid -o-> rtcall-info) (define (build-rtcall-hashes evts) diff --git a/collects/future-visualizer/private/visualizer-drawing.rkt b/collects/future-visualizer/private/visualizer-drawing.rkt index 126308512b..5d293bc7bd 100644 --- a/collects/future-visualizer/private/visualizer-drawing.rkt +++ b/collects/future-visualizer/private/visualizer-drawing.rkt @@ -154,13 +154,13 @@ ;;calc-row-mid-y : uint uint trace -> uint (define (calc-row-mid-y proc-index row-height tr) - (define PADDING 2) - (floor (- (+ (* (if (> (trace-num-gcs tr) 0) - (- proc-index 1) - proc-index) - row-height) - (/ row-height 2)) - PADDING))) + (case proc-index + [(gc) 0] + [else + (define PADDING 2) + (floor (- (+ (* proc-index row-height) + (/ row-height 2)) + PADDING))])) ;Gets the center of a circle with (xleft, ytop) as the top-left coordinate. ;;calc-center : uint uint uint -> (values uint uint) @@ -375,7 +375,8 @@ #f #f)) (set-event-segment! evt seg) - (vector-set! last-right-edges (event-proc-index evt) (+ offset segw)) + (when (not is-gc-evt?) + (vector-set! last-right-edges (event-proc-index evt) (+ offset segw))) (values (cons seg segs) new-delta (max largest-x (+ offset segw) #;last-right-edge)))) diff --git a/collects/future-visualizer/private/visualizer-gui.rkt b/collects/future-visualizer/private/visualizer-gui.rkt index fd649ab3ab..b6d7e0971c 100644 --- a/collects/future-visualizer/private/visualizer-gui.rkt +++ b/collects/future-visualizer/private/visualizer-gui.rkt @@ -146,6 +146,24 @@ (send (send item get-editor) insert (format "~a (~a)" prim (hash-ref (trace-sync-counts the-trace) prim)))) (send sync-node open) + (define gc-node (send hlist-ctl new-list)) + (define gc-time (for/fold ([gc-time 0.0]) ([gc (in-list (process-timeline-events (trace-gc-timeline the-trace)))]) + (define item (send gc-node new-item)) + (define len-ms (- (event-end-time gc) (event-start-time gc))) + (send (send item get-editor) insert (format "~a: ~a - ~a (~a ms)" + (case (event-user-data gc) + [(major) "Major"] + [(minor) "Minor"]) + (relative-time the-trace (event-start-time gc)) + (relative-time the-trace (event-end-time gc)) + len-ms)) + (+ gc-time len-ms))) + (send (send gc-node get-editor) insert (format "GC's (~a total, ~a ms)" + (trace-num-gcs the-trace) + gc-time) + 0) + (send gc-node open) + (define right-panel (new panel:vertical-dragable% [parent main-panel] [stretchable-width #t])) diff --git a/collects/tests/future/trace.rkt b/collects/tests/future/trace.rkt index 055f0e56f0..9add0d5d83 100644 --- a/collects/tests/future/trace.rkt +++ b/collects/tests/future/trace.rkt @@ -4,7 +4,8 @@ future-visualizer/private/visualizer-data (for-syntax racket/base future-visualizer/private/visualizer-data) - (only-in future-visualizer/trace trace-futures)) + (only-in future-visualizer/trace trace-futures) + "vtrace3.rkt") #| @@ -39,6 +40,17 @@ Invariants: (event-or-gc-time (indexed-future-event-fevent e)) i)))))])) +;Each future timeline's events sorted in time order? +(define (check-future-timeline-ordering tr) + (define ftls (hash-values (trace-future-timelines tr))) + (for ([ftl (in-list ftls)]) + (let loop ([evts ftl]) + (cond + [(null? (cdr evts)) void] + [else + (check-true (<= (event-start-time (car evts)) (event-start-time (car (cdr evts))))) + (loop (cdr evts))])))) + (cond [(futures-enabled?) (define log1 (parameterize ([current-output-port (open-output-string)]) @@ -101,7 +113,10 @@ Invariants: (define blocks (filter worker-block-event? (trace-all-events tr))) (for ([b (in-list blocks)]) (check-true (event? (event-block-handled-event b))) - (check-true (symbol? (event-prim-name b)))))] + (check-true (symbol? (event-prim-name b))))) + + (let ([tr (build-trace vtrace-3)]) + (check-future-timeline-ordering tr))] [else (define l (trace-futures (let ([f (future (λ () (printf "hello\n")))]) (sleep 0.1) diff --git a/collects/tests/future/visualizer.rkt b/collects/tests/future/visualizer.rkt index 9e390b8401..e4da7e3dc6 100644 --- a/collects/tests/future/visualizer.rkt +++ b/collects/tests/future/visualizer.rkt @@ -15,6 +15,11 @@ segs (frame-info-timeline-ticks finfo))) +(define (check-in-bounds? segs finfo) + (for ([s (in-list segs)]) + (check-false (negative? (segment-y s))) + (check-true (< (segment-y s) (frame-info-adjusted-height finfo))))) + ;Display tests (let ([vr (viewable-region 3 3 500 500)]) (for ([i (in-range 4 503)]) @@ -103,7 +108,8 @@ (indexed-future-event 2 (future-event 0 1 'end-work 2 #f #f)) (indexed-future-event 3 (future-event 0 0 'complete 3 #f #f)))] [trace (build-trace future-log)]) - (let-values ([(finfo segments) (calc-segments trace)]) + (let-values ([(finfo segments) (calc-segments trace)]) + (check-in-bounds? segments finfo) (check-equal? (length segments) 4) (check-equal? (length (filter (λ (s) (segment-next-future-seg s)) segments)) 2) (check-equal? (length (filter (λ (s) (segment-next-targ-future-seg s)) segments)) 1) @@ -116,6 +122,7 @@ (indexed-future-event 3 (future-event 42 0 'complete 1.2 #f #f)))] [tr (build-trace future-log)]) (define-values (finfo segs) (calc-segments tr)) + (check-in-bounds? segs finfo) (define ticks (frame-info-timeline-ticks finfo)) (check-equal? (length ticks) 11)) @@ -171,7 +178,8 @@ (indexed-future-event 8 (future-event 42 1 'end-work 1.42 #f #f)) (indexed-future-event 9 (future-event 42 0 'result 1.43 #f #f)))] [tr (build-trace future-log)]) - (define-values (finfo segs) (calc-segments tr)) + (define-values (finfo segs) (calc-segments tr)) + (check-in-bounds? segs finfo) (define ticks (frame-info-timeline-ticks finfo)) (check-seg-layout tr segs ticks)) @@ -216,7 +224,7 @@ (segment (event index real-start-time real-end-time - 0 0 0 0 0 0 0 0 0 0 0 0 0 #f) + 0 0 0 0 0 0 0 0 0 0 0 0 0 #f #f) 0 0 0 0 #f #f #f #f #f #f #f #f #f)) @@ -329,7 +337,8 @@ (indexed-future-event 3 (gc-info #f 0 0 0 0 0 0 0 15.0 19.5)) (indexed-future-event 4 (future-event 1 1 'complete 20.0 #f 0)) (indexed-future-event 5 (future-event 1 1 'end-work 21.0 #f 0)))) -(let-values ([(tr finfo segs ticks) (compile-trace-data gc-log3)]) +(let-values ([(tr finfo segs ticks) (compile-trace-data gc-log3)]) + (check-in-bounds? segs finfo) (check-equal? (length (filter gc-event? (trace-all-events tr))) 2) (check-equal? (trace-num-gcs tr) 2) (check-equal? (length (trace-proc-timelines tr)) 2) @@ -339,7 +348,8 @@ (check-equal? (length gc-segs) 2) (for ([gs (in-list gc-segs)]) (check-true (= (segment-height gs) (frame-info-adjusted-height finfo))) - (check-true (> (segment-width gs) 10))))) + (check-true (> (segment-width gs) 10)) + (check-true (= (segment-y gs) 0))))) (check-true (work-event? (future-event #f 0 'start-work 1.0 #f 0))) (check-true (work-event? (future-event #f 0 'start-0-work 2.0 #f 0))) diff --git a/collects/tests/future/vtrace3.rkt b/collects/tests/future/vtrace3.rkt new file mode 100644 index 0000000000..9dccb2a1c4 --- /dev/null +++ b/collects/tests/future/vtrace3.rkt @@ -0,0 +1,87 @@ +#lang racket/base +(require (only-in future-visualizer/private/visualizer-data + indexed-future-event + future-event)) +(provide vtrace-3) + +(define vtrace-3 + (list + (indexed-future-event 0 '#s(future-event #f 0 create 1350710151424.755 #f 1)) + (indexed-future-event 1 '#s(future-event 1 1 start-work 1350710151424.851 #f 0)) + (indexed-future-event 2 '#s(future-event 1 1 sync 1350710151424.865 #f 0)) + (indexed-future-event 3 '#s(future-event #f 0 create 1350710151424.966 #f 2)) + (indexed-future-event 4 '#s(future-event 2 2 start-work 1350710151425.023 #f 0)) + (indexed-future-event 5 '#s(future-event 2 2 sync 1350710151425.024 #f 0)) + (indexed-future-event 6 '#s(future-event #f 0 create 1350710151425.041 #f 3)) + (indexed-future-event 7 '#s(future-event 3 3 start-work 1350710151425.082 #f 0)) + (indexed-future-event 8 '#s(future-event 3 3 sync 1350710151425.083 #f 0)) + (indexed-future-event 9 '#s(future-event #f 0 create 1350710151425.096 #f 4)) + (indexed-future-event 10 '#s(future-event 4 4 start-work 1350710151425.135 #f 0)) + (indexed-future-event 11 '#s(future-event 4 4 sync 1350710151425.135 #f 0)) + (indexed-future-event 12 '#s(future-event #f 0 create 1350710151425.148 #f 5)) + (indexed-future-event 13 '#s(future-event 5 5 start-work 1350710151425.215 #f 0)) + (indexed-future-event 14 '#s(future-event 5 5 sync 1350710151425.216 #f 0)) + (indexed-future-event 15 '#s(future-event 1 0 sync 1350710151425.235 |[jit_on_demand]| for-loop)) + (indexed-future-event 16 '#s(future-event 1 0 result 1350710151425.274 #f 0)) + (indexed-future-event 17 '#s(future-event 1 1 result 1350710151425.306 #f 0)) + (indexed-future-event 18 '#s(future-event 1 1 start-work 1350710151425.306 #f 0)) + (indexed-future-event 19 '#s(future-event 1 1 sync 1350710151425.307 #f 0)) + (indexed-future-event 20 '#s(future-event 1 0 sync 1350710151425.361 |[allocate memory]| 2)) + (indexed-future-event 21 '#s(future-event 1 0 result 1350710151425.365 #f 0)) + (indexed-future-event 22 '#s(future-event 5 0 sync 1350710151425.372 |[jit_on_demand]| for-loop)) + (indexed-future-event 23 '#s(future-event 5 0 result 1350710151425.375 #f 0)) + (indexed-future-event 24 '#s(future-event 1 1 result 1350710151425.376 #f 0)) + (indexed-future-event 25 '#s(future-event 1 1 start-work 1350710151425.38 #f 0)) + (indexed-future-event 26 '#s(future-event 1 1 sync 1350710151425.39 #f 0)) + (indexed-future-event 27 '#s(future-event 5 5 result 1350710151425.399 #f 0)) + (indexed-future-event 28 '#s(future-event 5 5 start-work 1350710151425.4 #f 0)) + (indexed-future-event 29 '#s(future-event 5 5 sync 1350710151425.406 #f 0)) + (indexed-future-event 30 '#s(future-event 1 0 sync 1350710151425.421 |[jit_on_demand]| loop-x)) + (indexed-future-event 31 '#s(future-event 1 0 result 1350710151425.564 #f 0)) + (indexed-future-event 32 '#s(future-event 1 1 result 1350710151425.571 #f 0)) + (indexed-future-event 33 '#s(future-event 1 1 start-work 1350710151425.571 #f 0)) + (indexed-future-event 34 '#s(future-event 1 1 complete 1350710151425.573 #f 0)) + (indexed-future-event 35 '#s(future-event 1 1 end-work 1350710151425.574 #f 0)) + (indexed-future-event 36 '#s(future-event 5 0 sync 1350710151425.576 |[allocate memory]| 2)) + (indexed-future-event 37 '#s(future-event 5 0 result 1350710151425.58 #f 0)) + (indexed-future-event 38 '#s(future-event 5 5 result 1350710151425.587 #f 0)) + (indexed-future-event 39 '#s(future-event 5 5 start-work 1350710151425.587 #f 0)) + (indexed-future-event 40 '#s(future-event 5 5 complete 1350710151425.589 #f 0)) + (indexed-future-event 41 '#s(future-event 5 5 end-work 1350710151425.59 #f 0)) + (indexed-future-event 42 '#s(future-event 4 0 sync 1350710151425.598 |[jit_on_demand]| for-loop)) + (indexed-future-event 43 '#s(future-event 4 0 result 1350710151425.601 #f 0)) + (indexed-future-event 44 '#s(future-event 4 4 result 1350710151425.606 #f 0)) + (indexed-future-event 45 '#s(future-event 4 4 start-work 1350710151425.606 #f 0)) + (indexed-future-event 46 '#s(future-event 4 4 sync 1350710151425.607 #f 0)) + (indexed-future-event 47 '#s(future-event 3 0 sync 1350710151425.617 |[jit_on_demand]| for-loop)) + (indexed-future-event 48 '#s(future-event 3 0 result 1350710151425.62 #f 0)) + (indexed-future-event 49 '#s(future-event 3 3 result 1350710151425.625 #f 0)) + (indexed-future-event 50 '#s(future-event 3 3 start-work 1350710151425.625 #f 0)) + (indexed-future-event 51 '#s(future-event 3 3 sync 1350710151425.625 #f 0)) + (indexed-future-event 52 '#s(future-event 4 0 sync 1350710151425.633 |[allocate memory]| 2)) + (indexed-future-event 53 '#s(future-event 4 0 result 1350710151425.637 #f 0)) + (indexed-future-event 54 '#s(future-event 4 4 result 1350710151425.641 #f 0)) + (indexed-future-event 55 '#s(future-event 4 4 start-work 1350710151425.642 #f 0)) + (indexed-future-event 56 '#s(future-event 4 4 complete 1350710151425.647 #f 0)) + (indexed-future-event 57 '#s(future-event 4 4 end-work 1350710151425.648 #f 0)) + (indexed-future-event 58 '#s(future-event 3 0 sync 1350710151425.65 |[allocate memory]| 2)) + (indexed-future-event 59 '#s(future-event 3 0 result 1350710151425.653 #f 0)) + (indexed-future-event 60 '#s(future-event 3 3 result 1350710151425.657 #f 0)) + (indexed-future-event 61 '#s(future-event 3 3 start-work 1350710151425.658 #f 0)) + (indexed-future-event 62 '#s(future-event 3 3 complete 1350710151425.662 #f 0)) + (indexed-future-event 63 '#s(future-event 3 3 end-work 1350710151425.663 #f 0)) + (indexed-future-event 64 '#s(future-event 2 0 sync 1350710151425.669 |[jit_on_demand]| for-loop)) + (indexed-future-event 65 '#s(future-event 2 0 result 1350710151425.672 #f 0)) + (indexed-future-event 66 '#s(future-event 1 0 touch-pause 1350710151425.675 #f 0)) + (indexed-future-event 67 '#s(future-event 2 2 result 1350710151425.676 #f 0)) + (indexed-future-event 68 '#s(future-event 2 2 start-work 1350710151425.678 #f 0)) + (indexed-future-event 69 '#s(future-event 1 0 touch-resume 1350710151425.686 #f 0)) + (indexed-future-event 70 '#s(future-event 2 2 sync 1350710151425.688 #f 0)) + (indexed-future-event 71 '#s(future-event 2 0 sync 1350710151425.724 |[allocate memory]| 2)) + (indexed-future-event 72 '#s(future-event 2 0 result 1350710151425.728 #f 0)) + (indexed-future-event 73 '#s(future-event 2 0 touch-pause 1350710151425.734 #f 0)) + (indexed-future-event 74 '#s(future-event 2 2 result 1350710151425.734 #f 0)) + (indexed-future-event 75 '#s(future-event 2 2 start-work 1350710151425.734 #f 0)) + (indexed-future-event 76 '#s(future-event 2 2 complete 1350710151425.738 #f 0)) + (indexed-future-event 77 '#s(future-event 2 2 end-work 1350710151425.739 #f 0)) + (indexed-future-event 78 '#s(future-event 2 0 touch-resume 1350710151425.748 #f 0))))