2N/A/*
2N/A * CDDL HEADER START
2N/A *
2N/A * The contents of this file are subject to the terms of the
2N/A * Common Development and Distribution License (the "License").
2N/A * You may not use this file except in compliance with the License.
2N/A *
2N/A * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
2N/A * or http://www.opensolaris.org/os/licensing.
2N/A * See the License for the specific language governing permissions
2N/A * and limitations under the License.
2N/A *
2N/A * When distributing Covered Code, include this CDDL HEADER in each
2N/A * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
2N/A * If applicable, add the following below this CDDL HEADER, with the
2N/A * fields enclosed by brackets "[]" replaced with your own identifying
2N/A * information: Portions Copyright [yyyy] [name of copyright owner]
2N/A *
2N/A * CDDL HEADER END
2N/A */
2N/A
2N/A/*
2N/A * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
2N/A * Use is subject to license terms.
2N/A *
2N/A * ident "%Z%%M% %I% %E% SMI"
2N/A */
2N/Apackage org.opensolaris.os.dtrace;
2N/A
2N/Aimport java.io.Serializable;
2N/Aimport java.io.*;
2N/Aimport java.beans.*;
2N/A
2N/A/**
2N/A * Detail about one or more records dropped by DTrace (not reported to
2N/A * {@link ConsumerListener#dataReceived(DataEvent e)
2N/A * ConsumerListener.dataReceived()}) due to inadequte buffer space.
2N/A * <p>
2N/A * Immutable. Supports persistence using {@link java.beans.XMLEncoder}.
2N/A *
2N/A * @see ConsumerListener#dataDropped(DropEvent e)
2N/A *
2N/A * @author Tom Erickson
2N/A */
2N/Apublic final class Drop implements Serializable {
2N/A static final long serialVersionUID = 26653827678657381L;
2N/A
2N/A static {
2N/A try {
2N/A BeanInfo info = Introspector.getBeanInfo(Drop.class);
2N/A PersistenceDelegate persistenceDelegate =
2N/A new DefaultPersistenceDelegate(
2N/A new String[] {"CPU", "kind", "count", "total",
2N/A "defaultMessage"})
2N/A {
2N/A protected Expression
2N/A instantiate(Object oldInstance, Encoder out)
2N/A {
2N/A Drop drop = (Drop)oldInstance;
2N/A return new Expression(oldInstance, oldInstance.getClass(),
2N/A "new", new Object[] { drop.getCPU(),
2N/A drop.getKind().name(), drop.getCount(),
2N/A drop.getTotal(), drop.getDefaultMessage() });
2N/A }
2N/A };
2N/A BeanDescriptor d = info.getBeanDescriptor();
2N/A d.setValue("persistenceDelegate", persistenceDelegate);
2N/A } catch (IntrospectionException e) {
2N/A e.printStackTrace();
2N/A }
2N/A }
2N/A
2N/A /**
2N/A * Indicates what kind of buffer space experienced the data drop
2N/A * (such as principal buffer or aggregation buffer) and possibly a
2N/A * reason.
2N/A */
2N/A public enum Kind {
2N/A /** Drop to principal buffer */
2N/A PRINCIPAL("Principal buffer"),
2N/A /** Drop to aggregation buffer */
2N/A AGGREGATION("Aggregation"),
2N/A /** Dynamic drop */
2N/A DYNAMIC("Dynamic"),
2N/A /** Dynamic drop due to rinsing */
2N/A DYNRINSE("Dynamic (rinse)"),
2N/A /** Dynamic drop due to dirtiness */
2N/A DYNDIRTY("Dynamic (dirty)"),
2N/A /** Speculative drop */
2N/A SPEC("Speculation"),
2N/A /** Speculative drop due to business */
2N/A SPECBUSY("Speculation (busy)"),
2N/A /** Speculative drop due to unavailability */
2N/A SPECUNAVAIL("Speculation (unavailable)"),
2N/A /** Stack string table overflow */
2N/A STKSTROVERFLOW("Stack string table overflow"),
2N/A /** Error in ERROR probe */
2N/A DBLERROR("error in ERROR probe"),
2N/A /** Unrecognized value from native DTrace library */
2N/A UNKNOWN("Unknown");
2N/A
2N/A private String s;
2N/A
2N/A private
2N/A Kind(String displayString)
2N/A {
2N/A s = displayString;
2N/A }
2N/A
2N/A /**
2N/A * Overridden to get the default display value. To
2N/A * internationalize the display value, use {@link Enum#name()}
2N/A * instead as an I18N lookup key.
2N/A */
2N/A public String
2N/A toString()
2N/A {
2N/A return s;
2N/A }
2N/A }
2N/A
2N/A /** @serial */
2N/A private final int cpu;
2N/A /** @serial */
2N/A private final Kind kind;
2N/A /** @serial */
2N/A private final long count;
2N/A /** @serial */
2N/A private final long total;
2N/A /** @serial */
2N/A private final String defaultMessage;
2N/A
2N/A /**
2N/A * Creates a {@code Drop} instance with the given CPU, drop kind,
2N/A * drop counts, and default message. Supports XML persistence.
2N/A *
2N/A * @param dropCPU cpu where drops occurred
2N/A * @param dropKindName name of enumeration value indicating the kind
2N/A * of buffer space where the drop occurred and possibly a reason
2N/A * @param dropCount number of drops
2N/A * @param totalDrops total number of drops since the source {@link
2N/A * Consumer} started running
2N/A * @param defaultDropMessage drop message provided by DTrace
2N/A * @throws IllegalArgumentException if there is no {@code Drop.Kind}
2N/A * value with the given name or if {@code dropCount} or {@code
2N/A * totalDrops} is negative
2N/A * @throws NullPointerException if the given {@code Drop.Kind} name
2N/A * or default message is {@code null}
2N/A */
2N/A public
2N/A Drop(int dropCPU, String dropKindName, long dropCount, long totalDrops,
2N/A String defaultDropMessage)
2N/A {
2N/A cpu = dropCPU;
2N/A kind = Enum.valueOf(Kind.class, dropKindName);
2N/A count = dropCount;
2N/A total = totalDrops;
2N/A defaultMessage = defaultDropMessage;
2N/A validate();
2N/A }
2N/A
2N/A private final void
2N/A validate()
2N/A {
2N/A if (count < 0) {
2N/A throw new IllegalArgumentException("count is negative");
2N/A }
2N/A if (total < 0) {
2N/A throw new IllegalArgumentException("total is negative");
2N/A }
2N/A if (defaultMessage == null) {
2N/A throw new NullPointerException("default message is null");
2N/A }
2N/A }
2N/A
2N/A /**
2N/A * Gets the CPU where the drops occurred.
2N/A *
2N/A * @return non-negative CPU ID, or a negative number if the CPU is
2N/A * unknown
2N/A */
2N/A public int
2N/A getCPU()
2N/A {
2N/A return cpu;
2N/A }
2N/A
2N/A /**
2N/A * Gets the kind of drop for all drops included in {@link
2N/A * #getCount()}.
2N/A *
2N/A * @return non-null drop kind
2N/A */
2N/A public Kind
2N/A getKind()
2N/A {
2N/A return kind;
2N/A }
2N/A
2N/A /**
2N/A * Gets the number of drops reported by this {@code Drop} instance.
2N/A *
2N/A * @return non-negative drop count
2N/A */
2N/A public long
2N/A getCount()
2N/A {
2N/A return count;
2N/A }
2N/A
2N/A /**
2N/A * Gets the total number of drops since the source {@link Consumer}
2N/A * started running.
2N/A *
2N/A * @return non-negative drop total since tracing started
2N/A */
2N/A public long
2N/A getTotal()
2N/A {
2N/A return total;
2N/A }
2N/A
2N/A /**
2N/A * Gets the message provided by DTrace.
2N/A *
2N/A * @return non-null message provided by DTrace
2N/A */
2N/A public String
2N/A getDefaultMessage()
2N/A {
2N/A return defaultMessage;
2N/A }
2N/A
2N/A private void
2N/A readObject(ObjectInputStream s)
2N/A throws IOException, ClassNotFoundException
2N/A {
2N/A s.defaultReadObject();
2N/A // check class invariants
2N/A try {
2N/A validate();
2N/A } catch (Exception e) {
2N/A InvalidObjectException x = new InvalidObjectException(
2N/A e.getMessage());
2N/A x.initCause(e);
2N/A throw x;
2N/A }
2N/A }
2N/A
2N/A /**
2N/A * Gets a string representation of this drop instance, not intended
2N/A * for display. The exact details of the representation are
2N/A * unspecified and subject to change, but the following format may
2N/A * be regarded as typical:
2N/A * <pre><code>
2N/A * class-name[property1 = value1, property2 = value2]
2N/A * </code></pre>
2N/A */
2N/A public String
2N/A toString()
2N/A {
2N/A StringBuilder buf = new StringBuilder();
2N/A buf.append(Drop.class.getName());
2N/A buf.append("[cpu = ");
2N/A buf.append(cpu);
2N/A buf.append(", kind = ");
2N/A buf.append(kind);
2N/A buf.append(", count = ");
2N/A buf.append(count);
2N/A buf.append(", total = ");
2N/A buf.append(total);
2N/A buf.append(", defaultMessage = ");
2N/A buf.append(defaultMessage);
2N/A buf.append(']');
2N/A return buf.toString();
2N/A }
2N/A}