--- /dev/null 2016-10-25 08:46:44.038854975 +0200
+++ new/src/share/classes/sun/evtracing/processing/TraceEventReorderHandler.java 2016-10-25 10:40:46.461802206 +0200
@@ -0,0 +1,147 @@
+/*
+ * Copyright (c) 2014, 2015, Dynatrace and/or its affiliates. All rights reserved.
+ *
+ * This file is part of the Lock Contention Tracing Subsystem for the HotSpot
+ * Virtual Machine, which is developed at Christian Doppler Laboratory on
+ * Monitoring and Evolution of Very-Large-Scale Software Systems. Please
+ * contact us at if you need additional information
+ * or have any questions.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work. If not, see .
+ *
+ */
+package sun.evtracing.processing;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import sun.evtracing.parser.GroupEvent;
+import sun.evtracing.parser.MetadataResetEvent;
+import sun.evtracing.parser.MonitorContendedEnterEvent;
+import sun.evtracing.parser.MonitorContendedEnteredEvent;
+import sun.evtracing.parser.MonitorContendedExitedEvent;
+import sun.evtracing.parser.MonitorDeflateEvent;
+import sun.evtracing.parser.MonitorDummyEvent;
+import sun.evtracing.parser.MonitorEvent;
+import sun.evtracing.parser.MonitorInflateEvent;
+import sun.evtracing.parser.ThreadInterruptEvent;
+import sun.evtracing.parser.ThreadParkBeginEvent;
+import sun.evtracing.parser.ThreadParkEndEvent;
+import sun.evtracing.parser.GlobalSequenceOrderedEvent;
+import sun.evtracing.parser.ThreadUnparkEvent;
+
+public class TraceEventReorderHandler extends DelegateTraceEventHandler {
+
+ private int maxGlobalQueueLength = 0;
+ private int maxMonitorQueueLength = 0;
+
+ private final SequenceOrderedEventQueue globalQueue = new SequenceOrderedEventQueue(delegateHandler());
+ private final Map monitorQueues = new HashMap<>();
+
+ public TraceEventReorderHandler(TraceEventHandler handler) {
+ super(handler);
+ }
+
+ private SequenceOrderedEventQueue getOrCreateMonitorQueue(long monitor) {
+ return monitorQueues.computeIfAbsent(monitor, t -> new SequenceOrderedEventQueue(delegateHandler()));
+ }
+
+ private void handleGlobalSequenceOrderedEvent(GlobalSequenceOrderedEvent event) {
+ globalQueue.addEvent(event);
+ maxGlobalQueueLength = Math.max(maxGlobalQueueLength, globalQueue.size());
+ }
+
+ @Override
+ public void threadInterrupt(ThreadInterruptEvent event) {
+ handleGlobalSequenceOrderedEvent(event);
+ }
+
+ @Override
+ public void threadParkBegin(ThreadParkBeginEvent event) {
+ handleGlobalSequenceOrderedEvent(event);
+ }
+
+ @Override
+ public void threadParkEnd(ThreadParkEndEvent event) {
+ handleGlobalSequenceOrderedEvent(event);
+ }
+
+ @Override
+ public void threadUnpark(ThreadUnparkEvent event) {
+ handleGlobalSequenceOrderedEvent(event);
+ }
+
+ @Override
+ public void group(GroupEvent event) {
+ handleGlobalSequenceOrderedEvent(event);
+ }
+
+ private void handleMonitorEvent(MonitorEvent event) {
+ SequenceOrderedEventQueue q = getOrCreateMonitorQueue(event.monitor());
+ q.addEvent(event);
+ maxMonitorQueueLength = Math.max(maxMonitorQueueLength, q.size());
+ }
+
+ @Override
+ public void monitorInflate(MonitorInflateEvent event) {
+ handleMonitorEvent(event);
+ }
+
+ @Override
+ public void monitorContendedEnter(MonitorContendedEnterEvent event) {
+ handleMonitorEvent(event);
+ }
+
+ @Override
+ public void monitorContendedEntered(MonitorContendedEnteredEvent event) {
+ handleMonitorEvent(event);
+ }
+
+ @Override
+ public void monitorContendedExited(MonitorContendedExitedEvent event) {
+ handleMonitorEvent(event);
+ }
+
+ @Override
+ public void monitorDummy(MonitorDummyEvent event) {
+ handleMonitorEvent(event);
+ }
+
+ @Override
+ public void monitorDeflate(MonitorDeflateEvent event) {
+ handleMonitorEvent(event);
+ }
+
+ @Override
+ public void metadataReset(MetadataResetEvent event) {
+ // at this point, we must have received all missing events
+ assert globalQueue.size() == 0;
+ assert !monitorQueues.values().stream().anyMatch(q -> (q.size() != 0));
+ super.metadataReset(event);
+ }
+
+ @Override
+ public void putStatistics(Map map) {
+ map.put("max_global_queue_length", (double) maxGlobalQueueLength);
+ map.put("max_monitor_queue_length", (double) maxMonitorQueueLength);
+ map.put("monitor_queues", (double) monitorQueues.size());
+ super.putStatistics(map);
+ }
+
+ @Override
+ public void resetStatistics() {
+ maxGlobalQueueLength = maxMonitorQueueLength = 0;
+ super.resetStatistics();
+ }
+}