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
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
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 }