opd_sample_files.c

Go to the documentation of this file.
00001 
00012 #include <sys/types.h>
00013  
00014 #include "opd_sample_files.h"
00015 #include "opd_image.h"
00016 #include "opd_printf.h"
00017 #include "opd_events.h"
00018 #include "oprofiled.h"
00019 
00020 #include "op_sample_file.h"
00021 #include "op_file.h"
00022 #include "op_config.h"
00023 #include "op_mangle.h"
00024 #include "op_events.h"
00025 
00026 #include <stdio.h>
00027 #include <stdlib.h>
00028 #include <string.h>
00029 #include <errno.h>
00030 
00032 static LIST_HEAD(lru_list);
00033 
00034 /* this value probably doesn't matter too much */
00035 #define LRU_AMOUNT 1000
00036 static int opd_24_sfile_lru_clear(void)
00037 {
00038     struct list_head * pos;
00039     struct list_head * pos2;
00040     struct opd_24_sfile * sfile;
00041     int amount = LRU_AMOUNT;
00042 
00043     verbprintf(vsfile, "image lru clear\n");
00044 
00045     if (list_empty(&lru_list))
00046         return 1;
00047 
00048     list_for_each_safe(pos, pos2, &lru_list) {
00049         if (!--amount)
00050             break;
00051         sfile = list_entry(pos, struct opd_24_sfile, lru_next);
00052         odb_close(&sfile->sample_file);
00053         list_del_init(&sfile->lru_next);
00054     }
00055 
00056     return 0;
00057 }
00058 
00059 
00060 void opd_24_sfile_lru(struct opd_24_sfile * sfile)
00061 {
00062     list_del(&sfile->lru_next);
00063     list_add_tail(&sfile->lru_next, &lru_list);
00064 }
00065 
00066 
00067 static char * opd_mangle_filename(struct opd_image const * image, int counter,
00068                                   int cpu_nr)
00069 {
00070     char * mangled;
00071     struct mangle_values values;
00072     struct opd_event * event = find_counter_event(counter);
00073 
00074     values.flags = 0;
00075     if (image->kernel)
00076         values.flags |= MANGLE_KERNEL;
00077 
00078     if (separate_thread) {
00079         values.flags |= MANGLE_TGID | MANGLE_TID;
00080         values.tid = image->tid;
00081         values.tgid = image->tgid;
00082     }
00083 
00084     if (separate_cpu) {
00085         values.flags |= MANGLE_CPU;
00086         values.cpu = cpu_nr;
00087     }
00088 
00089     values.event_name = event->name;
00090     values.count = event->count;
00091     values.unit_mask = event->um;
00092 
00093     values.image_name = image->name;
00094     values.dep_name = separate_lib && image->app_name
00095         ? image->app_name : image->name;
00096 
00097     mangled = op_mangle_filename(&values);
00098 
00099     return mangled;
00100 }
00101 
00102 
00103 int opd_open_24_sample_file(struct opd_image * image, int counter, int cpu_nr)
00104 {
00105     char * mangled;
00106     struct opd_24_sfile * sfile;
00107     int err;
00108 
00109     mangled = opd_mangle_filename(image, counter, cpu_nr);
00110 
00111     verbprintf(vsfile, "Opening \"%s\"\n", mangled);
00112 
00113     create_path(mangled);
00114 
00115     sfile = image->sfiles[cpu_nr][counter];
00116     if (!sfile) {
00117         sfile = malloc(sizeof(struct opd_24_sfile));
00118         list_init(&sfile->lru_next);
00119         odb_init(&sfile->sample_file);
00120         image->sfiles[cpu_nr][counter] = sfile;
00121     }
00122 
00123     list_del(&sfile->lru_next);
00124     list_add_tail(&sfile->lru_next, &lru_list);
00125 
00126 retry:
00127     err = odb_open(&sfile->sample_file, mangled, ODB_RDWR,
00128                        sizeof(struct opd_header));
00129 
00130     /* This can naturally happen when racing against opcontrol --reset. */
00131     if (err) {
00132         if (err == EMFILE) {
00133             if (opd_24_sfile_lru_clear()) {
00134                 printf("LRU cleared but odb_open() fails for %s.\n", mangled);
00135                 abort();
00136             }
00137             goto retry;
00138         }
00139 
00140         fprintf(stderr, "oprofiled: open of %s failed: %s\n",
00141                 mangled, strerror(err));
00142         goto out;
00143     }
00144 
00145     fill_header(odb_get_data(&sfile->sample_file), counter, 0, 0,
00146             image->kernel, 0, 0, 0, image->mtime);
00147 
00148 out:
00149     free(mangled);
00150     return err;
00151 }
00152 
00153 
00154 void opd_sync_samples_files(void)
00155 {
00156     struct list_head * pos;
00157     struct opd_24_sfile * sfile;
00158 
00159     list_for_each(pos, &lru_list) {
00160         sfile = list_entry(pos, struct opd_24_sfile, lru_next);
00161         odb_sync(&sfile->sample_file);
00162     }
00163 }
00164 
00165 
00166 void opd_close_image_samples_files(struct opd_image * image)
00167 {
00168     uint i, j;
00169     for (i = 0 ; i < op_nr_counters ; ++i) {
00170         for (j = 0; j < NR_CPUS; ++j) {
00171             if (image->sfiles[j] && image->sfiles[j][i]) {
00172                 odb_close(&image->sfiles[j][i]->sample_file);
00173                 list_del(&image->sfiles[j][i]->lru_next);
00174                 free(image->sfiles[j][i]);
00175                 image->sfiles[j][i] = 0;
00176             }
00177         }
00178     }
00179 }

Generated on 8 Nov 2012 for Oprofile by  doxygen 1.6.1