📄 export_paje.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#define _XOPEN_SOURCE 600#include <pthread.h>#include <string.h>#include <stdlib.h>#include <limits.h>#include "modules.h"#include "paje.h"#include "glib_hash.h"#define TABLE_SZ 1000extern ptt_event_data_t ptt_event_array[];/* table indexed with fileno pointing at hash tables containing mutex names */static GHashTable *mutex_hash_table[TABLE_SZ] = {[0 ... (TABLE_SZ-1)] = NULL};/* table indexed with fileno pointing at hash tables containing conditional * variable names */static GHashTable *cond_hash_table[TABLE_SZ] = {[0 ... (TABLE_SZ-1)] = NULL};/* value associated with hash tables keys */static int ok = 1;static int show_attr;static int show_state;static int IO_only = 0;/* initialize the export_paje module * header: trace header * display : 0 no thread_attr and no thread_state, * 1 no thread_attr and thread_state * 2 thread_attr and thread_state * returns 0 if ok, < 0 if error */static int init (ptt_header_t *header, int display, int time_division) { switch (display) { case 0 : show_attr = 0; show_state = 0; IO_only = 1; break; case 1 : show_attr = 0; show_state = 1; break; case 2 : show_attr = 1; show_state = 1; break; default : fprintf (stderr, "Incorrect option for paje\n"); return -1; } if (header->file_number != 0) { fprintf (stderr, "Multiple file are unsuported\n"); return -1; } return 0;}/* insert a pair (key, value) in a hash table * key: key to insert * value: value corresponding to the key * hash_table: hash table in which the pair will be inserted */static void copy_pair (gpointer key, gpointer value, gpointer data) { GHashTable *hash_table = data; gpointer new_key; /* copy key */ new_key = (gpointer)strdup(key); if (new_key == NULL) { fprintf(stderr, "Error with strdup\n"); return; } /* insert pair in the table */ g_hash_table_insert (hash_table, new_key, (gpointer)(&ok));}/* initialize a trace file for paje, * copy the parent's hash table of objects if needed * fd : descriptor of the file to initialize * old_fd : descriptor of the parent file * returns 0 if ok, < 0 if error */static int init_file (FILE *fd, FILE *old_fd) { int ret; int file_no, old_file_no; /* copy paje declarations */ ret = fputs (paje_evt_def paje_prog_decl paje_thread_decl, fd); if (ret < 0) return ret; if (show_state) { ret = fputs(paje_thread_state_decl, fd); if (ret < 0) return ret; } if (show_attr) { ret = fputs(paje_thread_attr_decl, fd); if (ret < 0) return ret; } ret = fputs (paje_barrier_decl paje_cond_decl paje_mutex_decl paje_link_decl, fd); if (ret < 0) return ret; /* create hash tables */ file_no = fileno (fd); if (file_no == -1) { fprintf(stderr, "Error with fileno\n"); return -1; } if (file_no >= TABLE_SZ) { fprintf(stderr, "Fileno %d is too big\n", file_no); return -1; } mutex_hash_table[file_no] = g_hash_table_new (g_str_hash, g_str_equal); cond_hash_table[file_no] = g_hash_table_new (g_str_hash, g_str_equal); /* if old_fd is not NULL, copy hash table */ if (old_fd != NULL) { old_file_no = fileno(old_fd); if (old_file_no == -1) { fprintf(stderr, "Error with fileno\n"); return -1; } if (old_file_no >= TABLE_SZ) { fprintf(stderr, "Oldfileno %d is too big\n", old_file_no); return -1; } g_hash_table_foreach (mutex_hash_table[old_file_no], copy_pair, mutex_hash_table[file_no]); g_hash_table_foreach (cond_hash_table[old_file_no], copy_pair, cond_hash_table[file_no]); } return 0;}/* insert a name in a hash table if the name in not already in it * returns if 0 no insertion, 1 if insertion, < 0 if error */static int g_hash_table_insert_no_dup (GHashTable *hash_table, char *name) { gpointer key; if (g_hash_table_lookup (hash_table, name) == NULL) { key = (gpointer) strdup(name); if (key == NULL) { fprintf (stderr, "Error with strdup\n"); return -1; } g_hash_table_insert (hash_table, key, &ok); return 1; } return 0;}#define handle_cond_static_init(name) {\ switch (g_hash_table_insert_no_dup (cond_hash_table[file_no], name)) {\ case 0 : break;\ case 1 :\ fprintf (stderr, "Warning : supposing condition %s has been " \ "initialized statically\n", name);\ create_object_static (name, "cond");\ set_object_state_static (name, "cond_state", "COND_LOCK_FREE");\ break;\ case -1 : return -1;\ default : break;\ }\}#define handle_mutex_static_init(name) {\ switch (g_hash_table_insert_no_dup (mutex_hash_table[file_no], name)) {\ case 0 : break;\ case 1 :\ fprintf (stderr, "Warning : supposing condition %s has been " \ "initialized statically\n", name);\ create_object_static (name, "mutex");\ set_object_state_static (name, "mutex_state", "MUTEX_STATE_FREE");\ set_object_variable_static (name, "mutex_count", 0);\ break;\ case -1 : return -1;\ default : break;\ }\}static int write_paje (FILE *fd, ptt_timestamp_t time, pid_t pid, ptt_event_t event, char **tn, int *ti, unsigned int *tu, long long *tll) { int ret; ptt_event_data_t *evt_data = ptt_event_array + event; long double float_time = (long double)time/1000000.0; int file_no = fileno (fd); if (file_no == -1) { fprintf (stderr, "Error with fileno\n"); return -1; } if (file_no >= TABLE_SZ) { fprintf(stderr, "Fileno %d is too big\n", file_no); return -1; } /* handle initialization */ switch (event) { /* static initialization */ /* conditionnal variable */ case EVT_COND_LOCK_FREE : case EVT_COND_LOCK_REQUIRE : case EVT_COND_LOCK_TAKEN : case EVT_COND_DESTROY : handle_cond_static_init (tn[1]); break; /* conditionnal variable and mutex */ case EVT_COND_MUTEX_FREE : case EVT_COND_MUTEX_REQUIRE : case EVT_COND_MUTEX_TAKEN : handle_mutex_static_init (tn[1]); handle_cond_static_init (tn[2]); break; /* mutex */ case EVT_MUTEX_STATE_FREE : case EVT_MUTEX_STATE_REQUIRE : case EVT_MUTEX_STATE_TAKEN : case EVT_MUTEX_COUNT_DEC : case EVT_MUTEX_COUNT_INC : case EVT_MUTEX_DESTROY : handle_mutex_static_init (tn[1]); break; /* standard initialisation */ case EVT_BARRIER_INIT : create_object (tn[1], "barrier"); set_object_state (tn[1], "barrier_state", "BARRIER_LOCK_FREE"); set_object_variable (tn[1], "barrier_left", tu[0]); break; case EVT_COND_INIT : if (g_hash_table_insert_no_dup (cond_hash_table[file_no], tn[1]) == -1) return -1; create_object (tn[1], "cond"); set_object_state (tn[1], "cond_state", "COND_LOCK_FREE"); break; case EVT_MUTEX_INIT : if (g_hash_table_insert_no_dup (mutex_hash_table[file_no], tn[1])
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -