1*1449Stomee /*
2*1449Stomee  * CDDL HEADER START
3*1449Stomee  *
4*1449Stomee  * The contents of this file are subject to the terms of the
5*1449Stomee  * Common Development and Distribution License (the "License").
6*1449Stomee  * You may not use this file except in compliance with the License.
7*1449Stomee  *
8*1449Stomee  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*1449Stomee  * or http://www.opensolaris.org/os/licensing.
10*1449Stomee  * See the License for the specific language governing permissions
11*1449Stomee  * and limitations under the License.
12*1449Stomee  *
13*1449Stomee  * When distributing Covered Code, include this CDDL HEADER in each
14*1449Stomee  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*1449Stomee  * If applicable, add the following below this CDDL HEADER, with the
16*1449Stomee  * fields enclosed by brackets "[]" replaced with your own identifying
17*1449Stomee  * information: Portions Copyright [yyyy] [name of copyright owner]
18*1449Stomee  *
19*1449Stomee  * CDDL HEADER END
20*1449Stomee  */
21*1449Stomee 
22*1449Stomee /*
23*1449Stomee  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
24*1449Stomee  * Use is subject to license terms.
25*1449Stomee  */
26*1449Stomee 
27*1449Stomee #ifndef	_DTRACE_JNI_H
28*1449Stomee #define	_DTRACE_JNI_H
29*1449Stomee 
30*1449Stomee #pragma ident	"%Z%%M%	%I%	%E% SMI"
31*1449Stomee 
32*1449Stomee #include <libuutil.h>
33*1449Stomee #include <jni.h>
34*1449Stomee #include <dtrace.h>
35*1449Stomee #include <dtj_util.h>
36*1449Stomee 
37*1449Stomee #ifdef	__cplusplus
38*1449Stomee extern "C" {
39*1449Stomee #endif
40*1449Stomee 
41*1449Stomee /* Java DTrace API native library */
42*1449Stomee 
43*1449Stomee 
44*1449Stomee /*
45*1449Stomee  * Thread-specific data key used to obtain JNI state specific to either the
46*1449Stomee  * consumer loop (calls dtrace_work()) or the getAggregate() method (calls
47*1449Stomee  * dtrace_aggregate_print()).
48*1449Stomee  */
49*1449Stomee extern pthread_key_t g_dtj_consumer_key;
50*1449Stomee 
51*1449Stomee typedef enum dtj_consumer_state {
52*1449Stomee 	DTJ_CONSUMER_INIT,
53*1449Stomee 	DTJ_CONSUMER_GO,
54*1449Stomee 	DTJ_CONSUMER_START,
55*1449Stomee 	DTJ_CONSUMER_STOP
56*1449Stomee } dtj_consumer_state_t;
57*1449Stomee 
58*1449Stomee typedef struct dtj_error {
59*1449Stomee 	int dtje_number;		/* dtrace_errno() */
60*1449Stomee 	const char *dtje_message;	/* dtrace_errmsg() */
61*1449Stomee } dtj_error_t;
62*1449Stomee 
63*1449Stomee /*
64*1449Stomee  * Identifies which function should handle a request dequeued after
65*1449Stomee  * dtrace_sleep().
66*1449Stomee  */
67*1449Stomee typedef enum dtj_request_type {
68*1449Stomee 	DTJ_REQUEST_OPTION		/* set DTrace runtime option */
69*1449Stomee } dtj_request_type_t;
70*1449Stomee 
71*1449Stomee /*
72*1449Stomee  * A request made from Java (by native method call) that is unsafe to process
73*1449Stomee  * until just after the consumer loop wakes up from dtrace_sleep().
74*1449Stomee  */
75*1449Stomee typedef struct dtj_request {
76*1449Stomee 	dtj_request_type_t dtjr_type;	/* request handler ID */
77*1449Stomee 	uu_list_t *dtjr_args;		/* string args to request handler */
78*1449Stomee 	uu_list_node_t dtjr_node;	/* points to next and prev requests */
79*1449Stomee } dtj_request_t;
80*1449Stomee 
81*1449Stomee typedef enum dtj_program_type {
82*1449Stomee 	DTJ_PROGRAM_NONE,
83*1449Stomee 	DTJ_PROGRAM_STRING,		/* dtrace_program_strcompile() */
84*1449Stomee 	DTJ_PROGRAM_FILE		/* dtrace_program_fcompile() */
85*1449Stomee } dtj_program_type_t;
86*1449Stomee 
87*1449Stomee /* Identifier and description of a compiled DTrace program */
88*1449Stomee typedef struct dtj_program {
89*1449Stomee 	dtj_program_type_t dtjp_type;	/* string or file */
90*1449Stomee 	const char *dtjp_name;		/* string or filename for err msg */
91*1449Stomee 	dtrace_prog_t *dtjp_program;	/* libdtrace program handle */
92*1449Stomee 	dtrace_proginfo_t dtjp_info;	/* program attributes */
93*1449Stomee 	boolean_t dtjp_enabled;		/* dtrace_program_exec() flag */
94*1449Stomee 	uu_list_node_t dtjp_node;	/* points to next and prev programs */
95*1449Stomee } dtj_program_t;
96*1449Stomee 
97*1449Stomee /*
98*1449Stomee  * An entry used to maintain the association between the value of an aggregating
99*1449Stomee  * action (such as count()) and the aggregation to which the value belongs until
100*1449Stomee  * all the data associated with a single tuple is available to the callback
101*1449Stomee  * handler.
102*1449Stomee  */
103*1449Stomee typedef struct dtj_aggval {
104*1449Stomee 	jobject dtja_value;		/* value of aggregating action */
105*1449Stomee 	const char *dtja_aggname;	/* aggregation name */
106*1449Stomee 	int64_t dtja_aggid;		/* libdtrace aggregation ID */
107*1449Stomee 	uu_list_node_t dtja_node;	/* points to next and prev aggvals */
108*1449Stomee } dtj_aggval_t;
109*1449Stomee 
110*1449Stomee /*
111*1449Stomee  * Per-consumer state, including the libdtrace consumer handle, is valid across
112*1449Stomee  * multiple threads.  One consumer entry is added to a global table per
113*1449Stomee  * dtrace_open().
114*1449Stomee  */
115*1449Stomee typedef struct dtj_consumer {
116*1449Stomee 	/* Consumer state */
117*1449Stomee 
118*1449Stomee 	dtrace_hdl_t *dtjc_dtp;		/* libdtrace consumer handle */
119*1449Stomee 	uu_list_t *dtjc_program_list;	/* program_t list */
120*1449Stomee 	uu_list_t *dtjc_process_list;	/* proc handle list */
121*1449Stomee 
122*1449Stomee 	/*
123*1449Stomee 	 * Count of processes that have ended.  The consumer is stopped when
124*1449Stomee 	 * this count equals the number of outstanding target processes and
125*1449Stomee 	 * grabbed processes (see the Java Consumer createProcess() and
126*1449Stomee 	 * grabProcess() methods).
127*1449Stomee 	 */
128*1449Stomee 	int dtjc_procs_ended;
129*1449Stomee 
130*1449Stomee 	/*
131*1449Stomee 	 * Bit-field passed to dtrace_program_strcompile() and
132*1449Stomee 	 * dtrace_program_fcompile() containing compile flags.  The flags are
133*1449Stomee 	 * set from Java by the setOption() Consumer method (just like the
134*1449Stomee 	 * runtime options handled by dtrace_setopt(), except that they must be
135*1449Stomee 	 * set before program compilation to have any effect).
136*1449Stomee 	 */
137*1449Stomee 	uint_t dtjc_cflags;
138*1449Stomee 
139*1449Stomee 	boolean_t dtjc_flow;	/* current value of the flowindent option */
140*1449Stomee 	dtj_consumer_state_t dtjc_state; /* execution state */
141*1449Stomee 	boolean_t dtjc_interrupt;	/* flag that stops consumer */
142*1449Stomee 
143*1449Stomee 	/* Pending requests */
144*1449Stomee 	uu_list_t *dtjc_request_list;	/* request_t queue */
145*1449Stomee 	pthread_mutex_t dtjc_request_list_lock;
146*1449Stomee 
147*1449Stomee 
148*1449Stomee 	/* Cached for optimization and for use across functions */
149*1449Stomee 
150*1449Stomee 	/*
151*1449Stomee 	 * Nanosecond timestamp cached in the consumer loop just before
152*1449Stomee 	 * dtrace_work().  The timestamp is applied to each Java PrintaRecord
153*1449Stomee 	 * generated in that iteration of the consumer loop.  A value of zero
154*1449Stomee 	 * indicates that we are not in the consumer loop, but that the
155*1449Stomee 	 * callback was triggered instead by the Consumer getAggregate() method
156*1449Stomee 	 * (from dtrace_aggregate_print()).
157*1449Stomee 	 */
158*1449Stomee 	hrtime_t dtjc_printa_snaptime;
159*1449Stomee 
160*1449Stomee 	/*
161*1449Stomee 	 * The aggregation ID is used to optimize aggregation inclusion by
162*1449Stomee 	 * testing for inclusion only when the aggregation has changed.
163*1449Stomee 	 */
164*1449Stomee 	int64_t dtjc_aggid;
165*1449Stomee 	boolean_t dtjc_included;
166*1449Stomee 
167*1449Stomee 	/*
168*1449Stomee 	 * The expected tuple member count is used to determine whether or not
169*1449Stomee 	 * the aggregation tuple values are completely specified in the printa()
170*1449Stomee 	 * format string.
171*1449Stomee 	 */
172*1449Stomee 	int dtjc_expected;
173*1449Stomee 
174*1449Stomee 	int dtjc_probedata_rec_i;	/* probe data record index */
175*1449Stomee 
176*1449Stomee 	/*
177*1449Stomee 	 * The current DTrace action may apply across multiple libdtrace probe
178*1449Stomee 	 * data records.
179*1449Stomee 	 */
180*1449Stomee 	dtrace_actkind_t dtjc_probedata_act;
181*1449Stomee 
182*1449Stomee 	/* Placeholder used when listing probes */
183*1449Stomee 	dtrace_ecbdesc_t *dtjc_last_probe;
184*1449Stomee 
185*1449Stomee 	/* Function used by statement iterator when listing probes */
186*1449Stomee 	dtrace_probe_f *dtjc_plistfunc;
187*1449Stomee } dtj_consumer_t;
188*1449Stomee 
189*1449Stomee /*
190*1449Stomee  * A view of a dtj_consumer_t that lasts only as long as a single native method
191*1449Stomee  * call.  This view attaches state needed for interaction with Java and specific
192*1449Stomee  * to the JNI.
193*1449Stomee  */
194*1449Stomee typedef struct dtj_java_consumer {
195*1449Stomee 	/* Per-consumer state in global consumer table */
196*1449Stomee 	dtj_consumer_t *dtjj_consumer;
197*1449Stomee 
198*1449Stomee 	JNIEnv *dtjj_jenv;	/* Java environment pointer */
199*1449Stomee 	jobject dtjj_caller;	/* Java Consumer to call back with probe data */
200*1449Stomee 
201*1449Stomee 	/*
202*1449Stomee 	 * Java Object references used across function boundaries, valid only
203*1449Stomee 	 * within the current native method call.
204*1449Stomee 	 */
205*1449Stomee 
206*1449Stomee 	jobject dtjj_probedata;	/* instance of class ProbeData */
207*1449Stomee 
208*1449Stomee 	/*
209*1449Stomee 	 * StringBuffer used to concatenate buffered printa() output associated
210*1449Stomee 	 * with the current tuple.
211*1449Stomee 	 */
212*1449Stomee 	jobject dtjj_printa_buffer;
213*1449Stomee 
214*1449Stomee 	jobject dtjj_aggregate;	/* instance of class Aggregate */
215*1449Stomee 	jobject dtjj_tuple;	/* instance of class Tuple */
216*1449Stomee 
217*1449Stomee 	/*
218*1449Stomee 	 * AggregationValue instances cached until we receive the
219*1449Stomee 	 * DTRACE_BUFDATA_AGGLAST flag indicating the last callback associated
220*1449Stomee 	 * with the current tuple.
221*1449Stomee 	 */
222*1449Stomee 	uu_list_t *dtjj_aggval_list;
223*1449Stomee 
224*1449Stomee 	/* AggregateSpec used by get_aggregate() */
225*1449Stomee 	jobject dtjj_aggregate_spec;
226*1449Stomee 
227*1449Stomee 	jobject dtjj_probelist;	/* java.util.List returned by listProbes() */
228*1449Stomee 
229*1449Stomee 	/*
230*1449Stomee 	 * Exception temporarily cleared by callback handlers who cannot return
231*1449Stomee 	 * a signal to abort the consumer.  At a safe point when the consumer
232*1449Stomee 	 * loop gets control back from libdtrace, the exception is rethrown.
233*1449Stomee 	 */
234*1449Stomee 	jthrowable dtjj_exception;
235*1449Stomee 
236*1449Stomee 	jobject dtjj_consumer_lock; /* per-consumer lock */
237*1449Stomee 
238*1449Stomee } dtj_java_consumer_t;
239*1449Stomee 
240*1449Stomee /*
241*1449Stomee  * Cache of jclass, jmethodID, and jfieldID values, usable across multiple
242*1449Stomee  * native method calls and multiple threads.  Caching all of them up front
243*1449Stomee  * rather than as-needed guarantees early detection of incorrect class, method,
244*1449Stomee  * or field definitions, and eliminates the need for test cases to cover
245*1449Stomee  * seldom-used definitions.
246*1449Stomee  *
247*1449Stomee  * Suffix conventions:
248*1449Stomee  *   jc  java class
249*1449Stomee  *   jm  java method
250*1449Stomee  *   jsm java static method
251*1449Stomee  *   jf  java field
252*1449Stomee  *   jsf java static field
253*1449Stomee  */
254*1449Stomee 
255*1449Stomee /* LocalConsumer */
256*1449Stomee extern jclass g_caller_jc;
257*1449Stomee extern jmethodID g_gethandle_jm;
258*1449Stomee extern jmethodID g_sethandle_jm;
259*1449Stomee extern jmethodID g_pdatanext_jm;
260*1449Stomee extern jmethodID g_drop_jm;
261*1449Stomee extern jmethodID g_error_jm;
262*1449Stomee extern jmethodID g_proc_jm;
263*1449Stomee extern jmethodID g_interval_began_jm;
264*1449Stomee extern jmethodID g_interval_ended_jm;
265*1449Stomee extern jfieldID g_consumer_lock_jf;
266*1449Stomee 
267*1449Stomee /* DTraceException */
268*1449Stomee extern jclass g_dtx_jc;
269*1449Stomee extern jmethodID g_dtxinit_jm;
270*1449Stomee 
271*1449Stomee /* InterfaceAttributes */
272*1449Stomee extern jclass g_attr_jc;
273*1449Stomee extern jmethodID g_attrinit_jm;
274*1449Stomee extern jmethodID g_attrset_name_jm;
275*1449Stomee extern jmethodID g_attrset_data_jm;
276*1449Stomee extern jmethodID g_attrset_class_jm;
277*1449Stomee 
278*1449Stomee /* ProbeDescription */
279*1449Stomee extern jclass g_probedesc_jc;
280*1449Stomee extern jmethodID g_probedescinit_jm;
281*1449Stomee extern jfieldID g_probedesc_id_jf;
282*1449Stomee 
283*1449Stomee /* ProbeInfo */
284*1449Stomee extern jclass g_probeinfo_jc;
285*1449Stomee extern jmethodID g_probeinfoinit_jm;
286*1449Stomee 
287*1449Stomee /* Probe */
288*1449Stomee extern jclass g_probe_jc;
289*1449Stomee extern jmethodID g_probeinit_jm;
290*1449Stomee 
291*1449Stomee /* Program */
292*1449Stomee extern jclass g_program_jc;
293*1449Stomee extern jmethodID g_proginit_jm;
294*1449Stomee extern jfieldID g_progid_jf;
295*1449Stomee extern jfieldID g_proginfo_jf;
296*1449Stomee 
297*1449Stomee /* Program.File */
298*1449Stomee extern jclass g_programfile_jc;
299*1449Stomee extern jmethodID g_fproginit_jm;
300*1449Stomee 
301*1449Stomee /* ProgramInfo */
302*1449Stomee extern jclass g_proginfo_jc;
303*1449Stomee extern jmethodID g_proginfoinit_jm;
304*1449Stomee 
305*1449Stomee /* Flow */
306*1449Stomee extern jclass g_flow_jc;
307*1449Stomee extern jmethodID g_flowinit_jm;
308*1449Stomee 
309*1449Stomee /* ProbeData */
310*1449Stomee extern jclass g_pdata_jc;
311*1449Stomee extern jmethodID g_pdatainit_jm;
312*1449Stomee extern jmethodID g_pdataadd_jm;
313*1449Stomee extern jmethodID g_pdataadd_rec_jm;
314*1449Stomee extern jmethodID g_pdataadd_trace_jm;
315*1449Stomee extern jmethodID g_pdataadd_stack_jm;
316*1449Stomee extern jmethodID g_pdataadd_printf_jm;
317*1449Stomee extern jmethodID g_pdataadd_printa_jm;
318*1449Stomee extern jmethodID g_pdatainvalidate_printa_jm;
319*1449Stomee extern jmethodID g_pdataadd_aggrec_jm;
320*1449Stomee extern jmethodID g_pdataadd_printa_str_jm;
321*1449Stomee extern jmethodID g_pdataadd_exit_jm;
322*1449Stomee extern jmethodID g_pdataattach_jm;
323*1449Stomee extern jmethodID g_pdataset_formatted_jm;
324*1449Stomee extern jmethodID g_pdataclear_jm;
325*1449Stomee 
326*1449Stomee /* Drop */
327*1449Stomee extern jclass g_drop_jc;
328*1449Stomee extern jmethodID g_dropinit_jm;
329*1449Stomee 
330*1449Stomee /* Error */
331*1449Stomee extern jclass g_error_jc;
332*1449Stomee extern jmethodID g_errinit_jm;
333*1449Stomee 
334*1449Stomee /* ProcessState */
335*1449Stomee extern jclass g_process_jc;
336*1449Stomee extern jmethodID g_procinit_jm;
337*1449Stomee extern jmethodID g_procexit_jm;
338*1449Stomee 
339*1449Stomee /* Aggregate */
340*1449Stomee extern jclass g_agg_jc;
341*1449Stomee extern jmethodID g_agginit_jm;
342*1449Stomee extern jmethodID g_aggaddrec_jm;
343*1449Stomee 
344*1449Stomee /* AggregateSpec */
345*1449Stomee extern jclass g_aggspec_jc;
346*1449Stomee extern jmethodID g_aggspec_included_jm;
347*1449Stomee extern jmethodID g_aggspec_cleared_jm;
348*1449Stomee 
349*1449Stomee /* Tuple */
350*1449Stomee extern jclass g_tuple_jc;
351*1449Stomee extern jmethodID g_tupleinit_jm;
352*1449Stomee extern jmethodID g_tupleadd_jm;
353*1449Stomee extern jmethodID g_tuplesize_jm;
354*1449Stomee extern jfieldID g_tuple_EMPTY_jsf;
355*1449Stomee 
356*1449Stomee /* AggregationRecord */
357*1449Stomee extern jclass g_aggrec_jc;
358*1449Stomee extern jmethodID g_aggrecinit_jm;
359*1449Stomee extern jmethodID g_aggrecget_tuple_jm;
360*1449Stomee 
361*1449Stomee /* SumValue */
362*1449Stomee extern jclass g_aggsum_jc;
363*1449Stomee extern jmethodID g_aggsuminit_jm;
364*1449Stomee 
365*1449Stomee /* CountValue */
366*1449Stomee extern jclass g_aggcount_jc;
367*1449Stomee extern jmethodID g_aggcountinit_jm;
368*1449Stomee 
369*1449Stomee /* AvgValue */
370*1449Stomee extern jclass g_aggavg_jc;
371*1449Stomee extern jmethodID g_aggavginit_jm;
372*1449Stomee 
373*1449Stomee /* MinValue */
374*1449Stomee extern jclass g_aggmin_jc;
375*1449Stomee extern jmethodID g_aggmininit_jm;
376*1449Stomee 
377*1449Stomee /* MaxValue */
378*1449Stomee extern jclass g_aggmax_jc;
379*1449Stomee extern jmethodID g_aggmaxinit_jm;
380*1449Stomee 
381*1449Stomee /* KernelStackRecord */
382*1449Stomee extern jclass g_stack_jc;
383*1449Stomee extern jmethodID g_parsestack_jsm;
384*1449Stomee extern jmethodID g_stackinit_jm;
385*1449Stomee extern jmethodID g_stackset_frames_jm;
386*1449Stomee 
387*1449Stomee /* UserStackRecord */
388*1449Stomee extern jclass g_ustack_jc;
389*1449Stomee extern jmethodID g_ustackinit_jm;
390*1449Stomee extern jmethodID g_ustackset_frames_jm;
391*1449Stomee 
392*1449Stomee /* Distribution */
393*1449Stomee extern jclass g_adist_jc;
394*1449Stomee extern jmethodID g_dist_normal_jm;
395*1449Stomee 
396*1449Stomee /* LogDistribution */
397*1449Stomee extern jclass g_dist_jc;
398*1449Stomee extern jmethodID g_distinit_jm;
399*1449Stomee 
400*1449Stomee /* LinearDistribution */
401*1449Stomee extern jclass g_ldist_jc;
402*1449Stomee extern jmethodID g_ldistinit_jm;
403*1449Stomee 
404*1449Stomee /*
405*1449Stomee  * Populates the java class references and associated method and field IDs
406*1449Stomee  * declared in this file (above).
407*1449Stomee  *
408*1449Stomee  * Throws NoClassDefFoundError, NoSuchMethodError, or NoSuchFieldError if any
409*1449Stomee  * dtj_table_entry_t in dtj_jnitab.c is incorrect.
410*1449Stomee  */
411*1449Stomee extern dtj_status_t dtj_load(JNIEnv *);
412*1449Stomee 
413*1449Stomee /*
414*1449Stomee  * Functions that create a structure return NULL if out of memory.  A Java
415*1449Stomee  * OutOfMemoryError is pending in that case.
416*1449Stomee  */
417*1449Stomee extern dtj_request_t *dtj_request_create(JNIEnv *, dtj_request_type_t, ...);
418*1449Stomee extern dtj_program_t *dtj_program_create(JNIEnv *, dtj_program_type_t,
419*1449Stomee     const char *);
420*1449Stomee extern dtj_aggval_t *dtj_aggval_create(JNIEnv *, jobject, const char *,
421*1449Stomee     int64_t);
422*1449Stomee 
423*1449Stomee /*
424*1449Stomee  * uu_list_t element destructors' signatures match uuwrap_value_destroy_f
425*1449Stomee  */
426*1449Stomee extern void dtj_request_destroy(void *, void *); /* expects NULL user arg */
427*1449Stomee extern void dtj_program_destroy(void *, void *); /* expects NULL user arg */
428*1449Stomee extern void dtj_aggval_destroy(void *, void *);	/* expects JNIEnv * user arg */
429*1449Stomee 
430*1449Stomee /* Allocates and frees per-consumer state kept in the global consumer table */
431*1449Stomee extern dtj_consumer_t *dtj_consumer_create(JNIEnv *);
432*1449Stomee extern void dtj_consumer_destroy(dtj_consumer_t *);
433*1449Stomee 
434*1449Stomee /* Sets callback handlers before calling dtrace_go() */
435*1449Stomee extern dtj_status_t dtj_set_callback_handlers(dtj_java_consumer_t *);
436*1449Stomee 
437*1449Stomee /*
438*1449Stomee  * Initializes Java Object references cached across multiple functions called
439*1449Stomee  * within the consumer loop.  Deletes the references after exiting the consumer
440*1449Stomee  * loop.  It is only necessary to initialize and finalize a dtj_java_consumer_t
441*1449Stomee  * if the native method call will enter the consumer loop.
442*1449Stomee  */
443*1449Stomee extern dtj_status_t dtj_java_consumer_init(JNIEnv *, dtj_java_consumer_t *);
444*1449Stomee extern void dtj_java_consumer_fini(JNIEnv *, dtj_java_consumer_t *);
445*1449Stomee 
446*1449Stomee /*
447*1449Stomee  * Throws a DTraceException with a message constructed from the given format
448*1449Stomee  * string and variable arg list.
449*1449Stomee  */
450*1449Stomee extern void dtj_throw_dtrace_exception(dtj_java_consumer_t *,
451*1449Stomee     const char *, ...);
452*1449Stomee 
453*1449Stomee /* Returns NULL if pending Java Exception or OutOfMemoryError */
454*1449Stomee extern jobject dtj_new_probedesc(dtj_java_consumer_t *,
455*1449Stomee     const dtrace_probedesc_t *);
456*1449Stomee extern jobject dtj_new_probeinfo(dtj_java_consumer_t *,
457*1449Stomee     const dtrace_probeinfo_t *);
458*1449Stomee extern jobject dtj_new_attribute(dtj_java_consumer_t *,
459*1449Stomee     const dtrace_attribute_t *);
460*1449Stomee 
461*1449Stomee /*
462*1449Stomee  * Returns NULL if the given fault is unrecognized, otherwise returns the name
463*1449Stomee  * of the fault, guaranteed not to change across multiple versions of this API
464*1449Stomee  * even if the integer value changes in libdtrace.
465*1449Stomee  */
466*1449Stomee extern const char *dtj_get_fault_name(int);
467*1449Stomee 
468*1449Stomee /* Gets the libdtrace error number and message */
469*1449Stomee extern dtj_status_t dtj_get_dtrace_error(dtj_java_consumer_t *, dtj_error_t *);
470*1449Stomee 
471*1449Stomee /* Stops the DTrace consumer */
472*1449Stomee extern void dtj_stop(dtj_java_consumer_t *);
473*1449Stomee 
474*1449Stomee /*
475*1449Stomee  * The Consumer getAggregate() method runs in the caller's current thread
476*1449Stomee  * separate from the consumer loop.
477*1449Stomee  */
478*1449Stomee extern jobject dtj_get_aggregate(dtj_java_consumer_t *);
479*1449Stomee 
480*1449Stomee /*
481*1449Stomee  * A blocking call that runs the consumer loop.  If this function returns an
482*1449Stomee  * error status, it is necessary to call stop() in order to dtrace_stop() the
483*1449Stomee  * consumer in libdtrace (it is safe to call stop() in either case).
484*1449Stomee  */
485*1449Stomee extern dtj_status_t dtj_consume(dtj_java_consumer_t *);
486*1449Stomee 
487*1449Stomee #ifdef	__cplusplus
488*1449Stomee }
489*1449Stomee #endif
490*1449Stomee 
491*1449Stomee #endif	/* _DTRACE_JNI_H */
492