/** * Copyright (C) 2012 FuseSource, Inc. * http://fusesource.com * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.fusesource.hawtdispatch.internal; import org.fusesource.hawtdispatch.DispatchQueue; import org.fusesource.hawtdispatch.Metrics; import org.fusesource.hawtdispatch.Task; import java.util.concurrent.atomic.AtomicLong; /** * * @author <a href="http://hiramchirino.com">Hiram Chirino</a> * */ final public class ActiveMetricsCollector extends MetricsCollector { private final DispatchQueue queue; private final AtomicLong max_run_time = new AtomicLong(); private final AtomicLong max_wait_time = new AtomicLong(); private final AtomicLong enqueued = new AtomicLong(); private final AtomicLong dequeued = new AtomicLong(); private final AtomicLong total_run_time = new AtomicLong(); private final AtomicLong total_wait_time = new AtomicLong(); private final AtomicLong reset_at = new AtomicLong(System.nanoTime()); public ActiveMetricsCollector(DispatchQueue queue) { this.queue = queue; } private void setMax(AtomicLong holder, long value) { while (true) { long p = holder.get(); if( value > p ) { if( holder.compareAndSet(p, value) ) { return; } } else { return; } } } public Task track(final Task runnable) { enqueued.incrementAndGet(); final long enqueuedAt = System.nanoTime(); return new Task(){ public void run() { long dequeued_at = System.nanoTime(); long wait_time = dequeued_at - enqueuedAt; total_wait_time.addAndGet(wait_time); setMax(max_wait_time,wait_time ); dequeued.incrementAndGet(); long dequeuedAt = dequeued_at; try { runnable.run(); } finally { long run_time = System.nanoTime() - dequeuedAt; total_run_time.addAndGet(run_time); setMax(max_run_time,run_time); } } }; } public Metrics metrics() { long now = System.nanoTime(); long start = reset_at.getAndSet(now); long enq = enqueued.getAndSet(0); long deq = dequeued.getAndSet(0); if( enq==0 && deq==0 ) { return null; } Metrics rc = new Metrics(); rc.durationNS = now-start; rc.queue = queue; rc.enqueued = enq; rc.dequeued = deq; rc.maxWaitTimeNS = max_wait_time.getAndSet(0); rc.maxRunTimeNS = max_run_time.getAndSet(0); rc.totalRunTimeNS = total_run_time.getAndSet(0); rc.totalWaitTimeNS = total_wait_time.getAndSet(0); return rc; } }