/* * 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 #include #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; } 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 */