14ae67516Stomee /* 24ae67516Stomee * CDDL HEADER START 34ae67516Stomee * 44ae67516Stomee * The contents of this file are subject to the terms of the 54ae67516Stomee * Common Development and Distribution License (the "License"). 64ae67516Stomee * You may not use this file except in compliance with the License. 74ae67516Stomee * 84ae67516Stomee * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 94ae67516Stomee * or http://www.opensolaris.org/os/licensing. 104ae67516Stomee * See the License for the specific language governing permissions 114ae67516Stomee * and limitations under the License. 124ae67516Stomee * 134ae67516Stomee * When distributing Covered Code, include this CDDL HEADER in each 144ae67516Stomee * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 154ae67516Stomee * If applicable, add the following below this CDDL HEADER, with the 164ae67516Stomee * fields enclosed by brackets "[]" replaced with your own identifying 174ae67516Stomee * information: Portions Copyright [yyyy] [name of copyright owner] 184ae67516Stomee * 194ae67516Stomee * CDDL HEADER END 204ae67516Stomee */ 214ae67516Stomee 224ae67516Stomee /* 234ae67516Stomee * Copyright 2007 Sun Microsystems, Inc. All rights reserved. 244ae67516Stomee * Use is subject to license terms. 254ae67516Stomee */ 264ae67516Stomee import java.util.*; 274ae67516Stomee import java.util.concurrent.atomic.*; 284ae67516Stomee import org.opensolaris.os.dtrace.*; 294ae67516Stomee 304ae67516Stomee /** 314ae67516Stomee * Regression test for 6521523 aggregation drops can hang the Java 324ae67516Stomee * DTrace API. 334ae67516Stomee */ 344ae67516Stomee public class TestDrop { 354ae67516Stomee static final String PROGRAM = 364ae67516Stomee "fbt:genunix::entry { @[execname, pid] = count(); }"; 374ae67516Stomee 384ae67516Stomee static AtomicLong consumerThreadID = new AtomicLong(); 394ae67516Stomee static AtomicLong getAggregateThreadID = new AtomicLong(); 404ae67516Stomee static AtomicBoolean done = new AtomicBoolean(); 414ae67516Stomee static int seconds; 424ae67516Stomee 434ae67516Stomee private static void startTimer()444ae67516Stomee startTimer() 454ae67516Stomee { 464ae67516Stomee if (seconds <= 0) { 474ae67516Stomee return; 484ae67516Stomee } 494ae67516Stomee 504ae67516Stomee final Timer timer = new Timer(); 514ae67516Stomee timer.schedule(new TimerTask() { 524ae67516Stomee public void run() { 534ae67516Stomee done.set(true); 544ae67516Stomee timer.cancel(); 554ae67516Stomee } 564ae67516Stomee }, seconds * 1000L); 574ae67516Stomee } 584ae67516Stomee 594ae67516Stomee private static void sampleAggregate(Consumer consumer)604ae67516Stomee sampleAggregate(Consumer consumer) throws DTraceException 614ae67516Stomee { 624ae67516Stomee while (consumer.isRunning() && !done.get()) { 634ae67516Stomee try { 64*4d0eb50eSRichard PALO Thread.sleep(50); 654ae67516Stomee } catch (InterruptedException e) { 664ae67516Stomee } 674ae67516Stomee 684ae67516Stomee consumer.getAggregate(Collections. <String> emptySet()); 694ae67516Stomee } 704ae67516Stomee } 714ae67516Stomee 724ae67516Stomee private static void startAggregateThread(final Consumer consumer)734ae67516Stomee startAggregateThread(final Consumer consumer) 744ae67516Stomee { 754ae67516Stomee Runnable aggregateSampler = new Runnable() { 764ae67516Stomee public void run() { 774ae67516Stomee Thread t = Thread.currentThread(); 784ae67516Stomee getAggregateThreadID.set(t.getId()); 794ae67516Stomee Throwable x = null; 804ae67516Stomee try { 814ae67516Stomee sampleAggregate(consumer); 824ae67516Stomee } catch (Throwable e) { 834ae67516Stomee x = e; 844ae67516Stomee } 854ae67516Stomee 864ae67516Stomee if (Thread.holdsLock(LocalConsumer.class)) { 874ae67516Stomee if (x != null) { 884ae67516Stomee x.printStackTrace(); 894ae67516Stomee } 904ae67516Stomee System.out.println("Lock held"); 914ae67516Stomee System.exit(1); 924ae67516Stomee } else { 934ae67516Stomee System.out.println("Lock released"); 944ae67516Stomee consumer.close(); // blocks if lock held 954ae67516Stomee } 964ae67516Stomee } 974ae67516Stomee }; 984ae67516Stomee 994ae67516Stomee Thread t = new Thread(aggregateSampler, "Aggregate Sampler"); 1004ae67516Stomee t.start(); 1014ae67516Stomee } 1024ae67516Stomee 1034ae67516Stomee static void usage()1044ae67516Stomee usage() 1054ae67516Stomee { 1064ae67516Stomee System.err.println("usage: java TestDrop [ seconds ]"); 1074ae67516Stomee System.exit(2); 1084ae67516Stomee } 1094ae67516Stomee 1104ae67516Stomee public static void main(String[] args)1114ae67516Stomee main(String[] args) 1124ae67516Stomee { 1134ae67516Stomee if (args.length == 1) { 1144ae67516Stomee try { 1154ae67516Stomee seconds = Integer.parseInt(args[0]); 1164ae67516Stomee } catch (NumberFormatException e) { 1174ae67516Stomee usage(); 1184ae67516Stomee } 1194ae67516Stomee } else if (args.length > 1) { 1204ae67516Stomee usage(); 1214ae67516Stomee } 1224ae67516Stomee 1234ae67516Stomee final Consumer consumer = new LocalConsumer() { 1244ae67516Stomee protected Thread createThread() { 1254ae67516Stomee Runnable worker = new Runnable() { 1264ae67516Stomee public void run() { 1274ae67516Stomee Thread t = Thread.currentThread(); 1284ae67516Stomee consumerThreadID.set(t.getId()); 1294ae67516Stomee work(); 1304ae67516Stomee } 1314ae67516Stomee }; 1324ae67516Stomee Thread t = new Thread(worker); 1334ae67516Stomee return t; 1344ae67516Stomee } 1354ae67516Stomee }; 1364ae67516Stomee 1374ae67516Stomee consumer.addConsumerListener(new ConsumerAdapter() { 1384ae67516Stomee public void consumerStarted(ConsumerEvent e) { 1394ae67516Stomee startAggregateThread(consumer); 1404ae67516Stomee startTimer(); 1414ae67516Stomee } 1424ae67516Stomee public void dataDropped(DropEvent e) throws ConsumerException { 1434ae67516Stomee Thread t = Thread.currentThread(); 1444ae67516Stomee if (t.getId() == getAggregateThreadID.get()) { 1454ae67516Stomee Drop drop = e.getDrop(); 1464ae67516Stomee throw new ConsumerException(drop.getDefaultMessage(), 1474ae67516Stomee drop); 1484ae67516Stomee } 1494ae67516Stomee } 1504ae67516Stomee }); 1514ae67516Stomee 1524ae67516Stomee try { 1534ae67516Stomee consumer.open(); 1544ae67516Stomee consumer.setOption(Option.aggsize, Option.kb(1)); 1554ae67516Stomee consumer.setOption(Option.aggrate, Option.millis(101)); 1564ae67516Stomee consumer.compile(PROGRAM); 1574ae67516Stomee consumer.enable(); 1584ae67516Stomee consumer.go(new ExceptionHandler() { 1594ae67516Stomee public void handleException(Throwable e) { 1604ae67516Stomee e.printStackTrace(); 1614ae67516Stomee } 1624ae67516Stomee }); 1634ae67516Stomee } catch (DTraceException e) { 1644ae67516Stomee e.printStackTrace(); 1654ae67516Stomee } 1664ae67516Stomee } 1674ae67516Stomee } 168