1 /*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21 /*
22 * Copyright (c) 2008-2009, Intel Corporation.
23 * All Rights Reserved.
24 */
25
26 #ifndef _LATENCYTOP_H
27 #define _LATENCYTOP_H
28
29 #include <sys/types.h>
30
31 #include <glib.h>
32
33 #ifdef __cplusplus
34 extern "C" {
35 #endif
36
37 /*
38 * Without this lint seems to be confused by glib header file.
39 */
40 #ifdef __lint
41 #undef g_assert
42 #define g_assert(x) ((void)(x))
43 #undef TRUE
44 #define TRUE 1
45 #endif
46
47 /*
48 * We define our own conversions in order to avoid compiler warnings.
49 */
50 #define LT_INT_TO_POINTER(a) ((void *)(unsigned long)(a))
51
52 #define TITLE "LatencyTOP for OpenSolaris, version 1.0"
53 #define COPYRIGHT "Copyright (c) 2008-2009, Intel Corporation."
54 #define DEFAULT_KLOG_FILE "/var/log/latencytop.log"
55
56 #define INVALID_PID (~0)
57 #define INVALID_TID (~0)
58 #define PID_SYS_GLOBAL INVALID_PID
59 #define INVALID_CAUSE 0
60 #define HIGHER_PRIORITY(a, b) ((a) > (b))
61
62 #ifdef EMBED_CONFIGS
63 /*
64 * LatencyTOP configuration is embedded in the binary.
65 * Array will be generated by elfwrap.
66 */
67 extern char latencytop_d_start;
68 extern char latencytop_d_end;
69 extern char latencytop_trans_start;
70 extern char latencytop_trans_end;
71 #else
72 /*
73 * LatencyTOP configuration is provided externally by user.
74 */
75 #define DEFAULT_CONFIG_NAME "./latencytop.trans"
76 #define DEFAULT_D_SCRIPT_NAME "./latencytop.d"
77 #endif
78
79 typedef enum {
80 LT_STAT_COUNT,
81 LT_STAT_MAX,
82 LT_STAT_SUM,
83 } lt_stat_type_t;
84
85 #define LT_KLOG_LEVEL_NONE 0 /* Log nothing */
86 #define LT_KLOG_LEVEL_UNMAPPED 1 /* Log only stacks not mapped */
87 #define LT_KLOG_LEVEL_MAPPED 2 /* Log only stacks mapped */
88 #define LT_KLOG_LEVEL_ALL 3 /* Log all stacks, mapped or not */
89
90 typedef enum {
91 LT_LEVEL_GLOBAL, /* System wide statistics */
92 LT_LEVEL_PROCESS, /* Per-process statistics */
93 LT_LEVEL_THREAD, /* Per-thread statistics */
94 } lt_stat_level_t;
95
96 typedef enum {
97 LT_SORT_TOTAL,
98 LT_SORT_MAX,
99 LT_SORT_AVG,
100 LT_SORT_COUNT,
101 } lt_sort_t;
102
103 typedef enum {
104 LT_FIELD_FNAME,
105 LT_FIELD_PSARGS,
106 } lt_field_t;
107
108 typedef enum {
109 LT_LIST_CAUSE, /* List latency by causes (default) */
110 LT_LIST_SPECIALS, /* List only "special" causes */
111 LT_LIST_SOBJ /* List synchronization objects */
112 } lt_list_type_t;
113
114 /*
115 * Data structure which contains statistics.
116 */
117 typedef struct {
118 uint64_t lt_s_count;
119 uint64_t lt_s_total;
120 uint64_t lt_s_max;
121 } lt_stat_data_t;
122
123 /*
124 * Data structure that stores statistics along with the name.
125 */
126 typedef struct {
127 enum {
128 STAT_CAUSE,
129 STAT_SOBJ
130 } lt_se_type;
131 const char *lt_se_string;
132 lt_stat_data_t lt_se_data;
133 union {
134 struct {
135 int lt_se_c_id;
136 int lt_se_c_flags;
137 } lt_se_t_cause;
138 struct {
139 int lt_se_s_id;
140 } lt_se_t_sobj;
141 } lt_se_tsdata; /* type specific data */
142 } lt_stat_entry_t;
143
144 typedef struct {
145 int lt_cfg_enable_filter;
146 int lt_cfg_trace_sched;
147 int lt_cfg_trace_syncobj;
148 int lt_cfg_low_overhead_mode;
149 int lt_cfg_snap_interval;
150 char *lt_cfg_config_name;
151 unsigned int lt_cfg_trace_pid;
152 unsigned int lt_cfg_trace_pgid;
153 } lt_config_t;
154
155 extern lt_config_t g_config; /* The global settings */
156
157 /*
158 * Causes can be disabled through the configuration file.
159 * When disabled, though D script will continue to capture causes, they will
160 * not be counted by LatencyTOP.
161 */
162 #define CAUSE_FLAG_DISABLED 1
163 /*
164 * This flag will not show and count causes as part of summary in
165 * "kstack window".
166 */
167 #define CAUSE_FLAG_HIDE_IN_SUMMARY 2
168 /*
169 * This is generated from D script (named cause), and is "special".
170 */
171 #define CAUSE_FLAG_SPECIAL 4
172 #define CAUSE_ALL_FLAGS 0xffffffff
173
174 extern boolean_t lt_drop_detected;
175
176 /*
177 * These functions collect statistics using DTrace.
178 */
179 extern int lt_dtrace_init(void);
180 extern int lt_dtrace_work(int);
181 extern int lt_dtrace_collect(void);
182 extern int lt_dtrace_deinit(void);
183
184 /*
185 * These functions maintain configuration, e.g. symbol to cause mapping.
186 */
187 extern int lt_table_init(void);
188 extern int lt_table_cause_from_stack(const char *, int *, int *);
189 extern const char *lt_table_get_cause_name(int);
190 extern int lt_table_get_cause_flag(int, int);
191 extern int lt_table_cause_from_name(char *, int, int);
192 extern int lt_table_append_trans(FILE *fp);
193 extern void lt_table_deinit(void);
194
195 /*
196 * These functions update statistic of all causes of latency, collected
197 * from DTrace.
198 */
199 extern void lt_stat_update(pid_t, id_t, char *, char *, unsigned int,
200 lt_stat_type_t, uint64_t);
201 extern void lt_stat_update_cause(pid_t, id_t, int, lt_stat_type_t, uint64_t);
202 extern void lt_stat_update_sobj(pid_t, id_t, int, unsigned long long,
203 lt_stat_type_t, uint64_t);
204 extern void lt_stat_clear_all(void);
205 extern void lt_stat_free_all(void);
206
207 /*
208 * These functions produce lists for display panes.
209 * Note: after a call to lt_stat_update_*, the old lists will become invalid.
210 */
211 extern void *lt_stat_list_create(lt_list_type_t, lt_stat_level_t,
212 pid_t, id_t, int, lt_sort_t);
213 extern int lt_stat_list_has_item(void *, int);
214 extern const char *lt_stat_list_get_reason(void *, int);
215 extern uint64_t lt_stat_list_get_max(void *, int);
216 extern uint64_t lt_stat_list_get_sum(void *, int);
217 extern uint64_t lt_stat_list_get_count(void *, int);
218 extern uint64_t lt_stat_list_get_gtotal(void *);
219 extern void lt_stat_list_free(void *);
220
221 /*
222 * These functions produce the process list and the thread list.
223 */
224 extern int lt_stat_proc_list_create(pid_t **, id_t **);
225 extern void lt_stat_proc_list_free(pid_t *, id_t *);
226 extern const char *lt_stat_proc_get_name(pid_t);
227 extern int lt_stat_proc_get_nthreads(pid_t);
228
229 /*
230 * These functions use ncurses to create console-based display.
231 */
232 extern void lt_display_init(void);
233 extern int lt_display_loop(int);
234 extern void lt_display_error(const char *, ...);
235 extern void lt_display_deinit(void);
236
237 /*
238 * Write statistics to log file - useful for debugging and offline analysis.
239 */
240 extern void lt_klog_init(void);
241 extern void lt_klog_deinit(void);
242 extern int lt_klog_set_log_file(const char *);
243 extern int lt_klog_set_log_level(int);
244 extern void lt_klog_write(void);
245 extern void lt_klog_log(int, pid_t, char *, lt_stat_type_t,
246 uint64_t);
247
248 /*
249 * Utility functions.
250 */
251 extern uint64_t lt_millisecond(void);
252 extern void *lt_malloc(size_t);
253 extern void *lt_zalloc(size_t);
254 extern char *lt_strdup(const char *);
255 extern void lt_check_null(void *);
256 extern void lt_time_str(char *, int);
257 extern char *lt_get_proc_field(pid_t, lt_field_t);
258 extern void lt_update_stat_value(lt_stat_data_t *, lt_stat_type_t, uint64_t);
259 extern int lt_sort_by_total_desc(lt_stat_entry_t *, lt_stat_entry_t *);
260 extern int lt_sort_by_max_desc(lt_stat_entry_t *, lt_stat_entry_t *);
261 extern int lt_sort_by_count_desc(lt_stat_entry_t *, lt_stat_entry_t *);
262 extern int lt_sort_by_avg_desc(lt_stat_entry_t *, lt_stat_entry_t *);
263 extern void lt_gpipe_init(void);
264 extern void lt_gpipe_deinit(void);
265 extern void lt_gpipe_break(const char *);
266 extern int lt_gpipe_readfd(void);
267 extern int lt_file_exist(const char *);
268
269 #ifdef __cplusplus
270 }
271 #endif
272
273 #endif /* _LATENCYTOP_H */