📄 table_string.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 + -