📄 ptt_contention.c
字号:
/* Copyright (C) 2004,2005,2006 Bull S.A. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */#if HAVE_CONFIG_H#include <config.h>#endif#include <stdarg.h>#include <stdlib.h>#include <string.h>#include "types.h"#include "modules.h"#include "glib_hash.h"/*#define ADD_TIME(obj, thread_id, time, key, type) ({ \ if (thread_id != 0) \ sprintf (key_ob, "%-18.18s%-9s %-*s", (thread_id), (obj), \ MAX_ALIAS_LEN, (key)); \ else sprintf (key_ob, "%-9s %-18s", (obj), (key)); \ objects.insert (key_ob, (time), (type)); \})*/#define ADD_TIME(obj, thread_id, time, key, type) ({ \ if (thread_id != 0) \ sprintf (key_ob, "#thread %-*.*s - %-9s %-*s", MAX_ALIAS_LEN, \ MAX_ALIAS_LEN, (thread_id), (obj), MAX_ALIAS_LEN, (key)); \ else sprintf (key_ob, "%-9s %-18s", (obj), (key)); \ objects.insert (key_ob, (time), (type)); \})#define ADD_THREAD_TIME(time, type) \ ADD_TIME ("thread", 0, (time), list_name[0], (type))#define ADD_OBJECT_TIME(key, time, type) \ ADD_TIME ((key), list_name[0], (time), list_name[1], (type))extern struct give_name give_name;extern struct read_trace read_trace;extern struct interval interval;extern struct filter filter;extern struct table_string objects;static ptt_header_t head;static int accept_event [EVT_LAST] = {[0 ... EVT_LAST-1] = 1};static void error (char *err, ...) { va_list ap; fprintf(stderr, "Error : "); va_start(ap, err); vfprintf(stderr, err, ap); va_end(ap); fprintf(stderr, "\n"); exit (1);}static void warning (char *err, ...) { va_list ap; fprintf(stderr, "Warning : "); va_start(ap, err); vfprintf(stderr, err, ap); va_end(ap); fprintf(stderr, "\n");}static void usage () { fprintf (stderr, "ptt_content [options] input_file\n" " -a alias_file : use alias to describe objects\n" " -c : display contention time per couple [thread - NPTL object]\n" " -z start:end : event filter\n" " -Z start:end : time filter\n"); exit (1);}int main (int argc, char ** argv) { extern char *optarg; extern int optind, optopt; const char * optstring = "+ha:z:Z:c"; signed char c; int interval_mode = INT_NULL; unsigned long long itv_min = 0, itv_max = 0; ptt_event_t event, last_event; ptt_timestamp_t time, last_time; pid_t pid; int ret; char *alias_file = NULL; long long list_longlong [PTT_MAXARG]; int list_int [PTT_MAXARG]; unsigned int list_uint [PTT_MAXARG]; char *list_name [PTT_MAXARG+1]; /* +1: array is NULL terminated */ char **last_list_name = list_name; ptt_timestamp_t global_wait = 0; ptt_timestamp_t init_time = 0, end_time = 0, elapsed = 0; int first_event = 1; char key_ob[80]; int couple = 0; while ((c = getopt (argc, argv, optstring)) != EOF) { switch (c) { case 'a': alias_file = optarg; continue; case 'c': couple = 1; continue; case 'z': case 'Z': if (optarg[0] == ':') { itv_min = 0; if (!*(optarg+1)) { warning ("':' is not an interval"); continue; } itv_max = atoll (optarg+1); } else { itv_min = atoi (strsep (&optarg ,":")); if (!optarg) error ("missing `:' in %c\n", c); if (optarg[0] == 0) itv_max = -1LL; else itv_max = atoll (strsep (&optarg ,":")); } if (c == 'z') interval_mode = INT_EVT; else interval_mode = INT_TIME; continue; case 'h': usage (argv[0]); continue; case '?': warning ("Unknow option -%c", optopt); break; default: warning ("Unknow option -%c", c); break; } } if (argc - optind < 1) { usage(); return 1; } /* init modules */ ret = give_name.init (alias_file); if (ret < 0) return -ret; ret = interval.init (interval_mode, &itv_min, &itv_max); if (ret < 0) return -ret; ret = read_trace.init (argv[optind], &head); if (ret < 0) return -ret; ret = filter.init(NULL, accept_event, NULL); if (ret < 0) return ret; ret = objects.init (); if (ret < 0) return -ret; while ((ret = read_trace.read (&pid, &time, &event, list_name, list_int, list_uint, list_longlong)) > 0) { ret = filter.accept (pid, event, list_name); if (ret < 0) error ("filter.accept"); if (first_event) { init_time = time; first_event = 0; } end_time = time; switch (event) { case EVT_THREAD_STATE_WAIT_MUTEX: case EVT_THREAD_STATE_WAIT_BARRIER: case EVT_THREAD_STATE_WAIT_COND: case EVT_THREAD_STATE_WAIT_SEM: case EVT_THREAD_STATE_WAIT: ADD_THREAD_TIME (time, WAIT); break; case EVT_THREAD_STATE_WAKE_MUTEX: case EVT_THREAD_STATE_WAKE_BARRIER: case EVT_THREAD_STATE_WAKE_COND: case EVT_THREAD_STATE_WAKE_SEM: case EVT_THREAD_STATE_WAKE: global_wait += ADD_THREAD_TIME (time, WAKE); break; default: continue; } switch (event) { case EVT_THREAD_STATE_WAIT_MUTEX: ADD_OBJECT_TIME ("mutex", time, WAIT); break; case EVT_THREAD_STATE_WAIT_BARRIER: ADD_OBJECT_TIME ("barrier", time, WAIT); break; case EVT_THREAD_STATE_WAIT_COND: ADD_OBJECT_TIME ("cond-var", time, WAIT); break; case EVT_THREAD_STATE_WAIT_SEM: ADD_OBJECT_TIME ("semaphore", time, WAIT); break; case EVT_THREAD_STATE_WAKE_MUTEX: ADD_OBJECT_TIME ("mutex", time, WAKE); break; case EVT_THREAD_STATE_WAKE_BARRIER: ADD_OBJECT_TIME ("barrier", time, WAKE); break; case EVT_THREAD_STATE_WAKE_COND: ADD_OBJECT_TIME ("cond-var", time, WAKE); break; case EVT_THREAD_STATE_WAKE_SEM: ADD_OBJECT_TIME ("semaphore", time, WAKE); break; default: continue; } } if ((init_time != 0) && (end_time != 0)) elapsed = end_time - init_time; objects.display (global_wait, elapsed, couple); objects.close (); read_trace.close (); if (ret < 0) error ("read"); return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -