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