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