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

📄 table_string.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 <stdlib.h>#include <string.h>#include "modules.h"#include "types.h"#include "glib_hash.h"static GHashTable *hash_table;typedef struct s_object_list {    gpointer key;    gpointer value;    struct s_object_list *next;} object_list;typedef struct s_wait {    ptt_timestamp_t total;    ptt_timestamp_t cur_wait;} wait_t;static object_list *thr = NULL;static object_list *obj = NULL;static object_list *throbj = NULL;static int init () {    hash_table = g_hash_table_new (g_str_hash, g_str_equal);    return 0;}static int insert_add (char *name, ptt_timestamp_t value, int type) {    gpointer old_val = g_hash_table_lookup (hash_table, (gpointer)name);    if (old_val == NULL) {        wait_t *w = (wait_t *) malloc (sizeof (wait_t));        if (type == WAKE) return 0;        w->cur_wait = -value;        w->total = 0;        gpointer new_key = (gpointer) strdup (name);        if (new_key == NULL) {            fprintf(stderr, "Error with strdup\n"); return -1;	}        g_hash_table_insert (hash_table, new_key, (gpointer)(w));    }    else {        wait_t *w = (wait_t *)old_val;        if (type == WAIT) {            if (w->cur_wait != 0)                fprintf (stderr, "Error while computing waiting time of %s\n",                         name);            w->cur_wait = -value;            return 0;        }        else {            ptt_timestamp_t res = (w->cur_wait += value);            w->total += w->cur_wait;            w->cur_wait = 0;            return res;        }    }    return -1;}static void display_obj (gpointer key, gpointer value, ptt_timestamp_t global,                         ptt_timestamp_t elapsed, int is_thr) {    char *name = "%-*s: ";    char *time = "%.7gs   ";    char *perc = "%2.1f%%";    char *perc_el = "%2.1f%%";    double val = ((wait_t *)value)->total;    ptt_timestamp_t percent = 1000 * val / global;    ptt_timestamp_t percent_el;    if (elapsed != 0) percent_el = 1000 * val / elapsed;    if (val < 1000000) time = "%.6fs   ";    if (percent < 100) perc = " %1.1f%%";    if (percent == 0) perc = "   0%%";    if (percent == 1000) perc = " 100%%";    if (elapsed != 0) {        if (percent_el < 100) perc_el = " %1.1f%%";        if (percent_el == 0) perc_el = "   0%%";        if (percent_el == 1000) perc_el = " 100%%";    }    printf (name, 10 + MAX_ALIAS_LEN, (char *)key);    printf (time, val / 1000000.0);    printf (perc, (double)percent / 10);    if (is_thr) {        printf ("   ");        if (elapsed != 0) printf (perc_el, (double)percent_el / 10);        else printf ("    ?");        printf (" (elapsed time)");    }    printf ("\n");}static void display_list (object_list *list, ptt_timestamp_t global,                          ptt_timestamp_t elapsed) {    int is_thr = (list == thr) ? 1 : 0;    int is_throbj = (list == throbj) ? 1 : 0;    ptt_timestamp_t glob = global;    char *total;        if (!is_thr) total = "TOTAL                        : %.7gs    100%%\n";    if (is_throbj) total = "TOTAL                                            "                           "         : %.7gs    100%%\n";        if (!is_thr) {        glob = 0;        while (list != NULL) {            glob += ((wait_t *)list->value)->total;            list = list->next;        }        if (glob < 1000000) {            if (!is_throbj)                total = "TOTAL                        : %.6fs    100%%\n";            else                total = "TOTAL                                               "                        "      : %.6fs    100%%\n";        }        if (is_throbj) list = throbj;        else list = obj;    }    while (list != NULL) {        if (!is_throbj)            display_obj (list->key, list->value, glob, elapsed, is_thr);        else            display_obj (list->key + 1, list->value, glob, elapsed, is_thr);        list = list->next;    }    if (!is_thr) printf (total, glob / 1000000.0);}static void create_nptl_object (gpointer key, gpointer value,                                gpointer user_data) {    char *new_key = key + MAX_ALIAS_LEN + 11;    gpointer old_val;    if ((strncmp ((char *)new_key, "mutex", 5) != 0) &&        (strncmp ((char *)new_key, "barrier", 7) != 0) &&        (strncmp ((char *)new_key, "cond-var", 8) != 0) &&        (strncmp ((char *)new_key, "semaphore", 9) != 0)) return;    if ((old_val = g_hash_table_lookup (hash_table, new_key)) == NULL) {        ptt_timestamp_t *val = (ptt_timestamp_t *)                                malloc (sizeof (ptt_timestamp_t));        *val = ((wait_t *)value)->total;        g_hash_table_insert (hash_table, (gpointer)(new_key),                             (gpointer)(val));    }    else *((ptt_timestamp_t *) old_val) += *((ptt_timestamp_t *) value);}static void sort_obj (gpointer key, gpointer value, gpointer user_data) {    object_list *list, *list_prev = NULL;    object_list *new_obj = (object_list *) malloc (sizeof (object_list));    int is_thread = (strncmp ((char *)key, "thread", 6) == 0) ? 1 : 0;    int is_throbj = (((char *)key)[0] == '#') ? 1 : 0;    new_obj->key = key; new_obj->value = value;    if (is_thread) list = thr;    else if (is_throbj) list = throbj;    else list = obj;        while ((list != NULL) && (((wait_t *)(list->value))->total >           *((ptt_timestamp_t *)value))) {        list_prev = list; list = list->next;    }    new_obj->next = list;    if (list_prev == NULL) {        if (is_thread) thr = new_obj;        else if (is_throbj) throbj = new_obj;        else obj = new_obj;    }    else list_prev->next = new_obj;}static void display (ptt_timestamp_t global, ptt_timestamp_t elapsed,                     int couple) {    char *format = "TOTAL     (global contention): %.7gs    100%%\n";    char *format_elapsed = "elapsed time: %.7gs\n";    double wait;    if (elapsed == 0)        format_elapsed = "Can't calculate elapsed time.\n";    else if (elapsed < 1000000) format_elapsed = "elapsed time: %.6fs\n";    printf ("\n");    printf (format_elapsed, (double)elapsed / 1000000.0);        g_hash_table_foreach (hash_table, create_nptl_object, (gpointer)NULL);    g_hash_table_foreach (hash_table, sort_obj, (gpointer)NULL);    printf ("_________________________contention per thread"            "_________________________\n");    display_list (thr, global, elapsed);    wait = (double)global / 1000000.0;    if (wait < 1) format = "TOTAL     (global contention): %.6fs    100%%\n";    printf (format, wait);    printf ("\n___________contention per NPTL object___________\n");    display_list (obj, global, elapsed);    if (couple) {        printf ("\n_____________________contention per thread & NPTL object"                "_____________________\n");        display_list (throbj, global, elapsed);    }    printf ("\n");}static void free_key_val (gpointer key, gpointer value, gpointer user_data) {    if ((strncmp ((char *)key, "mutex", 5) != 0) &&        (strncmp ((char *)key, "barrier", 7) != 0) &&        (strncmp ((char *)key, "cond-var", 8) != 0) &&        (strncmp ((char *)key, "semaphore", 9) != 0)) {        free (key); free (value);    }}static void close () {    object_list *list;    g_hash_table_foreach (hash_table, free_key_val, (gpointer)NULL);    for (list = thr; list != NULL; list = list->next) free (list);    for (list = obj; list != NULL; list = list->next) free (list);}struct table_string objects = {    .init = init,    .insert = insert_add,    .display = display,    .close = close};

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -