xref: /illumos-gate/usr/src/lib/libc/inc/tdb_agent.h (revision 1da57d55)
1*7c478bd9Sstevel@tonic-gate /*
2*7c478bd9Sstevel@tonic-gate  * CDDL HEADER START
3*7c478bd9Sstevel@tonic-gate  *
4*7c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5*7c478bd9Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
6*7c478bd9Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
7*7c478bd9Sstevel@tonic-gate  * with the License.
8*7c478bd9Sstevel@tonic-gate  *
9*7c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10*7c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
11*7c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
12*7c478bd9Sstevel@tonic-gate  * and limitations under the License.
13*7c478bd9Sstevel@tonic-gate  *
14*7c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
15*7c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16*7c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
17*7c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
18*7c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
19*7c478bd9Sstevel@tonic-gate  *
20*7c478bd9Sstevel@tonic-gate  * CDDL HEADER END
21*7c478bd9Sstevel@tonic-gate  */
22*7c478bd9Sstevel@tonic-gate /*
23*7c478bd9Sstevel@tonic-gate  * Copyright 2003 Sun Microsystems, Inc.  All rights reserved.
24*7c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
25*7c478bd9Sstevel@tonic-gate  */
26*7c478bd9Sstevel@tonic-gate 
27*7c478bd9Sstevel@tonic-gate #ifndef	_TDB_AGENT_H
28*7c478bd9Sstevel@tonic-gate #define	_TDB_AGENT_H
29*7c478bd9Sstevel@tonic-gate 
30*7c478bd9Sstevel@tonic-gate /*
31*7c478bd9Sstevel@tonic-gate  * Thread debug agent control structures.
32*7c478bd9Sstevel@tonic-gate  *
33*7c478bd9Sstevel@tonic-gate  * This is an implementation-specific header file that is shared
34*7c478bd9Sstevel@tonic-gate  * between libc and libc_db.  It is NOT a public header file
35*7c478bd9Sstevel@tonic-gate  * and must never be installed in /usr/include
36*7c478bd9Sstevel@tonic-gate  */
37*7c478bd9Sstevel@tonic-gate 
38*7c478bd9Sstevel@tonic-gate #include <thread_db.h>
39*7c478bd9Sstevel@tonic-gate 
40*7c478bd9Sstevel@tonic-gate #ifdef __cplusplus
41*7c478bd9Sstevel@tonic-gate extern "C" {
42*7c478bd9Sstevel@tonic-gate #endif
43*7c478bd9Sstevel@tonic-gate 
44*7c478bd9Sstevel@tonic-gate /*
45*7c478bd9Sstevel@tonic-gate  * The structure containing per-thread event data.
46*7c478bd9Sstevel@tonic-gate  */
47*7c478bd9Sstevel@tonic-gate typedef struct {
48*7c478bd9Sstevel@tonic-gate 	td_thr_events_t	eventmask;	/* Which events are enabled? */
49*7c478bd9Sstevel@tonic-gate 	td_event_e	eventnum;	/* Most recent enabled event */
50*7c478bd9Sstevel@tonic-gate 	void		*eventdata;	/* Param. for most recent event */
51*7c478bd9Sstevel@tonic-gate } td_evbuf_t;
52*7c478bd9Sstevel@tonic-gate 
53*7c478bd9Sstevel@tonic-gate #ifdef _SYSCALL32
54*7c478bd9Sstevel@tonic-gate typedef struct {
55*7c478bd9Sstevel@tonic-gate 	td_thr_events_t	eventmask;	/* Which events are enabled? */
56*7c478bd9Sstevel@tonic-gate 	td_event_e	eventnum;	/* Most recent enabled event */
57*7c478bd9Sstevel@tonic-gate 	caddr32_t	eventdata;	/* Param. for most recent event */
58*7c478bd9Sstevel@tonic-gate } td_evbuf32_t;
59*7c478bd9Sstevel@tonic-gate #endif /* _SYSCALL32 */
60*7c478bd9Sstevel@tonic-gate 
61*7c478bd9Sstevel@tonic-gate 
62*7c478bd9Sstevel@tonic-gate /*
63*7c478bd9Sstevel@tonic-gate  * All of these structures are constrained to have a size of 48 bytes.
64*7c478bd9Sstevel@tonic-gate  * This is so that two 8-byte pointers can be inserted at the front to
65*7c478bd9Sstevel@tonic-gate  * make up a complete tdb_sync_stats_t structure of exactly 64 bytes.
66*7c478bd9Sstevel@tonic-gate  * The 'type' element of each structure identifies the type of the union,
67*7c478bd9Sstevel@tonic-gate  * with values from the following defines.
68*7c478bd9Sstevel@tonic-gate  */
69*7c478bd9Sstevel@tonic-gate 
70*7c478bd9Sstevel@tonic-gate #define	TDB_NONE	0
71*7c478bd9Sstevel@tonic-gate #define	TDB_MUTEX	1
72*7c478bd9Sstevel@tonic-gate #define	TDB_COND	2
73*7c478bd9Sstevel@tonic-gate #define	TDB_RWLOCK	3
74*7c478bd9Sstevel@tonic-gate #define	TDB_SEMA	4
75*7c478bd9Sstevel@tonic-gate 
76*7c478bd9Sstevel@tonic-gate typedef struct {
77*7c478bd9Sstevel@tonic-gate 	uint16_t	type;
78*7c478bd9Sstevel@tonic-gate 	uint16_t	unused;
79*7c478bd9Sstevel@tonic-gate 	uint_t		mutex_lock;
80*7c478bd9Sstevel@tonic-gate 	hrtime_t	mutex_hold_time;
81*7c478bd9Sstevel@tonic-gate 	hrtime_t	mutex_sleep_time;
82*7c478bd9Sstevel@tonic-gate 	uint_t		mutex_sleep;
83*7c478bd9Sstevel@tonic-gate 	uint_t		mutex_try;
84*7c478bd9Sstevel@tonic-gate 	uint_t		mutex_try_fail;
85*7c478bd9Sstevel@tonic-gate 	uint_t		mutex_pad[1];
86*7c478bd9Sstevel@tonic-gate 	hrtime_t	mutex_begin_hold;
87*7c478bd9Sstevel@tonic-gate } tdb_mutex_stats_t;
88*7c478bd9Sstevel@tonic-gate 
89*7c478bd9Sstevel@tonic-gate typedef struct {
90*7c478bd9Sstevel@tonic-gate 	uint16_t	type;
91*7c478bd9Sstevel@tonic-gate 	uint16_t	unused;
92*7c478bd9Sstevel@tonic-gate 	uint_t		cond_wait;
93*7c478bd9Sstevel@tonic-gate 	uint_t		cond_timedwait;
94*7c478bd9Sstevel@tonic-gate 	uint_t		cond_timedwait_timeout;
95*7c478bd9Sstevel@tonic-gate 	hrtime_t	cond_wait_sleep_time;
96*7c478bd9Sstevel@tonic-gate 	hrtime_t	cond_timedwait_sleep_time;
97*7c478bd9Sstevel@tonic-gate 	uint_t		cond_signal;
98*7c478bd9Sstevel@tonic-gate 	uint_t		cond_broadcast;
99*7c478bd9Sstevel@tonic-gate 	uint_t		cond_pad[2];
100*7c478bd9Sstevel@tonic-gate } tdb_cond_stats_t;
101*7c478bd9Sstevel@tonic-gate 
102*7c478bd9Sstevel@tonic-gate typedef struct {
103*7c478bd9Sstevel@tonic-gate 	uint16_t	type;
104*7c478bd9Sstevel@tonic-gate 	uint16_t	unused;
105*7c478bd9Sstevel@tonic-gate 	uint_t		rw_rdlock;
106*7c478bd9Sstevel@tonic-gate 	/* rw_rdlock_sleep is the reader cv's cond_wait count */
107*7c478bd9Sstevel@tonic-gate 	/* rw_rdlock_sleep_time is the reader cv's cond_wait_sleep_time */
108*7c478bd9Sstevel@tonic-gate 	uint_t		rw_rdlock_try;
109*7c478bd9Sstevel@tonic-gate 	uint_t		rw_rdlock_try_fail;
110*7c478bd9Sstevel@tonic-gate 	uint_t		rw_pad[1];
111*7c478bd9Sstevel@tonic-gate 	uint_t		rw_wrlock;
112*7c478bd9Sstevel@tonic-gate 	/* rw_wrlock_sleep is the writer cv's cond_wait count */
113*7c478bd9Sstevel@tonic-gate 	/* rw_wrlock_sleep_time is the writer cv's cond_wait_sleep_time */
114*7c478bd9Sstevel@tonic-gate 	hrtime_t	rw_wrlock_hold_time;
115*7c478bd9Sstevel@tonic-gate 	uint_t		rw_wrlock_try;
116*7c478bd9Sstevel@tonic-gate 	uint_t		rw_wrlock_try_fail;
117*7c478bd9Sstevel@tonic-gate 	hrtime_t	rw_wrlock_begin_hold;
118*7c478bd9Sstevel@tonic-gate } tdb_rwlock_stats_t;
119*7c478bd9Sstevel@tonic-gate 
120*7c478bd9Sstevel@tonic-gate typedef struct {
121*7c478bd9Sstevel@tonic-gate 	uint16_t	type;
122*7c478bd9Sstevel@tonic-gate 	uint16_t	unused;
123*7c478bd9Sstevel@tonic-gate 	uint_t		sema_post;
124*7c478bd9Sstevel@tonic-gate 	uint_t		sema_wait;
125*7c478bd9Sstevel@tonic-gate 	uint_t		sema_wait_sleep;
126*7c478bd9Sstevel@tonic-gate 	hrtime_t	sema_wait_sleep_time;
127*7c478bd9Sstevel@tonic-gate 	uint_t		sema_trywait;
128*7c478bd9Sstevel@tonic-gate 	uint_t		sema_trywait_fail;
129*7c478bd9Sstevel@tonic-gate 	uint_t		sema_max_count;
130*7c478bd9Sstevel@tonic-gate 	uint_t		sema_min_count;
131*7c478bd9Sstevel@tonic-gate 	uint_t		sema_pad[2];
132*7c478bd9Sstevel@tonic-gate } tdb_sema_stats_t;
133*7c478bd9Sstevel@tonic-gate 
134*7c478bd9Sstevel@tonic-gate /*
135*7c478bd9Sstevel@tonic-gate  * An entry in the sync. object hash table.
136*7c478bd9Sstevel@tonic-gate  */
137*7c478bd9Sstevel@tonic-gate typedef struct {
138*7c478bd9Sstevel@tonic-gate 	uint64_t	next;
139*7c478bd9Sstevel@tonic-gate 	uint64_t	sync_addr;
140*7c478bd9Sstevel@tonic-gate 	union {
141*7c478bd9Sstevel@tonic-gate 		uint16_t		type;
142*7c478bd9Sstevel@tonic-gate 		tdb_mutex_stats_t	mutex;
143*7c478bd9Sstevel@tonic-gate 		tdb_cond_stats_t	cond;
144*7c478bd9Sstevel@tonic-gate 		tdb_rwlock_stats_t	rwlock;
145*7c478bd9Sstevel@tonic-gate 		tdb_sema_stats_t	sema;
146*7c478bd9Sstevel@tonic-gate 	} un;
147*7c478bd9Sstevel@tonic-gate } tdb_sync_stats_t;
148*7c478bd9Sstevel@tonic-gate 
149*7c478bd9Sstevel@tonic-gate /* peg count values at UINT_MAX */
150*7c478bd9Sstevel@tonic-gate #define	tdb_incr(x)	(((x) != UINT_MAX)? (x)++ : 0)
151*7c478bd9Sstevel@tonic-gate 
152*7c478bd9Sstevel@tonic-gate /*
153*7c478bd9Sstevel@tonic-gate  * The tdb_register_sync variable is set to REGISTER_SYNC_ENABLE by a
154*7c478bd9Sstevel@tonic-gate  * debugger to enable synchronization object registration.
155*7c478bd9Sstevel@tonic-gate  * Thereafter, synchronization primitives call tdb_sync_obj_register()
156*7c478bd9Sstevel@tonic-gate  * to put their synchronization objects in the registration hash table.
157*7c478bd9Sstevel@tonic-gate  * In this state, the first call to tdb_sync_obj_register() empties the
158*7c478bd9Sstevel@tonic-gate  * hash table and sets tdb_register_sync to REGISTER_SYNC_ON.
159*7c478bd9Sstevel@tonic-gate  *
160*7c478bd9Sstevel@tonic-gate  * The tdb_register_sync variable is set to REGISTER_SYNC_DISABLE by a
161*7c478bd9Sstevel@tonic-gate  * debugger to disable synchronization object registration.
162*7c478bd9Sstevel@tonic-gate  * In this state, the first call to tdb_sync_obj_register() empties the
163*7c478bd9Sstevel@tonic-gate  * hash table and sets tdb_register_sync to REGISTER_SYNC_OFF.
164*7c478bd9Sstevel@tonic-gate  * Thereafter, synchronization primitives do not call tdb_sync_obj_register().
165*7c478bd9Sstevel@tonic-gate  *
166*7c478bd9Sstevel@tonic-gate  * Sync object *_destroy() functions always call tdb_sync_obj_deregister().
167*7c478bd9Sstevel@tonic-gate  */
168*7c478bd9Sstevel@tonic-gate typedef	uint8_t	register_sync_t;
169*7c478bd9Sstevel@tonic-gate #define	REGISTER_SYNC_OFF	0	/* registration is off */
170*7c478bd9Sstevel@tonic-gate #define	REGISTER_SYNC_ON	1	/* registration is on */
171*7c478bd9Sstevel@tonic-gate #define	REGISTER_SYNC_DISABLE	2	/* request to disable registration */
172*7c478bd9Sstevel@tonic-gate #define	REGISTER_SYNC_ENABLE	3	/* request to enable registration */
173*7c478bd9Sstevel@tonic-gate 
174*7c478bd9Sstevel@tonic-gate extern	tdb_sync_stats_t	*tdb_sync_obj_register(void *, int *);
175*7c478bd9Sstevel@tonic-gate extern	void			tdb_sync_obj_deregister(void *);
176*7c478bd9Sstevel@tonic-gate 
177*7c478bd9Sstevel@tonic-gate /*
178*7c478bd9Sstevel@tonic-gate  * Definitions for acquiring pointers to synch object statistics blocks
179*7c478bd9Sstevel@tonic-gate  * contained in the synchronization object registration hash table.
180*7c478bd9Sstevel@tonic-gate  */
181*7c478bd9Sstevel@tonic-gate extern	tdb_mutex_stats_t	*tdb_mutex_stats(mutex_t *);
182*7c478bd9Sstevel@tonic-gate extern	tdb_cond_stats_t	*tdb_cond_stats(cond_t *);
183*7c478bd9Sstevel@tonic-gate extern	tdb_rwlock_stats_t	*tdb_rwlock_stats(rwlock_t *);
184*7c478bd9Sstevel@tonic-gate extern	tdb_sema_stats_t	*tdb_sema_stats(sema_t *);
185*7c478bd9Sstevel@tonic-gate 
186*7c478bd9Sstevel@tonic-gate #define	REGISTER_SYNC(udp)	(udp)->uberflags.uf_tdb_register_sync
187*7c478bd9Sstevel@tonic-gate 
188*7c478bd9Sstevel@tonic-gate #define	MUTEX_STATS(mp, udp)	\
189*7c478bd9Sstevel@tonic-gate 		(REGISTER_SYNC(udp)? tdb_mutex_stats(mp): NULL)
190*7c478bd9Sstevel@tonic-gate #define	COND_STATS(cvp, udp)	\
191*7c478bd9Sstevel@tonic-gate 		(REGISTER_SYNC(udp)? tdb_cond_stats(cvp): NULL)
192*7c478bd9Sstevel@tonic-gate #define	RWLOCK_STATS(rwlp, udp)	\
193*7c478bd9Sstevel@tonic-gate 		(REGISTER_SYNC(udp)? tdb_rwlock_stats(rwlp): NULL)
194*7c478bd9Sstevel@tonic-gate #define	SEMA_STATS(sp, udp)	\
195*7c478bd9Sstevel@tonic-gate 		(REGISTER_SYNC(udp)? tdb_sema_stats(sp): NULL)
196*7c478bd9Sstevel@tonic-gate 
197*7c478bd9Sstevel@tonic-gate /*
198*7c478bd9Sstevel@tonic-gate  * Parameters of the synchronization object registration hash table.
199*7c478bd9Sstevel@tonic-gate  */
200*7c478bd9Sstevel@tonic-gate #define	TDB_HASH_SHIFT	15	/* 32K hash table entries */
201*7c478bd9Sstevel@tonic-gate #define	TDB_HASH_SIZE	(1 << TDB_HASH_SHIFT)
202*7c478bd9Sstevel@tonic-gate #define	TDB_HASH_MASK	(TDB_HASH_SIZE - 1)
203*7c478bd9Sstevel@tonic-gate 
204*7c478bd9Sstevel@tonic-gate /*
205*7c478bd9Sstevel@tonic-gate  * uberdata.tdb_hash_lock protects all synchronization object
206*7c478bd9Sstevel@tonic-gate  * hash table data structures.
207*7c478bd9Sstevel@tonic-gate  * uberdata.tdb_hash_lock_stats is a special tdb_sync_stats structure
208*7c478bd9Sstevel@tonic-gate  * reserved for tdb_hash_lock.
209*7c478bd9Sstevel@tonic-gate  */
210*7c478bd9Sstevel@tonic-gate 
211*7c478bd9Sstevel@tonic-gate typedef	void (*tdb_ev_func_t)(void);
212*7c478bd9Sstevel@tonic-gate 
213*7c478bd9Sstevel@tonic-gate /*
214*7c478bd9Sstevel@tonic-gate  * Uberdata for thread debug interfaces (known to libc_db).
215*7c478bd9Sstevel@tonic-gate  */
216*7c478bd9Sstevel@tonic-gate typedef struct {
217*7c478bd9Sstevel@tonic-gate 	/*
218*7c478bd9Sstevel@tonic-gate 	 * Pointer to the hash table of sync_addr_t descriptors.
219*7c478bd9Sstevel@tonic-gate 	 * This holds the addresses of all of the synchronization variables
220*7c478bd9Sstevel@tonic-gate 	 * that the library has seen since tracking was enabled by a debugger.
221*7c478bd9Sstevel@tonic-gate 	 */
222*7c478bd9Sstevel@tonic-gate 	uint64_t		*tdb_sync_addr_hash;
223*7c478bd9Sstevel@tonic-gate 	/*
224*7c478bd9Sstevel@tonic-gate 	 * The number of entries in the hash table.
225*7c478bd9Sstevel@tonic-gate 	 */
226*7c478bd9Sstevel@tonic-gate 	uint_t			tdb_register_count;
227*7c478bd9Sstevel@tonic-gate 	int			tdb_hash_alloc_failed;
228*7c478bd9Sstevel@tonic-gate 	/*
229*7c478bd9Sstevel@tonic-gate 	 * The free list of sync_addr_t descriptors.
230*7c478bd9Sstevel@tonic-gate 	 * When the free list is used up, it is replenished using mmap().
231*7c478bd9Sstevel@tonic-gate 	 * sync_addr_t descriptors are never freed, though they may be
232*7c478bd9Sstevel@tonic-gate 	 * removed from the hash table and returned to the free list.
233*7c478bd9Sstevel@tonic-gate 	 */
234*7c478bd9Sstevel@tonic-gate 	tdb_sync_stats_t	*tdb_sync_addr_free;
235*7c478bd9Sstevel@tonic-gate 	tdb_sync_stats_t	*tdb_sync_addr_last;
236*7c478bd9Sstevel@tonic-gate 	size_t			tdb_sync_alloc;
237*7c478bd9Sstevel@tonic-gate 	/*
238*7c478bd9Sstevel@tonic-gate 	 * The set of globally enabled events to report to libc_db.
239*7c478bd9Sstevel@tonic-gate 	 */
240*7c478bd9Sstevel@tonic-gate 	td_thr_events_t		tdb_ev_global_mask;
241*7c478bd9Sstevel@tonic-gate 	/*
242*7c478bd9Sstevel@tonic-gate 	 * The array of event function pointers.
243*7c478bd9Sstevel@tonic-gate 	 */
244*7c478bd9Sstevel@tonic-gate 	const tdb_ev_func_t	*tdb_events;
245*7c478bd9Sstevel@tonic-gate } tdb_t;
246*7c478bd9Sstevel@tonic-gate 
247*7c478bd9Sstevel@tonic-gate #ifdef _SYSCALL32
248*7c478bd9Sstevel@tonic-gate typedef struct {
249*7c478bd9Sstevel@tonic-gate 	caddr32_t	tdb_sync_addr_hash;
250*7c478bd9Sstevel@tonic-gate 	uint_t		tdb_register_count;
251*7c478bd9Sstevel@tonic-gate 	int		tdb_hash_alloc_failed;
252*7c478bd9Sstevel@tonic-gate 	caddr32_t	tdb_sync_addr_free;
253*7c478bd9Sstevel@tonic-gate 	caddr32_t	tdb_sync_addr_last;
254*7c478bd9Sstevel@tonic-gate 	size32_t	tdb_sync_alloc;
255*7c478bd9Sstevel@tonic-gate 	td_thr_events_t	tdb_ev_global_mask;
256*7c478bd9Sstevel@tonic-gate 	caddr32_t	tdb_events;
257*7c478bd9Sstevel@tonic-gate } tdb32_t;
258*7c478bd9Sstevel@tonic-gate #endif /* _SYSCALL32 */
259*7c478bd9Sstevel@tonic-gate 
260*7c478bd9Sstevel@tonic-gate /*
261*7c478bd9Sstevel@tonic-gate  * This will have to change if event numbers exceed 31.
262*7c478bd9Sstevel@tonic-gate  * Note that we only test tdb_ev_global_mask.event_bits[0] below.
263*7c478bd9Sstevel@tonic-gate  */
264*7c478bd9Sstevel@tonic-gate #define	__td_event_report(ulwp, event, udp)				\
265*7c478bd9Sstevel@tonic-gate 	(((ulwp)->ul_td_events_enable &&				\
266*7c478bd9Sstevel@tonic-gate 	td_eventismember(&(ulwp)->ul_td_evbuf.eventmask, (event))) ||	\
267*7c478bd9Sstevel@tonic-gate 	((udp)->tdb.tdb_ev_global_mask.event_bits[0] &&			\
268*7c478bd9Sstevel@tonic-gate 	td_eventismember(&(udp)->tdb.tdb_ev_global_mask, (event))))
269*7c478bd9Sstevel@tonic-gate 
270*7c478bd9Sstevel@tonic-gate /*
271*7c478bd9Sstevel@tonic-gate  * Event "reporting" functions.  A thread reports an event by calling
272*7c478bd9Sstevel@tonic-gate  * one of these empty functions; a debugger can set a breakpoint
273*7c478bd9Sstevel@tonic-gate  * at the address of any of these functions to determine that an
274*7c478bd9Sstevel@tonic-gate  * event is being reported.
275*7c478bd9Sstevel@tonic-gate  */
276*7c478bd9Sstevel@tonic-gate extern const tdb_ev_func_t tdb_events[TD_MAX_EVENT_NUM - TD_MIN_EVENT_NUM + 1];
277*7c478bd9Sstevel@tonic-gate 
278*7c478bd9Sstevel@tonic-gate #define	tdb_event(event, udp)		\
279*7c478bd9Sstevel@tonic-gate 	(*(udp)->tdb.tdb_events[(event) - TD_MIN_EVENT_NUM])()
280*7c478bd9Sstevel@tonic-gate 
281*7c478bd9Sstevel@tonic-gate #ifdef __cplusplus
282*7c478bd9Sstevel@tonic-gate }
283*7c478bd9Sstevel@tonic-gate #endif
284*7c478bd9Sstevel@tonic-gate 
285*7c478bd9Sstevel@tonic-gate #endif	/* _TDB_AGENT_H */
286