From: Maynard J. <may...@us...> - 2007-11-19 23:21:24
|
Update of /cvsroot/oprofile/oprofile/opjitconv In directory sc8-pr-cvs3.sourceforge.net:/tmp/cvs-serv27470/opjitconv Modified Files: Tag: JIT_SUPPORT opjitconv.c Log Message: Reverse order of finding JIT dumpfiles and anon sample dirs Index: opjitconv.c =================================================================== RCS file: /cvsroot/oprofile/oprofile/opjitconv/Attic/opjitconv.c,v retrieving revision 1.1.2.10 retrieving revision 1.1.2.11 diff -u -p -d -r1.1.2.10 -r1.1.2.11 --- opjitconv.c 18 Nov 2007 16:53:08 -0000 1.1.2.10 +++ opjitconv.c 19 Nov 2007 23:19:57 -0000 1.1.2.11 @@ -20,6 +20,8 @@ #include <bfd.h> #include <dlfcn.h> +#include <dirent.h> +#include <fnmatch.h> #include <errno.h> #include <fcntl.h> #include <limits.h> @@ -35,9 +37,10 @@ #define OP_JIT_CONV_NO_DUMPFILE 1 -#define OP_JIT_CONV_NO_MATCHING_ANON_SAMPLES 2 -#define OP_JIT_CONV_NO_JIT_RECS_IN_DUMPFILE 3 -#define OP_JIT_CONV_ALREADY_DONE 4 +#define OP_JIT_CONV_NO_ANON_SAMPLES 2 +#define OP_JIT_CONV_NO_MATCHING_ANON_SAMPLES 3 +#define OP_JIT_CONV_NO_JIT_RECS_IN_DUMPFILE 4 +#define OP_JIT_CONV_ALREADY_DONE 5 struct op_jitdump_info { void * dmp_file; @@ -143,13 +146,17 @@ static int op_jit_convert(struct op_jitd /* * Front-end processing from this point to end of the source. * From main(), the general flow is as follows: - * ->Find all JIT *.dump files. If we find at least one, - * then for each JIT dump file, do: - * ->Find matching anonymous samples directory - * ->mmap the JIT dump file and create ELF file if necessary - * by calling op_jit_convert + * 1. Find all anonymous samples directories + * 2. Find all JIT dump files + * 3. For each JIT dump file: + * 3.1 Find matching anon samples dir (from list retrieved in step 1) + * 3.2 mmap the JIT dump file + * 3.3 Call op_jit_convert to create ELF file if necessary */ +/* Callback function used for get_matching_pathnames() call to obtain + * matching path names. + */ static void get_pathname(char const * pathname, void * name_list) { struct list_head * names = (struct list_head *) name_list; @@ -158,15 +165,6 @@ static void get_pathname(char const * pa list_add(&pn->neighbor, names); } - -static char const * get_first_pathname(struct list_head const * path_names) -{ - if (list_empty(path_names)) - return NULL; - return list_entry(path_names->next, struct pathname, neighbor)->name; -} - - static void delete_pathname(struct pathname * pname) { free(pname->name); @@ -216,6 +214,20 @@ out: return rc; } +static char const * find_anon_dir_match(struct list_head * anon_dirs, + char const * proc_id) +{ + struct list_head * pos; + char match_filter [10]; + snprintf(match_filter, 10, "*/%s.*", proc_id); + list_for_each(pos, anon_dirs) { + struct pathname * anon_dir = + list_entry(pos, struct pathname, neighbor); + if (!fnmatch(match_filter, anon_dir->name, 0)) + return anon_dir->name; + } + return NULL; +} /* Look for an anonymous samples directory that matches the process ID * given by the passed JIT dmp_pathname. If none is found, it's an error @@ -223,9 +235,10 @@ out: * the user does --reset. If we do find the matching samples directory, * we create an ELF file (<proc_id>.jo) and place it in that directory. */ -static int process_jit_dumpfile(char const * session_dir, - char const * dmp_pathname, unsigned long long start_time, - unsigned long long end_time) +static int process_jit_dumpfile(char const * dmp_pathname, + struct list_head * anon_sample_dirs, + unsigned long long start_time, + unsigned long long end_time) { int result_dir_length, proc_id_length; int rc = OP_JIT_CONV_OK; @@ -234,14 +247,8 @@ static int process_jit_dumpfile(char con time_t dumpfile_modtime; struct op_jitdump_info dmp_info; char * elf_file = NULL; - char const * anon_dir; - LIST_HEAD(path_names); char * proc_id = NULL; - char const * samples_subdir = "/samples/current"; - char anon_dir_filter[30]; - int samples_dir_len = strlen(session_dir) + strlen(samples_subdir); - char samples_dir[samples_dir_len + 1]; - + char const * anon_dir; char const * dumpfilename = rindex(dmp_pathname, '/'); verbprintf(debug, "Processing dumpfile %s\n", dmp_pathname); if (dumpfilename) { @@ -262,18 +269,12 @@ chk_proc_id: rc = OP_JIT_CONV_FAIL; goto out; } - sprintf(samples_dir, "%s%s", session_dir, samples_subdir); - snprintf(anon_dir_filter, 30, "*/{dep}/{anon:anon}/%s*", proc_id); - if ((get_matching_pathnames(&path_names, get_pathname, samples_dir, - anon_dir_filter, - MATCH_DIR_ONLY_RECURSION) < 0) - || (path_names.next == &path_names)) { + if (!(anon_dir = find_anon_dir_match(anon_sample_dirs, proc_id))) { printf("Possible error: No matching anon samples for %s\n", dmp_pathname); rc = OP_JIT_CONV_NO_MATCHING_ANON_SAMPLES; goto free_res1; } - anon_dir = get_first_pathname(&path_names); if ((rc = mmap_jitdump(dmp_pathname, &dmp_info)) == OP_JIT_CONV_OK) { char * anon_path_seg = rindex(anon_dir, '/'); @@ -281,7 +282,7 @@ chk_proc_id: printf("opjitconv: Bad path for anon sample: %s\n", anon_dir); rc = OP_JIT_CONV_FAIL; - goto free_res1; + goto free_res2; } result_dir_length = ++anon_path_seg - anon_dir; elf_file = xmalloc(result_dir_length + @@ -299,7 +300,7 @@ chk_proc_id: if (rc < 0) { perror("opjitconv:fstat on .jo file"); rc = OP_JIT_CONV_FAIL; - goto free_res2; + goto free_res3; } if (dmp_info.dmp_file_stat.st_mtime > dmp_info.dmp_file_stat.st_ctime) @@ -314,64 +315,66 @@ chk_proc_id: if (!(jo_file_stat.st_ctime < dumpfile_modtime || jo_file_stat.st_mtime < dumpfile_modtime)) { rc = OP_JIT_CONV_ALREADY_DONE; - goto free_all_res; + goto free_res3; } create_elf: verbprintf(debug, "Converting %s to %s\n", dmp_pathname, elf_file); rc = op_jit_convert(dmp_info, elf_file, start_time, end_time); - free_all_res: - delete_path_names_list(&path_names); - munmap(dmp_info.dmp_file, dmp_info.dmp_file_stat.st_size); -free_res2: + free_res3: free(elf_file); + free_res2: + munmap(dmp_info.dmp_file, dmp_info.dmp_file_stat.st_size); } -free_res1: + free_res1: free(proc_id); -out: - + out: return rc; } - -/* FIXME: we must do it in the reverse way, get all sample filename which - * can potentially match a jit dump (matching *{anon:anon}*), get all - * jitdump, for each jitdump find in the previous set of sample filename the - * correspondig samples file for this dump. Actually the problem is we call - * create_file_list() one per dump which is costly and does not scale, it's - * f(NM) ops with N == number of dumps, M number of samples files. Doing - * it in the other way is already better: f(M) + f(N*N), and even if we get - * scaling problem with the f(N*N) we will just need to hash the set of sample - * filenames to retrieve one in f(1) and get a f(N) + f(M) total processing - * ops. - */ static int op_process_jit_dumpfiles(char const * session_dir, unsigned long long start_time, unsigned long long end_time) { struct list_head * pos1, * pos2; + int rc = OP_JIT_CONV_OK; char jitdumpfile[128]; char const * jitdump_dir = "/var/lib/oprofile/jitdump/"; - int rc = 0; - LIST_HEAD(path_names); + LIST_HEAD(jd_fnames); + char const * anon_dir_filter = "*/{dep}/{anon:anon}/[0-9]*.*"; + LIST_HEAD(anon_dnames); + char const * samples_subdir = "/samples/current"; + int samples_dir_len = strlen(session_dir) + strlen(samples_subdir); + char samples_dir[samples_dir_len + 1]; - if ((rc = get_matching_pathnames(&path_names, get_pathname, + sprintf(samples_dir, "%s%s", session_dir, samples_subdir); + if ((get_matching_pathnames(&anon_dnames, get_pathname, + samples_dir, anon_dir_filter, + MATCH_DIR_ONLY_RECURSION) < 0) + || (anon_dnames.next == &anon_dnames)) { + rc = OP_JIT_CONV_NO_ANON_SAMPLES; + goto out; + } + + if ((rc = get_matching_pathnames(&jd_fnames, get_pathname, jitdump_dir, "*.dump", NO_RECURSION)) < 0) goto out; - if (path_names.next == &path_names) + if (jd_fnames.next == &jd_fnames) { rc = OP_JIT_CONV_NO_DUMPFILE; + goto out; + } /* get_matching_pathnames returns only filename segment when * NO_RECURSION is passed, so below, we add back the JIT * dump directory path to the name. */ - list_for_each_safe(pos1, pos2, &path_names) { + list_for_each_safe(pos1, pos2, &jd_fnames) { struct pathname * dmpfile = list_entry(pos1, struct pathname, neighbor); bzero(jitdumpfile, 128); strcat(jitdumpfile, jitdump_dir); strcat(jitdumpfile, dmpfile->name); - rc = process_jit_dumpfile(session_dir, jitdumpfile, + rc = process_jit_dumpfile(jitdumpfile, &anon_dnames, start_time, end_time); if (rc == OP_JIT_CONV_FAIL) { verbprintf(debug, "JIT convert error %d\n", rc); @@ -379,11 +382,11 @@ static int op_process_jit_dumpfiles(char } delete_pathname(dmpfile); } -out: + delete_path_names_list(&anon_dnames); + out: return rc; } - int main(int argc, char ** argv) { unsigned long long start_time, end_time; |