ELF>0@@]@8@@@@@o@ @YY  B P2x#x#B@Pdd88@llo/usr/lib/amd64/ld.so.1!;llįDX0|\\8` HTpP LH<x@p` tH p `  0 X 8 H 0p  @ p 80 H` 0\0X,Xlx  H\pT@X(H8 h x   PX0dXD@hHt<8``t(x   $$@AC $LȲ@AC A$t|@AC $@RAC A,@L AC ABBBBx   ,$0@AC ABBB,T@;AC ABB,@AC ABBBB$@AC A$@wAC $ @AC ,,@{AC ABB,\<@ AC ABBBB,H@AC ABBBB,@uAC ABB$X@3AC A,@AC ABBB,D@AC ABB$t<@AC $ @AC $4@OAC A,@AC ABBBB$t@xAC $D@3AC x   $$ @4AC ,LT@AC ABBBB,|@AC ABBBB,@RAC ABBBB,T@AAC ABB$ @(AC $4@AC AB$\@AC AB$@AC $,@lAC Ax   $$@!AC $L@)AC $t@nAC $X@AC AB$@"AC $@AC A$,@CAC A,<p@QAC ABBBBx   $$@HAC A$L @YAC AB$th@^AC AB$@AAC $ @AC A$@aAC A,$@AC ABB,D@LAC ABBBB,t0@AC ABBBB,8@AC ABBBB,@AC ABB,@|AC ABBBB,4p@AC ABBBB$d@9AC $@>AC ,@$AC ABBBB$ @EAC A$ h@)AC $4@uAC AB$\ @,AC $8@,AC $d@,AC $@AC $@ AC $$@AC AB$LDAMAC AB,tA>AC ABBBB$AIAC $ A0AC A$PA<AC $ABAC ,DAiAC ABBBBx   $$<ASAC A$LANAC A,tA}AC ABB$`AAC ,AAC ABBBB,DAAC ABBB,,DAAC ABBB,\AAC ABBBB$ AAC , AAC ABBBB,AAC ABBBB,AAC ABBB,D4AAC ABB$tA6AC $A5AC $PALAC A$AAC Ax   $$<A@AC $L|AVAC $tA#AC A$A*AC A$$A#AC A$HAzAC AB,AAC ABB$DA)AC $lAcAC AB$AcAC AB$tAcAC AB$AAC AB$ AAC $4AAC $\AAC $A AC $AAC        !"$&')+-01347:;=@BDEGHIKMNQRSTVX[^_abcegjklnopqrtuvwy{|} #%(*,./25689<>?ACFJLOPUWYZ\]`dfhimsxz~ ")5CP@^Ȳ@j|@y@R0@@;@@@w @@{<@ H@*@u7X@3B@L@W<@c @mx @4T@@@RT@A@(@!@)@H @Yh@^@A @)@a3$@>@LP0@[8@j@u@ }@DAMA><ASANA}`AADADAA A' A4;MT0@[@eЮ@uh@)p@A6P@ A0P@AcЫ@@ @@@,@6AH@]Aiq@{Щ@`@P@ @,A@@B @@@@|y@,@x#B@"'RB(0 @6@<t@xNp@. @`&Bip@v@0@@`@A# ,B@Y@ @ 'B@'B8A! @ Я@*@>@ DY@Y0@`X@n@w @E@A@>,@CЬ@@X@@ @&B.@5PALK@XP@i@t`@@L `@@@@Э@@`@p@@PB P@@z@!PB p@AI;`@BA Rp@Q^ @z$A#0@4@O@@3@@@0@A@ @ tAc5 YA< 0@S @e @l @m@=@| @4@  @ +B @@ A) p@ @ AB A* @ ,@l &B@ HAz  @ @6 @a!&BC 'BT @[ @` 8RBg @ @@ A d@, A @u @ @ 4A `@ @RB `@1 @E @M <A@\ @f @p @@@B u @ p@ @9 A! @ Ъ@ HRB @1@ A}@ PA<@PRB Ac A( @7 &B @nF AT @@@b |AVp  @w @@ 8@, 0@ p@ P@ @$ A5 @latencytopcrti.scrt1x.ocrt1.sfsrx.svalues-Xa.cvalues-xpg6.clatencytop.ccheck_opt_dupprint_usagesignal_handlerto_intdisplay.cfill_spaceget_time_stringprint_statisticsprint_sysglobalprint_current_modeprint_empty_process_barprint_processprint_taskbar_processprint_taskbar_threadprint_threadprint_hintget_plistprint_helpprint_titleon_resizedwrapper.crec_get_valueaggwalk_callaggwalk_namedaggwalk_syncaggwalkdrop_handlerklog.cprint_procprint_statstat.csobj_id_hashsobj_id_equallookup_sobjcheck_processcheck_threadfree_statclear_statupdate_stat_entryfind_causenew_collectionget_stat_csort_idplist_createcount_threadstlist_createtable.cfree_causefree_dmacronew_causedisable_causeread_line_from_memparse_config_cmdparse_sym_transparse_dmacrogenscriptparse_configutil.clatencytop_wrap.ocrtn.sstrleninitscr32g_sequence_freelt_stat_list_has_item_exitlt_table_get_cause_namedtrace_closelt_stat_proc_list_freedtrace_handle_droplt_sort_by_max_descwgetchdtrace_errmsgg_ptr_array_foreachlt_dtrace_workw32attronlt_get_proc_fieldg_hash_table_destroylt_stat_update_sobjwrefreshfprintfg_list_freeg_list_sortlt_stat_list_get_maxlt_table_deinitsignal__iobstrtokstrtollt_stat_update_causelatencytop_d_startfopen_DYNAMIClt_klog_set_log_levelg_configfreadwbkgdlt_display_deinitg_hash_table_size_environgettimeofdaylt_display_loopdtrace_program_execnoecholt_malloc_edatadtrace_aggregate_snaplatencytop_d_enddtrace_aggregate_walk__xpg4wclear__xpg6_finig_hash_table_new_fullasctime_rg_hash_table_lookup__fsrlatencytop_trans_endgetpid_lib_versionvsnprintflt_stat_list_freelt_klog_writelt_table_cause_from_namelt_stat_free_all__fsr_init_valuelt_klog_deinitdtrace_gofwritelt_klog_set_log_filefseeklt_dtrace_init__longdouble_usedendwinlt_table_append_transdtrace_errnog_ptr_array_freew32attrsetlatencytop_trans_startmaindtrace_setoptg_sequence_newbasenamefcloseunlinkdtrace_program_fcompileg_str_hashtmpfilegetmaxx__ctypestrncpygetmaxyg_str_equallt_stat_proc_list_createg_string_freelt_gpipe_readfdlt_klog_logg_hash_table_foreach_removelt_strdupkeypadlt_display_initlt_display_errorg_sequence_appenddtrace_statusg_sequence_foreachstrchrlt_file_existg_hash_table_foreachdtrace_lookup_by_addrlt_sort_by_count_desc_etextdtrace_aggregate_clearlt_dtrace_collectsubwing_ptr_array_addwerasestart_colordtransdtrace_stoplt_update_stat_valuecurs_settimelt_stat_proc_get_nthreadslt_zallocatexitlt_dtrace_deinit___Argvlt_time_strstrncmpg_assertion_message_exprg_string_newlt_drop_detectedcallocpipeoptarglt_stat_list_get_gtotaldtrace_openlt_gpipe_deinitlt_stat_list_get_countlt_gpipe_initlt_stat_list_get_reasong_hash_table_newftelllt_table_cause_from_stackmemsetoptind_PROCEDURE_LINKAGE_TABLE_g_hash_table_insertmemmovelt_millisecondmvwprintwinit_pairnonlg_string_appendlt_stat_updatelt_stat_clear_alllt_klog_initgetopt_longw32attroffstdscr_memcpylt_gpipe_breaklt_stat_proc_get_namelt_sort_by_total_desclt_sort_by_avg_descg_direct_equal__environ_locklt_table_initg_direct_hashlt_check_nullstrcmpg_hash_table_get_valueslt_stat_list_get_sumg_ptr_array_newselectcbreaklt_stat_list_createlt_table_get_cause_flaggmtime_rlibcurses.so.1SUNW_1.1SUNWprivate_1.1libdtrace.so.1libc.so.1SUNW_1.22SUNW_0.7libglib-2.0.so.0 0'=  qN    qN  . y8 '=  (= B qN  cp oj !"#S%&f()*+,-./012bI\3456MW89:;<=>?@AK]sUO{exzgHRBPB[8RB@RB@B B B( B0 B^8 B>@ BTH BP BX B` Bh Bp Bx B B B\ B B By B B Bz B B B BO B$ B B| Bg!B!B!B-!B !B(!B]0!BZ8!Bv@!BH!B P!B4X!BK`!Bxh!Bqp!Bx!B<!B!B !BR!BY!B!BH!BW!BU!B,!BE!BM!B !Bl!B0!B2!Bt"B~"B"BX"B` "B7("B0"B8"B@"BiH"BVP"BpX"B`"B9h"Bp"Bex"Bn"B"B"B"B&"Bw"Bk"B"B"BS"B"B"B{"Bm"B"B#"B#B #BN#Bb#B) #B(#B0#B8#B@#BH#B8P#BX#B`#Bh#BFp#B'(d@tpa@od@kd@hha@fc@lc@cc@scheck_opt_duppj@Pj@ j@i@i@i@Pi@i@h@h@(n@m@m@m@m@hm@j@Pm@(m@m@l@l@l@l@`l@0l@l@l@k@@o@(o@o@n@n@n@Pn@@@.AeA?<@Y@lt_klog_loglt_klog_writelt_klog_set_log_filetlist_createcount_threadslt_stat_list_get_reasonfind_causeclear_statcheck_threadlookup_sobjv@xv@pv@hv@`v@Xv@u@u@sobj_id_equalsobj_id_hashlt_table_cause_from_stacklt_table_initparse_dmacroread_line_from_memnew_causefree_dmacrofree_causelt_sort_by_avg_desclt_sort_by_count_desclt_sort_by_max_desclt_sort_by_total_desclt_check_null%s low%s featureoutput-log-filet:o:k:hf:l:c:s:Collecting data for %d seconds... Unable to initialize dtrace. Unable to load configuration table. Copyright (c) 2008-2009, Intel Corporation.LatencyTOP for Solaris, version 1.0%s %s Unknown option(s): Cannot write to log file: %s Process/process group ID must be greater than 0: %s Invalid select option: %s pgid=pid=Configuration name is too long. Invalid log interval: %s Unknown feature: %s sobjschedfilterno,Log file name is too long: %s Invalid log level: %s Invalid refresh interval: %s selectconfiglog-periodhelpkernel-log-levelintervalqOptions: -h, --help Print this help. -t, --interval TIME Set refresh interval to TIME. Valid range [1...60] seconds, default = 5 -o, --output-log-file FILE Output kernel log to FILE. Default = /var/log/latencytop.log -k, --kernel-log-level LEVEL Set kernel log level to LEVEL. 0(default) = None, 1 = Unmapped, 2 = Mapped, 3 = All. -f, --feature [no]feature1,[no]feature2,... Enable/disable features in LatencyTOP. [no]filter: Filter large interruptible latencies, e.g. sleep. [no]sched: Monitors sched (PID=0). [no]sobj: Monitors synchronization objects. [no]low: Lower overhead by sampling small latencies. -l, --log-period TIME Write and restart log every TIME seconds, TIME >= 60 -s --select [ pid= | pgid= ] Monitor only the given process or processes in the given process group. Usage: %s [option(s)] use '%s -h' for details. Usage: %s [option(s)], %ssizeof (errmsg)/sizeof (errmsg[0]) == (int)LT_CMDOPT__LAST../common/latencytop.c-s is set more than once with different values.-f [no]low is set more than once with different values.-f [no]sobj is set more than once with different values.-f [no]sched is set more than once with different values.-f [no]filter is set more than once with different values.-c is set more than once.-l is set more than once with different values.-k is set more than once with different values.-o is set more than once.-t is set more than once with different values.%s _%d%.1f %%q - Exit.Tracing synchronization objects is disabled.Switching mode is not available for '-f low'.Press q to quit.Please resize it to 80x24 or larger.Terminal size is too small.r Cause Count Average Maximum PercentPress any key to continue...h - Show this help.3 - Show list by synchronization objects.2 - Show list of special entries.1 - Show list by causes.p - Sort by percent.m - Sort by maximum.a - Sort by average.c - Sort by count.t - Toggle process/thread mode.r - Refresh.> - Move to next process/thread.< - Move to previous process/thread.These single-character commands are available:Copyright (c) 2008-2009, Intel Corporation.LatencyTOP for Solaris, version 1.0Use '1', '2', '3' to switch between windows.Use 'c', 'a', 'm', 'p' to change sort criteria.Press 'h' for help.Press 't' to toggle Process/Thread display mode.Press 'r' to refresh immediately.Press 'q' to exit.Press '<' or '>' to switch between processes.Process %s (%i), LWP %d-><%d><-Total: %sProcess %s (%i), %d threadsNo process/thread data is availableView: %c%cSystem wide latencies--- %llu%s%.0e sec%3.1f sec%3.1f msec%3.1f usec%3.1f nsecmaxsumdtrace_stop failed: %s Failed to sort aggregate: %s Failed to snap aggregate: %s Failed when getting status: %s Failed to run D script. Failed to enable probes. Failed to compile D script. Could not copy D script, fwrite() failed Cannot create tmp file Failed to set option ENABLE_LOW_OVERHEAD. ENABLE_LOW_OVERHEADFailed to set option TRACE_PGID. TRACE_PGID=%uFailed to set option TRACE_PID. TRACE_PID=%uFailed to set option ENABLE_SCHED. ENABLE_SCHEDFailed to set option ENABLE_SYNCOBJ. ENABLE_SYNCOBJFailed to set option ENABLE_FILTER. ENABLE_FILTERdefineCannot install DTrace handle: %s Cannot open dtrace library: %s Drop: %s countsyncnamedcalllt_%s`%s %ld, "%s"TOTAL, COUNT, MAX, PID, KSTACK # Statistics PID, CMD # List of processes LatencyTOP for Solaris, version 1.0# Log generated at %s by %s klog_table != NULL && proc_table != NULLastrlen(filename) < sizeof (klog_filename)../common/klog.c%lld, %lld, %lld, %s %-8ld "%s" ShuttleUser_PI/proc/%u/lwp/%ucount == retret != NULLlist->lt_sl_entries[i]->lt_se_string != NULLSyscall: %sThread %dSYSTEMcause_priority != NULLcause_id != NULLstat != NULLstat->lt_sc_parent->lt_sc_level == LT_LEVEL_PROCESSstat->lt_sc_parent != NULL/proc/%u%s: 0x%llXUserSemaCVRWLockMutexNonea != NULL && b != NULLid != NULL../common/stat.cNothingmodule_func != NULL && cause_id != NULL && priority != NULLcause->lt_c_cause_id == INVALID_CAUSELoaded configuration from %s Unable to read configuration file. Unable to open configuration file. rInvalid configuration line: %s No space after flag char: %s Configuration line too long. parser->lt_pr_dmacro != NULLcause != NULL%s %s TRANSLATE(%s, %s, "%s", %d) Unknown command: %s Invalid command format: %s disable_causemem != NULL && line != NULL && index != NULLname != NULLd->lt_dm_macro != NULLcause != NULL && cause->lt_c_name != NULL../common/table.c/proc/%d/psinfoOut of memory! a != NULL && b != NULL0../common/util.c/* */ /* * Copyright (c) 2008-2009, Intel Corporation. * All Rights Reserved. */ #define MAX_TAG 8 #define MAX_STACK 64 #pragma D option aggsize=8m #pragma D option bufsize=16m #pragma D option dynvarsize=16m #pragma D option aggrate=0 #pragma D option stackframes=MAX_STACK /* * Our D script needs to compile even if some of the TRANSLATE probes cannot * be found. Missing probes can be caused by older kernel, different * architecture, unloaded modules etc. */ #pragma D option zdefs #if defined(ENABLE_SCHED) #if defined(TRACE_PID) #define TRACE_FILTER / pid == 0 || pid == TRACE_PID / #define TRACE_FILTER_COND(a) / (pid == 0 || pid == TRACE_PID) && (a) / #elif defined(TRACE_PGID) #define TRACE_FILTER / pid == 0 || curpsinfo->pr_pgid == TRACE_PGID / #define TRACE_FILTER_COND(a) / (pid == 0 || curpsinfo->pr_pgid == TRACE_PGID) && (a) / #else #define TRACE_FILTER #define TRACE_FILTER_COND(a) / (a) / #endif #else /* ENABLE_SCHED */ #if defined(TRACE_PID) #define TRACE_FILTER / pid == TRACE_PID / #define TRACE_FILTER_COND(a) / (pid == TRACE_PID) && (a) / #elif defined(TRACE_PGID) #define TRACE_FILTER / curpsinfo->pr_pgid == TRACE_PGID / #define TRACE_FILTER_COND(a) / (curpsinfo->pr_pgid == TRACE_PGID) && (a) / #else #define TRACE_FILTER / pid != 0 / #define TRACE_FILTER_COND(a) / (pid != 0) && (a) / #endif #endif /* ENABLE_SCHED */ /* Threshold to filter WAKEABLE latencies. */ #define FILTER_THRESHOLD 5000000 /* From thread.h */ #define T_WAKEABLE 2 /* * This array is used to store timestamp of when threads are enqueued * to dispatch queue. * self-> is not accessible when enqueue happens. */ unsigned long long lt_timestamps[int, int]; self unsigned int lt_is_block_wakeable; self unsigned long long lt_sleep_start; self unsigned long long lt_sleep_duration; self unsigned long long lt_sch_delay; self unsigned int lt_counter; /* only used in low overhead */ self unsigned long long lt_timestamp; /* only used in low overhead */ self unsigned int lt_stackp; self unsigned int lt_prio[int]; self string lt_cause[int]; this unsigned int priority; this string cause; /* * Clean up everything, otherwise we will run out of memory. */ proc:::lwp-exit { lt_timestamps[curpsinfo->pr_pid, curlwpsinfo->pr_lwpid] = 0; self->lt_sleep_start = 0; self->lt_is_block_wakeable = 0; self->lt_counter = 0; self->lt_timestamp = 0; /* * Workaround: no way to clear associative array. * We have to manually clear 0 ~ (MAX_TAG-1). */ self->lt_prio[0] = 0; self->lt_prio[1] = 0; self->lt_prio[2] = 0; self->lt_prio[3] = 0; self->lt_prio[4] = 0; self->lt_prio[5] = 0; self->lt_prio[6] = 0; self->lt_prio[7] = 0; self->lt_cause[0] = 0; self->lt_cause[1] = 0; self->lt_cause[2] = 0; self->lt_cause[3] = 0; self->lt_cause[4] = 0; self->lt_cause[5] = 0; self->lt_cause[6] = 0; self->lt_cause[7] = 0; } #if !defined(ENABLE_LOW_OVERHEAD) /* * Log timestamp when a thread is taken off the CPU. */ sched::resume:off-cpu TRACE_FILTER_COND(curlwpsinfo->pr_state == SSLEEP) { self->lt_sleep_start = timestamp; self->lt_is_block_wakeable = curthread->t_flag & T_WAKEABLE; lt_timestamps[curpsinfo->pr_pid, curlwpsinfo->pr_lwpid] = self->lt_sleep_start; } /* * Log timestamp when a thread is put on a dispatch queue and becomes runnable. */ sched:::enqueue /lt_timestamps[args[1]->pr_pid, args[0]->pr_lwpid] != 0/ { lt_timestamps[args[1]->pr_pid, args[0]->pr_lwpid] = timestamp; } /* * Calculate latency when the thread is actually on the CPU. * This is necessary in order to get the right stack. */ this unsigned long long end; this unsigned long long now; sched::resume:on-cpu /self->lt_sleep_start != 0/ { this->end = lt_timestamps[curpsinfo->pr_pid, curlwpsinfo->pr_lwpid]; this->now = timestamp; lt_timestamps[curpsinfo->pr_pid, curlwpsinfo->pr_lwpid] = 0; this->end = (this->end != 0 && this->end != self->lt_sleep_start) ? this->end : this->now; self->lt_sch_delay = this->now - this->end; self->lt_sleep_duration = this->end - self->lt_sleep_start; self->lt_sleep_start = 0; } /* * Filter: drop all "large" latency when it is interruptible, i.e., sleep() * etc. */ #if defined(ENABLE_FILTER) sched::resume:on-cpu /self->lt_sleep_duration > FILTER_THRESHOLD && self->lt_is_block_wakeable != 0/ { self->lt_sch_delay = 0; self->lt_sleep_duration = 0; self->lt_is_block_wakeable = 0; } #endif /* defined(ENABLE_FILTER) */ /* * Write sleep time to the aggregation. * lt_sleep_duration is the duration between the time when a thread is taken * off the CPU and the time when it is enqueued again. */ sched::resume:on-cpu /self->lt_sleep_duration != 0/ { this->cause = self->lt_stackp > 0 ? self->lt_cause[self->lt_stackp - 1] : ""; this->priority = self->lt_stackp > 0 ? self->lt_prio[self->lt_stackp - 1] : 0; @lt_call_count[pid, tid, stack(), this->cause, this->priority] = count(); @lt_call_sum[pid, tid, stack(), this->cause, this->priority] = sum(self->lt_sleep_duration); @lt_call_max[pid, tid, stack(), this->cause, this->priority] = max(self->lt_sleep_duration); self->lt_is_block_wakeable = 0; /* Clear the flag to avoid leak */ self->lt_sleep_duration = 0; } /* * Write time spent in queue to the aggregation. * lt_sch_delay is the interval between the time when a thread becomes * runnable and the time when it is actually on the CPU. */ sched::resume:on-cpu /self->lt_sch_delay != 0/ { @lt_named_count[pid, tid, "Wait for available CPU"] = count(); @lt_named_sum[pid, tid, "Wait for available CPU"] = sum(self->lt_sch_delay); @lt_named_max[pid, tid, "Wait for available CPU"] = max(self->lt_sch_delay); self->lt_sch_delay = 0; } /* * Probes to track latency caused by spinning on a lock. */ lockstat:::adaptive-spin TRACE_FILTER { @lt_named_count[pid, tid, "Adapt. lock spin"] = count(); @lt_named_sum[pid, tid, "Adapt. lock spin"] = sum(arg1); @lt_named_max[pid, tid, "Adapt. lock spin"] = max(arg1); } lockstat:::spin-spin TRACE_FILTER { @lt_named_count[pid, tid, "Spinlock spin"] = count(); @lt_named_sum[pid, tid, "Spinlock spin"] = sum(arg1); @lt_named_max[pid, tid, "Spinlock spin"] = max(arg1); } /* * Probes to track latency caused by blocking on a lock. */ lockstat:::adaptive-block TRACE_FILTER { @lt_named_count[pid, tid, "#Adapt. lock block"] = count(); @lt_named_sum[pid, tid, "#Adapt. lock block"] = sum(arg1); @lt_named_max[pid, tid, "#Adapt. lock block"] = max(arg1); } lockstat:::rw-block TRACE_FILTER { @lt_named_count[pid, tid, "#RW. lock block"] = count(); @lt_named_sum[pid, tid, "#RW. lock block"] = sum(arg1); @lt_named_max[pid, tid, "#RW. lock block"] = max(arg1); } #if defined(ENABLE_SYNCOBJ) /* * Probes to track latency caused by synchronization objects. */ this int stype; this unsigned long long wchan; this unsigned long long wtime; sched:::wakeup /* * Currently we are unable to track wakeup from sched, because all its LWP IDs * are zero when we trace it and that makes lt_timestamps unusable. */ /args[1]->pr_pid != 0 && lt_timestamps[args[1]->pr_pid, args[0]->pr_lwpid] != 0/ { this->stype = args[0]->pr_stype; this->wchan = args[0]->pr_wchan; /* * We can use lt_timestamps[] here, because * wakeup is always fired before enqueue. * After enqueue, lt_timestamps[] will be overwritten. */ this->wtime = timestamp - lt_timestamps[args[1]->pr_pid, args[0]->pr_lwpid]; @lt_sync_count[args[1]->pr_pid, args[0]->pr_lwpid, this->stype, this->wchan] = count(); @lt_sync_sum[args[1]->pr_pid, args[0]->pr_lwpid, this->stype, this->wchan] = sum(this->wtime); @lt_sync_max[args[1]->pr_pid, args[0]->pr_lwpid, this->stype, this->wchan] = max(this->wtime); } #endif /* defined(ENABLE_SYNCOBJ) */ #else /* !defined(ENABLE_LOW_OVERHEAD) */ /* * This is the low overhead mode. * In order to reduce the number of instructions executed during each * off-cpu and on-cpu event, we do the following: * * 1. Use sampling and update aggregations only roughly 1/100 times * (SAMPLE_TIMES). * 2. Do not track anything other than what is needed for "main" window. * 3. Use as few thread local variables as possible. */ #define SAMPLE_TIMES 100 #define SAMPLE_THRESHOLD 50000000 /* * Log timestamp when a thread is off CPU. */ sched::resume:off-cpu TRACE_FILTER_COND(curlwpsinfo->pr_state == SSLEEP) { self->lt_timestamp = timestamp; #if defined(ENABLE_FILTER) self->lt_is_block_wakeable = curthread->t_flag & T_WAKEABLE; #endif /* defined(ENABLE_FILTER) */ } /* * Calculate latency when a thread is actually on the CPU. */ this int need_skip; sched::resume:on-cpu /self->lt_timestamp != 0/ { self->lt_timestamp = timestamp - self->lt_timestamp; #if defined(ENABLE_FILTER) self->lt_timestamp = (self->lt_timestamp > FILTER_THRESHOLD && self->lt_is_block_wakeable != 0) ? 0 : self->lt_timestamp; self->lt_is_block_wakeable = 0; #endif /* defined(ENABLE_FILTER) */ this->need_skip = (self->lt_counter < (SAMPLE_TIMES - 1) && self->lt_timestamp <= SAMPLE_THRESHOLD) ? 1 : 0; self->lt_timestamp = this->need_skip ? 0 : self->lt_timestamp; self->lt_counter += this->need_skip; } /* * Track large latency first. */ sched::resume:on-cpu /self->lt_timestamp > SAMPLE_THRESHOLD/ { this->cause = self->lt_stackp > 0 ? self->lt_cause[self->lt_stackp - 1] : ""; this->priority = self->lt_stackp > 0 ? self->lt_prio[self->lt_stackp - 1] : 0; @lt_call_count[pid, tid, stack(), this->cause, this->priority] = sum(1); @lt_call_sum[pid, tid, stack(), this->cause, this->priority] = sum(self->lt_timestamp); @lt_call_max[pid, tid, stack(), this->cause, this->priority] = max(self->lt_timestamp); self->lt_timestamp = 0; } /* * If we fall back to this probe, that means the latency is small and counter * has reached SAMPLE_TIMES. */ sched::resume:on-cpu /self->lt_timestamp != 0/ { this->cause = self->lt_stackp > 0 ? self->lt_cause[self->lt_stackp - 1] : ""; this->priority = self->lt_stackp > 0 ? self->lt_prio[self->lt_stackp - 1] : 0; /* Need +1 because lt_counter has not been updated in this cycle. */ @lt_call_count[pid, tid, stack(), this->cause, this->priority] = sum(self->lt_counter + 1); @lt_call_sum[pid, tid, stack(), this->cause, this->priority] = sum((self->lt_counter + 1) * self->lt_timestamp); @lt_call_max[pid, tid, stack(), this->cause, this->priority] = max(self->lt_timestamp); self->lt_timestamp = 0; self->lt_counter = 0; } #endif /* !defined(ENABLE_LOW_OVERHEAD) */ #define TRANSLATE(entryprobe, returnprobe, cause, priority) \ entryprobe \ TRACE_FILTER_COND(self->lt_stackp == 0 || \ (self->lt_stackp < MAX_TAG && \ self->lt_prio[self->lt_stackp - 1] <= priority) ) \ { \ self->lt_prio[self->lt_stackp] = priority; \ self->lt_cause[self->lt_stackp] = cause; \ ++self->lt_stackp; \ } \ returnprobe \ TRACE_FILTER_COND(self->lt_stackp > 0 && \ self->lt_cause[self->lt_stackp - 1] == cause) \ { \ --self->lt_stackp; \ self->lt_cause[self->lt_stackp] = NULL; \ } /* * Syscalls have a priority of 10. This is to make sure that latency is * traced to one of the syscalls only if nothing else matches. * We put this special probe here because it uses "probefunc" variable instead * of a constant string. */ TRANSLATE(syscall:::entry, syscall:::return, probefunc, 10) # # # Copyright (c) 2008-2009, Intel Corporation. # All Rights Reserved. # # LatencyTOP 1.0 configuration # # # Format: # D ... # ;