⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ptt_contention.c

📁 linux下的多线程调试工具
💻 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 + -