text: /*
   * 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 */
  