File indexing completed on 2023-05-28 05:10:56 UTC
view on githubraw file Latest commit b4daa243 on 2023-05-28 03:53:22 UTC
b4daa24319 Shre*0001
0002
0003
0004
0005
0006
0007
0008 #include <stdio.h>
0009 #include <stdlib.h>
0010 #include <string.h>
0011 #include <signal.h>
0012 #include <sys/types.h>
0013 #include <unistd.h>
0014 #include <time.h>
0015 #include <unistd.h>
0016
0017
0018 #define rdtscll(val) \
0019 __asm__ __volatile__ ("rdtsc" : "=A" (val))
0020
0021 #define ENABLE_LINE_RECORDING 1
0022
0023 unsigned long long int mytime_() {
0024 unsigned long long int time;
0025
0026 rdtscll(time);
0027 return time ;
0028 }
0029
0030
0031 extern long int bigStackSize;
0032 extern long int smallstacksize_();
0033
0034
0035
0036 #define ARRAY_SIZE 100000
0037 struct event {
0038 int kind;
0039 char *function;
0040 int len;
0041 unsigned long long int time;
0042 int stacksize;
0043 #ifdef ENABLE_LINE_RECORDING
0044 int line;
0045 #endif
0046 };
0047
0048 struct list_node {
0049 struct event array[ARRAY_SIZE];
0050 struct list_node *next;
0051 };
0052 static struct list_node hdcell = { .next = 0 };
0053 static struct list_node *tlcell = &hdcell;
0054 static int cell_index = 0;
0055
0056
0057 static void traverse_event_list(void (*process)(struct event *ev, void *data), void *data) {
0058 struct list_node *c = &hdcell;
0059
0060 while (c) {
0061 int max = c->next ? ARRAY_SIZE : cell_index;
0062 int i;
0063 for (i = 0; i < max; ++i)
0064 process(&c->array[i], data);
0065 c = c->next;
0066 }
0067 }
0068
0069
0070
0071 #if 1
0072 #define profiledebug
0073 #else
0074 #define profiledebug(type) \
0075 printf("%50s %02u %022llu %010lu %li\n", buffer, type, mytime_(), bigStackSize, smallstacksize_());
0076 #endif
0077 enum { BEGIN = 1, END, ENDFWD, BEGINSNAPSHOT, ENDSNAPSHOT, ENDORIG };
0078
0079 int init = 0;
0080 unsigned long long int beginning_of_time = 0;
0081 inline static void profile_real(char *function, int flen, int kind) {
0082 static struct list_node *new = 0;
0083 if (cell_index >= ARRAY_SIZE) {
0084 new = (struct list_node*)calloc(1, sizeof(struct list_node));
0085 tlcell->next = new;
0086 tlcell = new;
0087 new->next = 0;
0088 cell_index = 0;
0089 }
0090 static unsigned long long int time;
0091 time = mytime_();
0092 if (init == 0)
0093 beginning_of_time = time, init = 1;
0094 tlcell->array[cell_index].kind = kind;
0095 tlcell->array[cell_index].function = function;
0096 tlcell->array[cell_index].len = flen;
0097 tlcell->array[cell_index].time = time - beginning_of_time;
0098 tlcell->array[cell_index].stacksize = bigStackSize + smallstacksize_();
0099 #if 0
0100 printf("%016llu %09lu %02hhu ", time-beginning_of_time, bigStackSize + smallstacksize_(), kind);
0101 fwrite(function, 1, flen, stdout);
0102 printf("\n");
0103 #endif
0104 cell_index++;
0105 }
0106
0107 #define declare_profile(suffix,type) \
0108 void profile##suffix##_(char *function, int flen) {\
0109 profile_real(function, flen, type);\
0110 }
0111
0112 declare_profile(begin,BEGIN)
0113 declare_profile(end,END)
0114 declare_profile(endfwd,ENDFWD)
0115 declare_profile(beginsnapshot,BEGINSNAPSHOT)
0116 declare_profile(endsnapshot,ENDSNAPSHOT)
0117 declare_profile(endorig,ENDORIG)
0118
0119 #ifdef ENABLE_LINE_RECORDING
0120 static int current_line_number = 0;
0121
0122 void profileline_(int *line) {
0123 current_line_number = *line;
0124 }
0125 #endif
0126
0127
0128 #define hashtbl_size 4093
0129 struct hash_cell {
0130 char *function;
0131 int len;
0132 } hashtbl[hashtbl_size];
0133
0134 int hashtbl_count;
0135
0136
0137 static inline unsigned int hash(unsigned int u) {
0138 return ((u % hashtbl_size) * 1024 ) % hashtbl_size;
0139 }
0140
0141
0142 static inline unsigned int hash_string(char *string, int flen) {
0143 unsigned int ret = 0x55555555;
0144 while (flen--)
0145 ret *= ((unsigned char)*string++ * hashtbl_size);
0146 return hash(ret);
0147 }
0148
0149
0150 #define min(a,b) (a < b ? a : b)
0151
0152
0153 static int get(char *function, int flen) {
0154 int h = hash_string(function, flen);
0155 while (hashtbl[h].function) {
0156 if (strncmp(hashtbl[h].function, function, min(flen, hashtbl[h].len)) == 0)
0157 break;
0158 h = hash(h);
0159 }
0160 hashtbl[h].function = function;
0161 hashtbl[h].len = flen;
0162 return h;
0163 }
0164
0165
0166 static inline void fwrite_int(FILE *f, int i) {
0167 fwrite(&i, sizeof(int), 1, f);
0168 }
0169 static inline void fwrite_llint(FILE *f, unsigned long long int i) {
0170 fwrite(&i, sizeof(unsigned long long int), 1, f);
0171 }
0172 static inline void fwrite_string(FILE *f, char *str, int len) {
0173 fwrite_int(f, len);
0174 fwrite(str, (unsigned int) len, 1, f);
0175 }
0176
0177
0178 static void add_event_to_hashtable(struct event *ev, void *data);
0179 static void build_hashtable() {
0180
0181
0182 memset(hashtbl, 0, sizeof(struct hash_cell)*hashtbl_size);
0183
0184 traverse_event_list(add_event_to_hashtable, 0);
0185
0186 hashtbl_count = 0;
0187 int i;
0188 for (i=0; i < hashtbl_size; ++i)
0189 if (hashtbl[i].function)
0190 hashtbl_count++;
0191 }
0192 static void add_event_to_hashtable(struct event *ev, void *data) {
0193 int h = get(ev->function, ev->len);
0194 }
0195
0196
0197
0198 struct print_args {
0199 FILE *prof;
0200 struct event **stack;
0201 int *stack_counter;
0202 };
0203 static void print_an_event(struct event *ev, void *data);
0204 void printprofile_() {
0205 int i = 0;
0206 FILE *prof = fopen("tapenade.prof", "w");
0207 if (!prof) {
0208 perror("Can't open tapenade.prof");
0209 exit(1);
0210 }
0211
0212
0213
0214
0215 build_hashtable();
0216
0217
0218 fseek(prof, 0, SEEK_SET);
0219
0220
0221 fwrite_int(prof, hashtbl_count);
0222 for (i=0; i < hashtbl_size; ++i)
0223 if (hashtbl[i].function) {
0224 fwrite_int(prof, i);
0225 char *string = hashtbl[i].function;
0226 int string_length = hashtbl[i].len;
0227 fwrite_string(prof, string, string_length);
0228 }
0229
0230
0231 struct list_node *c = &hdcell;
0232 struct event *stack[1000];
0233 int stack_counter = -1;
0234 struct print_args args = {
0235 .prof = prof,
0236 .stack = stack,
0237 .stack_counter = &stack_counter
0238 };
0239 traverse_event_list(print_an_event, &args);
0240
0241
0242
0243 for (i=stack_counter; i>-1;i--) {
0244 struct event *cur = stack[i];
0245 int h = get(cur->function, cur->len);
0246 fwrite_int(prof, h);
0247 fwrite_int(prof, 2);
0248 fwrite_llint(prof, cur->time);
0249 fwrite_int(prof, cur->stacksize);
0250 }
0251 fclose(prof);
0252 }
0253 void halt_();
0254
0255 static void print_an_event(struct event *ev, void *data) {
0256 struct print_args *args = (struct print_args*)data;
0257 static unsigned long long int last_time = 0;
0258
0259 int h = get(ev->function, ev->len);
0260
0261 switch (ev->kind) {
0262 case 1:
0263 *(args->stack_counter) += 1;
0264 args->stack[*(args->stack_counter)] = ev;
0265 break;
0266 case 2:
0267 *(args->stack_counter) -= 1;
0268 break;
0269 }
0270
0271 if (last_time && ev->time <= last_time) {
0272 printf("Erreur time <= last_time: %llu <= %llu\n", time, last_time);
0273 halt_();
0274 }
0275 fwrite_int(args->prof, h);
0276 fwrite_int(args->prof, ev->kind);
0277 fwrite_llint(args->prof, ev->time);
0278 fwrite_int(args->prof, ev->stacksize);
0279 last_time = ev->time;
0280 }
0281
0282 #include <signal.h>
0283 void halt_() {
0284 kill(getpid(), SIGTRAP);
0285 }