1fb3fb4f3Stomee /*
2fb3fb4f3Stomee  * CDDL HEADER START
3fb3fb4f3Stomee  *
4fb3fb4f3Stomee  * The contents of this file are subject to the terms of the
5fb3fb4f3Stomee  * Common Development and Distribution License (the "License").
6fb3fb4f3Stomee  * You may not use this file except in compliance with the License.
7fb3fb4f3Stomee  *
8fb3fb4f3Stomee  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9fb3fb4f3Stomee  * or http://www.opensolaris.org/os/licensing.
10fb3fb4f3Stomee  * See the License for the specific language governing permissions
11fb3fb4f3Stomee  * and limitations under the License.
12fb3fb4f3Stomee  *
13fb3fb4f3Stomee  * When distributing Covered Code, include this CDDL HEADER in each
14fb3fb4f3Stomee  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15fb3fb4f3Stomee  * If applicable, add the following below this CDDL HEADER, with the
16fb3fb4f3Stomee  * fields enclosed by brackets "[]" replaced with your own identifying
17fb3fb4f3Stomee  * information: Portions Copyright [yyyy] [name of copyright owner]
18fb3fb4f3Stomee  *
19fb3fb4f3Stomee  * CDDL HEADER END
20fb3fb4f3Stomee  */
21fb3fb4f3Stomee 
22fb3fb4f3Stomee /*
2391cfa10aStomee  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
24fb3fb4f3Stomee  * Use is subject to license terms.
25fb3fb4f3Stomee  *
26fb3fb4f3Stomee  * ident	"%Z%%M%	%I%	%E% SMI"
27fb3fb4f3Stomee  */
28fb3fb4f3Stomee package org.opensolaris.os.dtrace;
29fb3fb4f3Stomee 
30fb3fb4f3Stomee import java.io.Serializable;
31fb3fb4f3Stomee import java.io.*;
32fb3fb4f3Stomee import java.beans.*;
33fb3fb4f3Stomee 
34fb3fb4f3Stomee /**
35fb3fb4f3Stomee  * Detail about one or more records dropped by DTrace (not reported to
36fb3fb4f3Stomee  * {@link ConsumerListener#dataReceived(DataEvent e)
37fb3fb4f3Stomee  * ConsumerListener.dataReceived()}) due to inadequte buffer space.
38fb3fb4f3Stomee  * <p>
39fb3fb4f3Stomee  * Immutable.  Supports persistence using {@link java.beans.XMLEncoder}.
40fb3fb4f3Stomee  *
41fb3fb4f3Stomee  * @see ConsumerListener#dataDropped(DropEvent e)
42fb3fb4f3Stomee  *
43fb3fb4f3Stomee  * @author Tom Erickson
44fb3fb4f3Stomee  */
45fb3fb4f3Stomee public final class Drop implements Serializable {
46fb3fb4f3Stomee     static final long serialVersionUID = 26653827678657381L;
47fb3fb4f3Stomee 
48fb3fb4f3Stomee     static {
49fb3fb4f3Stomee 	try {
50fb3fb4f3Stomee 	    BeanInfo info = Introspector.getBeanInfo(Drop.class);
51fb3fb4f3Stomee 	    PersistenceDelegate persistenceDelegate =
52fb3fb4f3Stomee 		    new DefaultPersistenceDelegate(
53fb3fb4f3Stomee 		    new String[] {"CPU", "kind", "count", "total",
54fb3fb4f3Stomee 		    "defaultMessage"})
55fb3fb4f3Stomee 	    {
56fb3fb4f3Stomee 		protected Expression
57fb3fb4f3Stomee 		instantiate(Object oldInstance, Encoder out)
58fb3fb4f3Stomee 		{
59fb3fb4f3Stomee 		    Drop drop = (Drop)oldInstance;
60fb3fb4f3Stomee 		    return new Expression(oldInstance, oldInstance.getClass(),
61fb3fb4f3Stomee 			    "new", new Object[] { drop.getCPU(),
62fb3fb4f3Stomee 			    drop.getKind().name(), drop.getCount(),
63fb3fb4f3Stomee 			    drop.getTotal(), drop.getDefaultMessage() });
64fb3fb4f3Stomee 		}
65fb3fb4f3Stomee 	    };
66fb3fb4f3Stomee 	    BeanDescriptor d = info.getBeanDescriptor();
67fb3fb4f3Stomee 	    d.setValue("persistenceDelegate", persistenceDelegate);
68fb3fb4f3Stomee 	} catch (IntrospectionException e) {
69fb3fb4f3Stomee 	    e.printStackTrace();
70fb3fb4f3Stomee 	}
71fb3fb4f3Stomee     }
72fb3fb4f3Stomee 
73fb3fb4f3Stomee     /**
74fb3fb4f3Stomee      * Indicates what kind of buffer space experienced the data drop
75fb3fb4f3Stomee      * (such as principal buffer or aggregation buffer) and possibly a
76fb3fb4f3Stomee      * reason.
77fb3fb4f3Stomee      */
78fb3fb4f3Stomee     public enum Kind {
79fb3fb4f3Stomee 	/** Drop to principal buffer */
80fb3fb4f3Stomee 	PRINCIPAL("Principal buffer"),
81fb3fb4f3Stomee 	/** Drop to aggregation buffer */
82fb3fb4f3Stomee 	AGGREGATION("Aggregation"),
83fb3fb4f3Stomee 	/** Dynamic drop */
84fb3fb4f3Stomee 	DYNAMIC("Dynamic"),
85fb3fb4f3Stomee 	/** Dynamic drop due to rinsing */
86fb3fb4f3Stomee 	DYNRINSE("Dynamic (rinse)"),
87fb3fb4f3Stomee 	/** Dynamic drop due to dirtiness */
88fb3fb4f3Stomee 	DYNDIRTY("Dynamic (dirty)"),
89fb3fb4f3Stomee 	/** Speculative drop */
90fb3fb4f3Stomee 	SPEC("Speculation"),
91fb3fb4f3Stomee 	/** Speculative drop due to business */
92fb3fb4f3Stomee 	SPECBUSY("Speculation (busy)"),
93fb3fb4f3Stomee 	/** Speculative drop due to unavailability */
94fb3fb4f3Stomee 	SPECUNAVAIL("Speculation (unavailable)"),
95fb3fb4f3Stomee 	/** Stack string table overflow */
96fb3fb4f3Stomee 	STKSTROVERFLOW("Stack string table overflow"),
97fb3fb4f3Stomee 	/** Error in ERROR probe */
98fb3fb4f3Stomee 	DBLERROR("error in ERROR probe"),
99fb3fb4f3Stomee 	/** Unrecognized value from native DTrace library */
100fb3fb4f3Stomee 	UNKNOWN("Unknown");
101fb3fb4f3Stomee 
102fb3fb4f3Stomee 	private String s;
103fb3fb4f3Stomee 
104fb3fb4f3Stomee 	private
Kind(String displayString)105fb3fb4f3Stomee 	Kind(String displayString)
106fb3fb4f3Stomee 	{
107fb3fb4f3Stomee 	    s = displayString;
108fb3fb4f3Stomee 	}
109fb3fb4f3Stomee 
110fb3fb4f3Stomee 	/**
111fb3fb4f3Stomee 	 * Overridden to get the default display value.  To
112fb3fb4f3Stomee 	 * internationalize the display value, use {@link Enum#name()}
113fb3fb4f3Stomee 	 * instead as an I18N lookup key.
114fb3fb4f3Stomee 	 */
115fb3fb4f3Stomee 	public String
toString()116fb3fb4f3Stomee 	toString()
117fb3fb4f3Stomee 	{
118fb3fb4f3Stomee 	    return s;
119fb3fb4f3Stomee 	}
120fb3fb4f3Stomee     }
121fb3fb4f3Stomee 
122fb3fb4f3Stomee     /** @serial */
123fb3fb4f3Stomee     private final int cpu;
124fb3fb4f3Stomee     /** @serial */
125fb3fb4f3Stomee     private final Kind kind;
126fb3fb4f3Stomee     /** @serial */
127fb3fb4f3Stomee     private final long count;
128fb3fb4f3Stomee     /** @serial */
129fb3fb4f3Stomee     private final long total;
130fb3fb4f3Stomee     /** @serial */
131fb3fb4f3Stomee     private final String defaultMessage;
132fb3fb4f3Stomee 
133fb3fb4f3Stomee     /**
134fb3fb4f3Stomee      * Creates a {@code Drop} instance with the given CPU, drop kind,
135fb3fb4f3Stomee      * drop counts, and default message.  Supports XML persistence.
136fb3fb4f3Stomee      *
137fb3fb4f3Stomee      * @param dropCPU cpu where drops occurred
138fb3fb4f3Stomee      * @param dropKindName name of enumeration value indicating the kind
139fb3fb4f3Stomee      * of buffer space where the drop occurred and possibly a reason
140fb3fb4f3Stomee      * @param dropCount number of drops
141fb3fb4f3Stomee      * @param totalDrops total number of drops since the source {@link
142fb3fb4f3Stomee      * Consumer} started running
143fb3fb4f3Stomee      * @param defaultDropMessage drop message provided by DTrace
144fb3fb4f3Stomee      * @throws IllegalArgumentException if there is no {@code Drop.Kind}
145fb3fb4f3Stomee      * value with the given name or if {@code dropCount} or {@code
146fb3fb4f3Stomee      * totalDrops} is negative
147fb3fb4f3Stomee      * @throws NullPointerException if the given {@code Drop.Kind} name
148fb3fb4f3Stomee      * or default message is {@code null}
149fb3fb4f3Stomee      */
150fb3fb4f3Stomee     public
Drop(int dropCPU, String dropKindName, long dropCount, long totalDrops, String defaultDropMessage)151fb3fb4f3Stomee     Drop(int dropCPU, String dropKindName, long dropCount, long totalDrops,
152fb3fb4f3Stomee 	    String defaultDropMessage)
153fb3fb4f3Stomee     {
154fb3fb4f3Stomee 	cpu = dropCPU;
155fb3fb4f3Stomee 	kind = Enum.valueOf(Kind.class, dropKindName);
156fb3fb4f3Stomee 	count = dropCount;
157fb3fb4f3Stomee 	total = totalDrops;
158fb3fb4f3Stomee 	defaultMessage = defaultDropMessage;
159fb3fb4f3Stomee 	validate();
160fb3fb4f3Stomee     }
161fb3fb4f3Stomee 
16291cfa10aStomee     private final void
validate()163fb3fb4f3Stomee     validate()
164fb3fb4f3Stomee     {
165fb3fb4f3Stomee 	if (count < 0) {
166fb3fb4f3Stomee 	    throw new IllegalArgumentException("count is negative");
167fb3fb4f3Stomee 	}
168fb3fb4f3Stomee 	if (total < 0) {
169fb3fb4f3Stomee 	    throw new IllegalArgumentException("total is negative");
170fb3fb4f3Stomee 	}
171fb3fb4f3Stomee 	if (defaultMessage == null) {
172fb3fb4f3Stomee 	    throw new NullPointerException("default message is null");
173fb3fb4f3Stomee 	}
174fb3fb4f3Stomee     }
175fb3fb4f3Stomee 
176fb3fb4f3Stomee     /**
177fb3fb4f3Stomee      * Gets the CPU where the drops occurred.
178fb3fb4f3Stomee      *
179fb3fb4f3Stomee      * @return non-negative CPU ID, or a negative number if the CPU is
180fb3fb4f3Stomee      * unknown
181fb3fb4f3Stomee      */
182fb3fb4f3Stomee     public int
getCPU()183fb3fb4f3Stomee     getCPU()
184fb3fb4f3Stomee     {
185fb3fb4f3Stomee 	return cpu;
186fb3fb4f3Stomee     }
187fb3fb4f3Stomee 
188fb3fb4f3Stomee     /**
189fb3fb4f3Stomee      * Gets the kind of drop for all drops included in {@link
190fb3fb4f3Stomee      * #getCount()}.
191fb3fb4f3Stomee      *
192fb3fb4f3Stomee      * @return non-null drop kind
193fb3fb4f3Stomee      */
194fb3fb4f3Stomee     public Kind
getKind()195fb3fb4f3Stomee     getKind()
196fb3fb4f3Stomee     {
197fb3fb4f3Stomee 	return kind;
198fb3fb4f3Stomee     }
199fb3fb4f3Stomee 
200fb3fb4f3Stomee     /**
201fb3fb4f3Stomee      * Gets the number of drops reported by this {@code Drop} instance.
202fb3fb4f3Stomee      *
203fb3fb4f3Stomee      * @return non-negative drop count
204fb3fb4f3Stomee      */
205fb3fb4f3Stomee     public long
getCount()206fb3fb4f3Stomee     getCount()
207fb3fb4f3Stomee     {
208fb3fb4f3Stomee 	return count;
209fb3fb4f3Stomee     }
210fb3fb4f3Stomee 
211fb3fb4f3Stomee     /**
212fb3fb4f3Stomee      * Gets the total number of drops since the source {@link Consumer}
213fb3fb4f3Stomee      * started running.
214fb3fb4f3Stomee      *
215fb3fb4f3Stomee      * @return non-negative drop total since tracing started
216fb3fb4f3Stomee      */
217fb3fb4f3Stomee     public long
getTotal()218fb3fb4f3Stomee     getTotal()
219fb3fb4f3Stomee     {
220fb3fb4f3Stomee 	return total;
221fb3fb4f3Stomee     }
222fb3fb4f3Stomee 
223fb3fb4f3Stomee     /**
224fb3fb4f3Stomee      * Gets the message provided by DTrace.
225fb3fb4f3Stomee      *
226fb3fb4f3Stomee      * @return non-null message provided by DTrace
227fb3fb4f3Stomee      */
228fb3fb4f3Stomee     public String
getDefaultMessage()229fb3fb4f3Stomee     getDefaultMessage()
230fb3fb4f3Stomee     {
231fb3fb4f3Stomee 	return defaultMessage;
232fb3fb4f3Stomee     }
233fb3fb4f3Stomee 
234fb3fb4f3Stomee     private void
readObject(ObjectInputStream s)235fb3fb4f3Stomee     readObject(ObjectInputStream s)
236fb3fb4f3Stomee 	    throws IOException, ClassNotFoundException
237fb3fb4f3Stomee     {
238fb3fb4f3Stomee 	s.defaultReadObject();
239fb3fb4f3Stomee 	// check class invariants
240fb3fb4f3Stomee 	try {
241fb3fb4f3Stomee 	    validate();
242fb3fb4f3Stomee 	} catch (Exception e) {
243*4ae67516Stomee 	    InvalidObjectException x = new InvalidObjectException(
244*4ae67516Stomee 		    e.getMessage());
245*4ae67516Stomee 	    x.initCause(e);
246*4ae67516Stomee 	    throw x;
247fb3fb4f3Stomee 	}
248fb3fb4f3Stomee     }
249fb3fb4f3Stomee 
250fb3fb4f3Stomee     /**
251fb3fb4f3Stomee      * Gets a string representation of this drop instance, not intended
252fb3fb4f3Stomee      * for display.  The exact details of the representation are
253fb3fb4f3Stomee      * unspecified and subject to change, but the following format may
254fb3fb4f3Stomee      * be regarded as typical:
255fb3fb4f3Stomee      * <pre><code>
256fb3fb4f3Stomee      * class-name[property1 = value1, property2 = value2]
257fb3fb4f3Stomee      * </code></pre>
258fb3fb4f3Stomee      */
259fb3fb4f3Stomee     public String
toString()260fb3fb4f3Stomee     toString()
261fb3fb4f3Stomee     {
262*4ae67516Stomee 	StringBuilder buf = new StringBuilder();
263fb3fb4f3Stomee 	buf.append(Drop.class.getName());
264fb3fb4f3Stomee 	buf.append("[cpu = ");
265fb3fb4f3Stomee 	buf.append(cpu);
266fb3fb4f3Stomee 	buf.append(", kind = ");
267fb3fb4f3Stomee 	buf.append(kind);
268fb3fb4f3Stomee 	buf.append(", count = ");
269fb3fb4f3Stomee 	buf.append(count);
270fb3fb4f3Stomee 	buf.append(", total = ");
271fb3fb4f3Stomee 	buf.append(total);
272fb3fb4f3Stomee 	buf.append(", defaultMessage = ");
273fb3fb4f3Stomee 	buf.append(defaultMessage);
274fb3fb4f3Stomee 	buf.append(']');
275fb3fb4f3Stomee 	return buf.toString();
276fb3fb4f3Stomee     }
277fb3fb4f3Stomee }
278