bug fixed: getEventTime()
[lttv.git] / ltt / branches / poly / ltt / tracefile.c
CommitLineData
6cd62ccf 1#include <stdio.h>
2#include <fcntl.h>
3#include <sys/stat.h>
4#include <sys/types.h>
963b5f2d 5#include <dirent.h>
6cd62ccf 6#include <linux/errno.h>
7
6cd62ccf 8#include "parser.h"
a5dcde2f 9#include <ltt/ltt.h>
10#include "ltt-private.h"
963b5f2d 11#include <ltt/trace.h>
a5dcde2f 12#include <ltt/facility.h>
6cd62ccf 13
963b5f2d 14#define DIR_NAME_SIZE 256
6cd62ccf 15
16/* set the offset of the fields belonging to the event,
17 need the information of the archecture */
40331ba8 18void setFieldsOffset(LttTracefile *tf,LttEventType *evT,void *evD,LttTrace *t);
6cd62ccf 19
20/* get the size of the field type according to the archtecture's
21 size and endian type(info of the archecture) */
40331ba8 22int getFieldtypeSize(LttTracefile * tf, LttEventType * evT, int offsetRoot,
23 int offsetParent, LttField *fld, void *evD, LttTrace* t);
6cd62ccf 24
25/* read a fixed size or a block information from the file (fd) */
26int readFile(int fd, void * buf, size_t size, char * mesg);
963b5f2d 27int readBlock(LttTracefile * tf, int whichBlock);
6cd62ccf 28
29/* calculate cycles per nsec for current block */
963b5f2d 30void getCyclePerNsec(LttTracefile * t);
6cd62ccf 31
32/* reinitialize the info of the block which is already in the buffer */
963b5f2d 33void updateTracefile(LttTracefile * tf);
6cd62ccf 34
35/* go to the next event */
963b5f2d 36int skipEvent(LttTracefile * t);
6cd62ccf 37
6cd62ccf 38
39/*****************************************************************************
40 *Function name
963b5f2d 41 * ltt_tracefile_open : open a trace file, construct a LttTracefile
6cd62ccf 42 *Input params
963b5f2d 43 * t : the trace containing the tracefile
44 * fileName : path name of the trace file
6cd62ccf 45 *Return value
963b5f2d 46 * : a pointer to a tracefile
6cd62ccf 47 ****************************************************************************/
48
963b5f2d 49LttTracefile* ltt_tracefile_open(LttTrace * t, char * fileName)
6cd62ccf 50{
963b5f2d 51 LttTracefile * tf;
52 struct stat lTDFStat; /* Trace data file status */
53 BlockStart a_block_start;
6cd62ccf 54
963b5f2d 55 tf = g_new(LttTracefile, 1);
6cd62ccf 56
57 //open the file
963b5f2d 58 tf->name = g_strdup(fileName);
59 tf->trace = t;
6cd62ccf 60 tf->fd = open(fileName, O_RDONLY, 0);
61 if(tf->fd < 0){
62 g_error("Unable to open input data file %s\n", fileName);
63 }
64
65 // Get the file's status
66 if(fstat(tf->fd, &lTDFStat) < 0){
67 g_error("Unable to get the status of the input data file %s\n", fileName);
68 }
69
70 // Is the file large enough to contain a trace
963b5f2d 71 if(lTDFStat.st_size < sizeof(BlockStart) + EVENT_HEADER_SIZE){
8710c6c7 72 g_print("The input data file %s does not contain a trace\n", fileName);
663bd9ff 73 g_free(tf->name);
74 close(tf->fd);
75 g_free(tf);
8710c6c7 76 return NULL;
6cd62ccf 77 }
78
79 //store the size of the file
80 tf->file_size = lTDFStat.st_size;
963b5f2d 81 tf->block_size = t->system_description->ltt_block_size;
82 tf->block_number = tf->file_size / tf->block_size;
83 tf->which_block = 0;
6cd62ccf 84
85 //allocate memory to contain the info of a block
963b5f2d 86 tf->buffer = (void *) g_new(char, t->system_description->ltt_block_size);
6cd62ccf 87
963b5f2d 88 //read the first block
89 if(readBlock(tf,1)) exit(1);
6cd62ccf 90
91 return tf;
92}
93
6cd62ccf 94
95/*****************************************************************************
963b5f2d 96 *Open control and per cpu tracefiles
6cd62ccf 97 ****************************************************************************/
98
963b5f2d 99void ltt_tracefile_open_cpu(LttTrace *t, char * tracefile_name)
6cd62ccf 100{
963b5f2d 101 LttTracefile * tf;
102 tf = ltt_tracefile_open(t,tracefile_name);
4a6c8e36 103 if(!tf) return;
963b5f2d 104 t->per_cpu_tracefile_number++;
105 g_ptr_array_add(t->per_cpu_tracefiles, tf);
6cd62ccf 106}
107
963b5f2d 108void ltt_tracefile_open_control(LttTrace *t, char * control_name)
6cd62ccf 109{
963b5f2d 110 LttTracefile * tf;
111 LttEvent * ev;
112 LttFacility * f;
cbd41522 113 guint16 evId;
963b5f2d 114 void * pos;
115 FacilityLoad fLoad;
116 int i;
117
118 tf = ltt_tracefile_open(t,control_name);
8710c6c7 119 if(!tf) return;
963b5f2d 120 t->control_tracefile_number++;
121 g_ptr_array_add(t->control_tracefiles,tf);
122
123 //parse facilities tracefile to get base_id
542ceddd 124 if(strcmp(&control_name[strlen(control_name)-10],"facilities") ==0){
963b5f2d 125 while(1){
40331ba8 126 ev = ltt_tracefile_read(tf);
127 if(!ev)return; // end of file
128
129 if(ev->event_id == TRACE_FACILITY_LOAD){
130 pos = ev->data;
963b5f2d 131 fLoad.name = (char*)pos;
47a166fc 132 fLoad.checksum = *(LttChecksum*)(pos + strlen(fLoad.name));
cbd41522 133 fLoad.base_code = *(guint32 *)(pos + strlen(fLoad.name) + sizeof(LttChecksum));
963b5f2d 134
135 for(i=0;i<t->facility_number;i++){
136 f = (LttFacility*)g_ptr_array_index(t->facilities,i);
137 if(strcmp(f->name,fLoad.name)==0 && fLoad.checksum==f->checksum){
138 f->base_id = fLoad.base_code;
139 break;
140 }
141 }
142 if(i==t->facility_number)
143 g_error("Facility: %s, checksum: %d is not founded\n",
144 fLoad.name,fLoad.checksum);
40331ba8 145 }else if(ev->event_id == TRACE_BLOCK_START){
146 continue;
147 }else if(ev->event_id == TRACE_BLOCK_END){
148 break;
963b5f2d 149 }else g_error("Not valid facilities trace file\n");
150 }
151 }
6cd62ccf 152}
153
154/*****************************************************************************
155 *Function name
963b5f2d 156 * ltt_tracefile_close: close a trace file,
6cd62ccf 157 *Input params
963b5f2d 158 * t : tracefile which will be closed
6cd62ccf 159 ****************************************************************************/
160
963b5f2d 161void ltt_tracefile_close(LttTracefile *t)
6cd62ccf 162{
963b5f2d 163 g_free(t->name);
164 g_free(t->buffer);
663bd9ff 165 close(t->fd);
963b5f2d 166 g_free(t);
167}
6cd62ccf 168
6cd62ccf 169
963b5f2d 170/*****************************************************************************
171 *Get system information
172 ****************************************************************************/
173void getSystemInfo(LttSystemDescription* des, char * pathname)
174{
175 FILE * fp;
176 int i;
177 int entry_number = 15;
178 char buf[DIR_NAME_SIZE];
179 char description[4*DIR_NAME_SIZE];
180 char * ptr;
181
182 fp = fopen(pathname,"r");
183 if(!fp){
184 g_error("Can not open file : %s\n", pathname);
6cd62ccf 185 }
963b5f2d 186
187 while(fgets(buf,DIR_NAME_SIZE, fp)!= NULL){
188 ptr = buf;
189 while(isspace(*ptr)) ptr++;
190 if(strlen(ptr) == 0) continue;
191 break;
6cd62ccf 192 }
193
963b5f2d 194 if(strlen(ptr) == 0) g_error("Not a valid file: %s\n", pathname);
195 if(strncmp("<system",ptr,7) !=0)g_error("Not a valid file: %s\n", pathname);
196
197 for(i=0;i<entry_number;i++){
198 if(fgets(buf,DIR_NAME_SIZE, fp)== NULL)
199 g_error("Not a valid file: %s\n", pathname);
8710c6c7 200 buf[strlen(buf)-1] = '\0';
963b5f2d 201 ptr = buf;
202 while(isspace(*ptr)) ptr++;
203 switch(i){
204 case 0:
205 if(strncmp("node_name=",ptr,10)!=0)
206 g_error("Not a valid file: %s\n", pathname);
207 des->node_name = g_strdup(ptr+10);
208 break;
209 case 1:
210 if(strncmp("domainname=",ptr,11)!=0)
211 g_error("Not a valid file: %s\n", pathname);
212 des->domain_name = g_strdup(ptr+11);
213 break;
214 case 2:
215 if(strncmp("cpu=",ptr,4)!=0)
216 g_error("Not a valid file: %s\n", pathname);
217 des->nb_cpu = (unsigned)atoi(ptr+4);
218 break;
219 case 3:
220 if(strncmp("arch_size=",ptr,10)!=0)
221 g_error("Not a valid file: %s\n", pathname);
222 if(strcmp(ptr+10,"\"LP32\"") == 0) des->size = LTT_LP32;
223 else if(strcmp(ptr+10,"\"ILP32\"") == 0) des->size = LTT_ILP32;
224 else if(strcmp(ptr+10,"\"LP64\"") == 0) des->size = LTT_LP64;
225 else if(strcmp(ptr+10,"\"ILP64\"") == 0) des->size = LTT_ILP64;
226 else if(strcmp(ptr+10,"\"UNKNOWN\"") == 0) des->size = LTT_UNKNOWN;
227 break;
228 case 4:
229 if(strncmp("endian=",ptr,7)!=0)
230 g_error("Not a valid file: %s\n", pathname);
231 if(strcmp(ptr+7,"\"LITTLE_ENDIAN\"") == 0)
232 des->endian = LTT_LITTLE_ENDIAN;
233 else if(strcmp(ptr+7,"\"BIG_ENDIAN\"") == 0)
234 des->endian = LTT_BIG_ENDIAN;
235 break;
236 case 5:
237 if(strncmp("kernel_name=",ptr,12)!=0)
238 g_error("Not a valid file: %s\n", pathname);
239 des->kernel_name = g_strdup(ptr+12);
240 break;
241 case 6:
242 if(strncmp("kernel_release=",ptr,15)!=0)
243 g_error("Not a valid file: %s\n", pathname);
244 des->kernel_release = g_strdup(ptr+15);
245 break;
246 case 7:
247 if(strncmp("kernel_version=",ptr,15)!=0)
248 g_error("Not a valid file: %s\n", pathname);
249 des->kernel_version = g_strdup(ptr+15);
250 break;
251 case 8:
252 if(strncmp("machine=",ptr,8)!=0)
253 g_error("Not a valid file: %s\n", pathname);
254 des->machine = g_strdup(ptr+8);
255 break;
256 case 9:
257 if(strncmp("processor=",ptr,10)!=0)
258 g_error("Not a valid file: %s\n", pathname);
259 des->processor = g_strdup(ptr+10);
260 break;
261 case 10:
262 if(strncmp("hardware_platform=",ptr,18)!=0)
263 g_error("Not a valid file: %s\n", pathname);
264 des->hardware_platform = g_strdup(ptr+18);
265 break;
266 case 11:
267 if(strncmp("operating_system=",ptr,17)!=0)
268 g_error("Not a valid file: %s\n", pathname);
269 des->operating_system = g_strdup(ptr+17);
270 break;
271 case 12:
272 if(strncmp("ltt_major_version=",ptr,18)!=0)
273 g_error("Not a valid file: %s\n", pathname);
274 ptr += 18;
8710c6c7 275 // ptr++;//skip begining "
276 // ptr[strlen(ptr)-1] = '\0'; //get rid of the ending "
963b5f2d 277 des->ltt_major_version = (unsigned)atoi(ptr);
278 break;
279 case 13:
280 if(strncmp("ltt_minor_version=",ptr,18)!=0)
281 g_error("Not a valid file: %s\n", pathname);
282 ptr += 18;
8710c6c7 283 // ptr++;//skip begining "
284 // ptr[strlen(ptr)-1] = '\0'; //get rid of the ending "
963b5f2d 285 des->ltt_minor_version = (unsigned)atoi(ptr);
286 break;
287 case 14:
288 if(strncmp("ltt_block_size=",ptr,15)!=0)
289 g_error("Not a valid file: %s\n", pathname);
290 ptr += 15;
8710c6c7 291 // ptr++;//skip begining "
292 // ptr[strlen(ptr)-1] = '\0'; //get rid of the ending "
963b5f2d 293 des->ltt_block_size = (unsigned)atoi(ptr);
294 break;
295 default:
296 g_error("Not a valid file: %s\n", pathname);
297 }
6cd62ccf 298 }
299
963b5f2d 300 //get description
301 description[0] = '\0';
302 if(fgets(buf,DIR_NAME_SIZE, fp)== NULL)
303 g_error("Not a valid file: %s\n", pathname);
304 ptr = buf;
305 while(isspace(*ptr)) ptr++;
306 if(*ptr != '>') g_error("Not a valid file: %s\n", pathname);
307 while((ptr=fgets(buf,DIR_NAME_SIZE, fp))!= NULL){
308 ptr = buf;
309 while(isspace(*ptr)) ptr++;
310 if(strncmp("</system>",ptr,9) == 0 )break;
311 strcat(description, buf);
312 }
313 if(!ptr)g_error("Not a valid file: %s\n", pathname);
314 if(description[0] = '\0')des->description = NULL;
315 des->description = g_strdup(description);
6cd62ccf 316
963b5f2d 317 fclose(fp);
6cd62ccf 318}
319
320/*****************************************************************************
963b5f2d 321 *The following functions get facility/tracefile information
6cd62ccf 322 ****************************************************************************/
323
963b5f2d 324void getFacilityInfo(LttTrace *t, char* eventdefs)
6cd62ccf 325{
963b5f2d 326 DIR * dir;
327 struct dirent *entry;
328 char * ptr;
329 int i,j;
330 LttFacility * f;
331 LttEventType * et;
e8bb1a73 332 char name[DIR_NAME_SIZE];
963b5f2d 333
334 dir = opendir(eventdefs);
335 if(!dir) g_error("Can not open directory: %s\n", eventdefs);
336
337 while((entry = readdir(dir)) != NULL){
338 ptr = &entry->d_name[strlen(entry->d_name)-4];
339 if(strcmp(ptr,".xml") != 0) continue;
e8bb1a73 340 strcpy(name,eventdefs);
341 strcat(name,entry->d_name);
342 ltt_facility_open(t,name);
963b5f2d 343 }
344 closedir(dir);
345
963b5f2d 346 for(j=0;j<t->facility_number;j++){
8710c6c7 347 f = (LttFacility*)g_ptr_array_index(t->facilities, j);
963b5f2d 348 for(i=0; i<f->event_number; i++){
349 et = f->events[i];
40331ba8 350 setFieldsOffset(NULL, et, NULL, t);
963b5f2d 351 }
352 }
353}
6cd62ccf 354
963b5f2d 355void getControlFileInfo(LttTrace *t, char* control)
6cd62ccf 356{
963b5f2d 357 DIR * dir;
358 struct dirent *entry;
e8bb1a73 359 char name[DIR_NAME_SIZE];
963b5f2d 360
361 dir = opendir(control);
362 if(!dir) g_error("Can not open directory: %s\n", control);
363
364 while((entry = readdir(dir)) != NULL){
8710c6c7 365 if(strcmp(entry->d_name,"facilities") != 0 &&
366 strcmp(entry->d_name,"interrupts") != 0 &&
963b5f2d 367 strcmp(entry->d_name,"processes") != 0) continue;
368
e8bb1a73 369 strcpy(name,control);
370 strcat(name,entry->d_name);
371 ltt_tracefile_open_control(t,name);
963b5f2d 372 }
373 closedir(dir);
6cd62ccf 374}
375
963b5f2d 376void getCpuFileInfo(LttTrace *t, char* cpu)
6cd62ccf 377{
963b5f2d 378 DIR * dir;
379 struct dirent *entry;
e8bb1a73 380 char name[DIR_NAME_SIZE];
963b5f2d 381
382 dir = opendir(cpu);
383 if(!dir) g_error("Can not open directory: %s\n", cpu);
384
385 while((entry = readdir(dir)) != NULL){
8710c6c7 386 if(strcmp(entry->d_name,".") != 0 &&
963b5f2d 387 strcmp(entry->d_name,"..") != 0 ){
e8bb1a73 388 strcpy(name,cpu);
389 strcat(name,entry->d_name);
390 ltt_tracefile_open_cpu(t,name);
963b5f2d 391 }else continue;
392 }
393 closedir(dir);
6cd62ccf 394}
395
963b5f2d 396/*****************************************************************************
397 *A trace is specified as a pathname to the directory containing all the
398 *associated data (control tracefiles, per cpu tracefiles, event
399 *descriptions...).
400 *
401 *When a trace is closed, all the associated facilities, types and fields
402 *are released as well.
403 ****************************************************************************/
6cd62ccf 404
f7afe191 405LttTrace *ltt_trace_open(const char *pathname)
6cd62ccf 406{
963b5f2d 407 LttTrace * t;
408 LttSystemDescription * sys_description;
409 char eventdefs[DIR_NAME_SIZE];
410 char info[DIR_NAME_SIZE];
411 char control[DIR_NAME_SIZE];
412 char cpu[DIR_NAME_SIZE];
413 char tmp[DIR_NAME_SIZE];
414 gboolean has_slash = FALSE;
415
416 //establish the pathname to different directories
417 if(pathname[strlen(pathname)-1] == '/')has_slash = TRUE;
418 strcpy(eventdefs,pathname);
419 if(!has_slash)strcat(eventdefs,"/");
420 strcat(eventdefs,"eventdefs/");
421
422 strcpy(info,pathname);
423 if(!has_slash)strcat(info,"/");
424 strcat(info,"info/");
425
426 strcpy(control,pathname);
427 if(!has_slash)strcat(control,"/");
428 strcat(control,"control/");
429
430 strcpy(cpu,pathname);
431 if(!has_slash)strcat(cpu,"/");
432 strcat(cpu,"cpu/");
433
434 //new trace
435 t = g_new(LttTrace, 1);
436 sys_description = g_new(LttSystemDescription, 1);
437 t->pathname = g_strdup(pathname);
438 t->facility_number = 0;
439 t->control_tracefile_number = 0;
440 t->per_cpu_tracefile_number = 0;
441 t->system_description = sys_description;
442 t->control_tracefiles = g_ptr_array_new();
443 t->per_cpu_tracefiles = g_ptr_array_new();
444 t->facilities = g_ptr_array_new();
445 getDataEndianType(&(t->my_arch_size), &(t->my_arch_endian));
446
447 //get system description
448 strcpy(tmp,info);
449 strcat(tmp,"system.xml");
450 getSystemInfo(sys_description, tmp);
451
b333a76b 452 //get facilities info
453 getFacilityInfo(t,eventdefs);
454
963b5f2d 455 //get control tracefile info
456 getControlFileInfo(t,control);
457
458 //get cpu tracefile info
459 getCpuFileInfo(t,cpu);
460
963b5f2d 461 return t;
6cd62ccf 462}
463
49bf71b5 464char * ltt_trace_name(LttTrace *t)
465{
466 return t->pathname;
467}
468
469
f7afe191 470/******************************************************************************
471 * When we copy a trace, we want all the opening actions to happen again :
472 * the trace will be reopened and totally independant from the original.
473 * That's why we call ltt_trace_open.
474 *****************************************************************************/
475LttTrace *ltt_trace_copy(LttTrace *self)
476{
477 return ltt_trace_open(self->pathname);
478}
479
963b5f2d 480void ltt_trace_close(LttTrace *t)
6cd62ccf 481{
963b5f2d 482 int i;
483 LttTracefile * tf;
484 LttFacility * f;
485
486 g_free(t->pathname);
487
488 //free system_description
489 g_free(t->system_description->description);
490 g_free(t->system_description->node_name);
491 g_free(t->system_description->domain_name);
492 g_free(t->system_description->kernel_name);
493 g_free(t->system_description->kernel_release);
494 g_free(t->system_description->kernel_version);
495 g_free(t->system_description->machine);
496 g_free(t->system_description->processor);
497 g_free(t->system_description->hardware_platform);
498 g_free(t->system_description->operating_system);
499 g_free(t->system_description);
500
501 //free control_tracefiles
502 for(i=0;i<t->control_tracefile_number;i++){
503 tf = (LttTracefile*)g_ptr_array_index(t->control_tracefiles,i);
504 ltt_tracefile_close(tf);
505 }
09ad4797 506 g_ptr_array_free(t->control_tracefiles, TRUE);
963b5f2d 507
508 //free per_cpu_tracefiles
509 for(i=0;i<t->per_cpu_tracefile_number;i++){
510 tf = (LttTracefile*)g_ptr_array_index(t->per_cpu_tracefiles,i);
511 ltt_tracefile_close(tf);
512 }
09ad4797 513 g_ptr_array_free(t->per_cpu_tracefiles, TRUE);
963b5f2d 514
515 //free facilities
516 for(i=0;i<t->facility_number;i++){
517 f = (LttFacility*)g_ptr_array_index(t->facilities,i);
518 ltt_facility_close(f);
519 }
09ad4797 520 g_ptr_array_free(t->facilities, TRUE);
963b5f2d 521
522 g_free(t);
09ad4797 523
524 g_blow_chunks();
6cd62ccf 525}
526
963b5f2d 527
6cd62ccf 528/*****************************************************************************
963b5f2d 529 *Get the system description of the trace
6cd62ccf 530 ****************************************************************************/
531
963b5f2d 532LttSystemDescription *ltt_trace_system_description(LttTrace *t)
6cd62ccf 533{
963b5f2d 534 return t->system_description;
6cd62ccf 535}
536
537/*****************************************************************************
963b5f2d 538 * The following functions discover the facilities of the trace
6cd62ccf 539 ****************************************************************************/
540
963b5f2d 541unsigned ltt_trace_facility_number(LttTrace *t)
542{
543 return (unsigned)(t->facility_number);
544}
545
546LttFacility *ltt_trace_facility_get(LttTrace *t, unsigned i)
6cd62ccf 547{
963b5f2d 548 return (LttFacility*)g_ptr_array_index(t->facilities, i);
6cd62ccf 549}
550
551/*****************************************************************************
552 *Function name
963b5f2d 553 * ltt_trace_facility_find : find facilities in the trace
6cd62ccf 554 *Input params
963b5f2d 555 * t : the trace
556 * name : facility name
557 *Output params
558 * position : position of the facility in the trace
6cd62ccf 559 *Return value
963b5f2d 560 * : the number of facilities
6cd62ccf 561 ****************************************************************************/
562
963b5f2d 563unsigned ltt_trace_facility_find(LttTrace *t, char *name, unsigned *position)
6cd62ccf 564{
963b5f2d 565 int i, count=0;
566 LttFacility * f;
8a3005f3 567 for(i=0;i<t->facility_number;i++){
963b5f2d 568 f = (LttFacility*)g_ptr_array_index(t->facilities, i);
569 if(strcmp(f->name,name)==0){
570 count++;
571 if(count==1) *position = i;
572 }else{
573 if(count) break;
574 }
575 }
576 return count;
6cd62ccf 577}
578
579/*****************************************************************************
963b5f2d 580 * Functions to discover all the event types in the trace
6cd62ccf 581 ****************************************************************************/
582
963b5f2d 583unsigned ltt_trace_eventtype_number(LttTrace *t)
6cd62ccf 584{
963b5f2d 585 int i;
586 unsigned count = 0;
587 LttFacility * f;
b445142a 588 for(i=0;i<t->facility_number;i++){
963b5f2d 589 f = (LttFacility*)g_ptr_array_index(t->facilities, i);
590 count += f->event_number;
591 }
592 return count;
6cd62ccf 593}
594
963b5f2d 595LttFacility * ltt_trace_facility_by_id(LttTrace * trace, unsigned id)
6cd62ccf 596{
963b5f2d 597 LttFacility * facility;
598 int i;
599 for(i=0;i<trace->facility_number;i++){
600 facility = (LttFacility*) g_ptr_array_index(trace->facilities,i);
601 if(id >= facility->base_id &&
602 id < facility->base_id + facility->event_number)
603 break;
604 }
605 if(i==trace->facility_number) return NULL;
606 else return facility;
6cd62ccf 607}
608
963b5f2d 609LttEventType *ltt_trace_eventtype_get(LttTrace *t, unsigned evId)
6cd62ccf 610{
963b5f2d 611 LttFacility * f;
612 f = ltt_trace_facility_by_id(t,evId);
613 if(!f) return NULL;
614 return f->events[evId - f->base_id];
6cd62ccf 615}
616
617/*****************************************************************************
963b5f2d 618 *There is one "per cpu" tracefile for each CPU, numbered from 0 to
619 *the maximum number of CPU in the system. When the number of CPU installed
620 *is less than the maximum, some positions are unused. There are also a
621 *number of "control" tracefiles (facilities, interrupts...).
6cd62ccf 622 ****************************************************************************/
963b5f2d 623unsigned ltt_trace_control_tracefile_number(LttTrace *t)
6cd62ccf 624{
963b5f2d 625 return t->control_tracefile_number;
6cd62ccf 626}
627
963b5f2d 628unsigned ltt_trace_per_cpu_tracefile_number(LttTrace *t)
6cd62ccf 629{
963b5f2d 630 return t->per_cpu_tracefile_number;
6cd62ccf 631}
632
633/*****************************************************************************
963b5f2d 634 *It is possible to search for the tracefiles by name or by CPU position.
635 *The index within the tracefiles of the same type is returned if found
636 *and a negative value otherwise.
6cd62ccf 637 ****************************************************************************/
638
963b5f2d 639int ltt_trace_control_tracefile_find(LttTrace *t, char *name)
6cd62ccf 640{
963b5f2d 641 LttTracefile * tracefile;
642 int i;
643 for(i=0;i<t->control_tracefile_number;i++){
644 tracefile = (LttTracefile*)g_ptr_array_index(t->control_tracefiles, i);
645 if(strcmp(tracefile->name, name)==0)break;
646 }
647 if(i == t->control_tracefile_number) return -1;
648 return i;
6cd62ccf 649}
650
963b5f2d 651int ltt_trace_per_cpu_tracefile_find(LttTrace *t, unsigned i)
6cd62ccf 652{
963b5f2d 653 LttTracefile * tracefile;
654 int j, name;
655 for(j=0;j<t->per_cpu_tracefile_number;j++){
656 tracefile = (LttTracefile*)g_ptr_array_index(t->per_cpu_tracefiles, j);
657 name = atoi(tracefile->name);
658 if(name == (int)i)break;
659 }
660 if(j == t->per_cpu_tracefile_number) return -1;
661 return j;
6cd62ccf 662}
663
664/*****************************************************************************
963b5f2d 665 *Get a specific tracefile
6cd62ccf 666 ****************************************************************************/
667
963b5f2d 668LttTracefile *ltt_trace_control_tracefile_get(LttTrace *t, unsigned i)
6cd62ccf 669{
5598cfe3 670 return (LttTracefile*)g_ptr_array_index(t->control_tracefiles, i);
963b5f2d 671}
672
673LttTracefile *ltt_trace_per_cpu_tracefile_get(LttTrace *t, unsigned i)
674{
675 return (LttTracefile*)g_ptr_array_index(t->per_cpu_tracefiles, i);
6cd62ccf 676}
677
487ad181 678/*****************************************************************************
679 * Get the start time and end time of the trace
680 ****************************************************************************/
681
682void ltt_trace_time_span_get(LttTrace *t, LttTime *start, LttTime *end)
683{
684 LttTime startSmall, startTmp, endBig, endTmp;
685 int i, j=0;
686 LttTracefile * tf;
687
688 for(i=0;i<t->control_tracefile_number;i++){
689 tf = g_ptr_array_index(t->control_tracefiles, i);
690 readBlock(tf,1);
691 startTmp = tf->a_block_start->time;
692 readBlock(tf,tf->block_number);
693 endTmp = tf->a_block_end->time;
694 if(i==0){
695 startSmall = startTmp;
696 endBig = endTmp;
697 j = 1;
698 continue;
699 }
308711e5 700 if(ltt_time_compare(startSmall,startTmp) > 0) startSmall = startTmp;
701 if(ltt_time_compare(endBig,endTmp) < 0) endBig = endTmp;
487ad181 702 }
703
704 for(i=0;i<t->per_cpu_tracefile_number;i++){
705 tf = g_ptr_array_index(t->per_cpu_tracefiles, i);
706 readBlock(tf,1);
707 startTmp = tf->a_block_start->time;
708 readBlock(tf,tf->block_number);
709 endTmp = tf->a_block_end->time;
710 if(j == 0 && i==0){
711 startSmall = startTmp;
712 endBig = endTmp;
713 continue;
714 }
308711e5 715 if(ltt_time_compare(startSmall,startTmp) > 0) startSmall = startTmp;
716 if(ltt_time_compare(endBig,endTmp) < 0) endBig = endTmp;
487ad181 717 }
718
719 *start = startSmall;
720 *end = endBig;
721}
722
723
6cd62ccf 724/*****************************************************************************
963b5f2d 725 *Get the name of a tracefile
6cd62ccf 726 ****************************************************************************/
727
963b5f2d 728char *ltt_tracefile_name(LttTracefile *tf)
6cd62ccf 729{
963b5f2d 730 return tf->name;
6cd62ccf 731}
732
80da81ad 733/*****************************************************************************
734 * Get the number of blocks in the tracefile
735 ****************************************************************************/
736
737unsigned ltt_tracefile_block_number(LttTracefile *tf)
738{
739 return tf->block_number;
740}
741
6cd62ccf 742/*****************************************************************************
743 *Function name
744 * ltt_tracefile_seek_time: seek to the first event of the trace with time
745 * larger or equal to time
746 *Input params
747 * t : tracefile
748 * time : criteria of the time
6cd62ccf 749 ****************************************************************************/
caf7a67a 750void ltt_tracefile_find_time_block(LttTracefile *t, LttTime time,
751 int start_block, int end_block)
752{
753 int err, tmp_block, s, e;
754 int headTime;
755 int tailTime;
756
757 err=readBlock(t,start_block);
758 if(err) g_error("Can not read tracefile: %s\n", t->name);
759 if(start_block == end_block)return;
760
761 tailTime = ltt_time_compare(t->a_block_end->time, time);
762 if(tailTime >= 0) return;
763
764 err=readBlock(t,end_block);
765 if(err) g_error("Can not read tracefile: %s\n", t->name);
766 if(start_block+1 == end_block)return;
767
768 headTime = ltt_time_compare(t->a_block_start->time, time);
769 if(headTime <= 0 ) return;
770
771 tmp_block = (end_block + start_block)/2;
772 err=readBlock(t,tmp_block);
773 if(err) g_error("Can not read tracefile: %s\n", t->name);
774
775 headTime = ltt_time_compare(t->a_block_start->time, time);
776 tailTime = ltt_time_compare(t->a_block_end->time, time);
777 if(headTime <= 0 && tailTime >= 0) return;
778
779 if(headTime > 0){
780 s = start_block + 1;
781 e = tmp_block - 1;
782 if(s <= e)
783 ltt_tracefile_find_time_block(t, time, s, e);
784 else return;
785 }
786
787 if(tailTime < 0){
788 s = tmp_block + 1;
789 e = end_block - 1;
790 if(s <= e)
791 ltt_tracefile_find_time_block(t, time, s, e);
792 else return;
793 }
794}
795
796void ltt_tracefile_backward_find_time_block(LttTracefile *t, LttTime time)
797{
798 int t_time, h_time, err;
799 err=readBlock(t,t->which_block-1);
800 if(err) g_error("Can not read tracefile: %s\n", t->name);
801 h_time = ltt_time_compare(t->a_block_start->time, time);
802 t_time = ltt_time_compare(t->a_block_end->time, time);
803 if(h_time == 0){
804 int tmp;
805 if(t->which_block == 1) return;
806 err=readBlock(t,t->which_block-1);
807 if(err) g_error("Can not read tracefile: %s\n", t->name);
808 tmp = ltt_time_compare(t->a_block_end->time, time);
809 if(tmp == 0) return ltt_tracefile_seek_time(t, time);
810 err=readBlock(t,t->which_block+1);
811 if(err) g_error("Can not read tracefile: %s\n", t->name);
812 }else if(h_time > 0){
813 ltt_tracefile_find_time_block(t, time, 1, t->which_block);
814 return ltt_tracefile_seek_time(t, time) ;
815 }else{
816 if(t_time >= 0) return ltt_tracefile_seek_time(t, time);
817 err=readBlock(t,t->which_block+1);
818 if(err) g_error("Can not read tracefile: %s\n", t->name);
819 }
820}
6cd62ccf 821
963b5f2d 822void ltt_tracefile_seek_time(LttTracefile *t, LttTime time)
6cd62ccf 823{
824 int err;
963b5f2d 825 LttTime lttTime;
308711e5 826 int headTime = ltt_time_compare(t->a_block_start->time, time);
827 int tailTime = ltt_time_compare(t->a_block_end->time, time);
62e55dd6 828 LttEvent * ev;
829
6cd62ccf 830 if(headTime < 0 && tailTime > 0){
308711e5 831 if(ltt_time_compare(t->a_block_end->time, t->current_event_time) !=0) {
db55eaae 832 lttTime = getEventTime(t);
308711e5 833 err = ltt_time_compare(lttTime, time);
db55eaae 834 if(err > 0){
308711e5 835 if(t->which_event==2 || (&t->prev_event_time,&time)<0){
1a3b8cbd 836 return;
db55eaae 837 }else{
838 updateTracefile(t);
839 return ltt_tracefile_seek_time(t, time);
1a3b8cbd 840 }
db55eaae 841 }else if(err < 0){
842 while(1){
843 ev = ltt_tracefile_read(t);
844 if(ev == NULL){
845 g_print("End of file\n");
846 return;
847 }
848 lttTime = getEventTime(t);
308711e5 849 err = ltt_time_compare(lttTime, time);
db55eaae 850 if(err >= 0)return;
851 }
852 }else return;
853 }else{//we are at the end of the block
854 updateTracefile(t);
855 return ltt_tracefile_seek_time(t, time);
856 }
e37c1372 857 }else if(headTime >= 0){
6cd62ccf 858 if(t->which_block == 1){
859 updateTracefile(t);
860 }else{
1ee6a9af 861 if(ltt_time_compare(t->prev_block_end_time, time) >= 0 ||
862 (t->prev_block_end_time.tv_sec == 0 &&
863 t->prev_block_end_time.tv_nsec == 0 )){
caf7a67a 864 ltt_tracefile_backward_find_time_block(t, time);
6cd62ccf 865 }else{
866 updateTracefile(t);
867 }
868 }
40331ba8 869 }else if(tailTime < 0){
6cd62ccf 870 if(t->which_block != t->block_number){
caf7a67a 871 ltt_tracefile_find_time_block(t, time, t->which_block+1, t->block_number);
872 return ltt_tracefile_seek_time(t, time);
963b5f2d 873 }else {
a8c0f09d 874 t->cur_event_pos = t->buffer + t->block_size;
875 g_print("End of file\n");
963b5f2d 876 return;
877 }
40331ba8 878 }else if(tailTime == 0){
e37c1372 879 t->cur_event_pos = t->last_event_pos;
62e55dd6 880 t->current_event_time = time;
881 t->cur_heart_beat_number = 0;
882 t->prev_event_time.tv_sec = 0;
883 t->prev_event_time.tv_nsec = 0;
40331ba8 884 return;
6cd62ccf 885 }
6cd62ccf 886}
887
80da81ad 888/*****************************************************************************
889 * Seek to the first event with position equal or larger to ep
890 ****************************************************************************/
891
892void ltt_tracefile_seek_position(LttTracefile *t, LttEventPosition *ep)
893{
894 //if we are at the right place, just return
895 if(t->which_block == ep->block_num && t->which_event == ep->event_num)
896 return;
897
898 if(t->which_block == ep->block_num) updateTracefile(t);
899 else readBlock(t,ep->block_num);
900
901 //event offset is availiable
902 if(ep->old_position){
903 t->cur_heart_beat_number = ep->heart_beat_number;
904 t->cur_event_pos = t->buffer + ep->event_offset;
905 return;
906 }
907
908 //only block number and event index are availiable
909 while(t->which_event < ep->event_num) ltt_tracefile_read(t);
910
911 return;
912}
913
6cd62ccf 914/*****************************************************************************
915 *Function name
40331ba8 916 * ltt_tracefile_read : read the current event, set the pointer to the next
6cd62ccf 917 *Input params
918 * t : tracefile
919 *Return value
963b5f2d 920 * LttEvent * : an event to be processed
6cd62ccf 921 ****************************************************************************/
922
963b5f2d 923LttEvent *ltt_tracefile_read(LttTracefile *t)
6cd62ccf 924{
7525f9e5 925 LttEvent * lttEvent = &t->an_event;
963b5f2d 926 int err;
6cd62ccf 927
bdc36259 928 if(t->cur_event_pos == t->buffer + t->block_size){
929 if(t->which_block == t->block_number){
bdc36259 930 return NULL;
931 }
932 err = readBlock(t, t->which_block + 1);
933 if(err)g_error("Can not read tracefile");
934 }
935
cbd41522 936 lttEvent->event_id = (int)(*(guint16 *)(t->cur_event_pos));
963b5f2d 937 if(lttEvent->event_id == TRACE_TIME_HEARTBEAT)
938 t->cur_heart_beat_number++;
6cd62ccf 939
40331ba8 940 t->prev_event_time = t->current_event_time;
62e55dd6 941 // t->current_event_time = getEventTime(t);
6cd62ccf 942
cbd41522 943 lttEvent->time_delta = *(guint32 *)(t->cur_event_pos + EVENT_ID_SIZE);
963b5f2d 944 lttEvent->event_time = t->current_event_time;
945
6cd62ccf 946 lttEvent->tracefile = t;
947 lttEvent->data = t->cur_event_pos + EVENT_HEADER_SIZE;
908f42fa 948 lttEvent->which_block = t->which_block;
949 lttEvent->which_event = t->which_event;
6cd62ccf 950
40331ba8 951 //update the fields of the current event and go to the next event
952 err = skipEvent(t);
40331ba8 953 if(err == ERANGE) g_error("event id is out of range\n");
40331ba8 954
e4eced0f 955 lttEvent->event_cycle_count = t->cur_cycle_count;
956
6cd62ccf 957 return lttEvent;
958}
959
960/****************************************************************************
961 *Function name
962 * readFile : wrap function to read from a file
963 *Input Params
964 * fd : file descriptor
965 * buf : buf to contain the content
966 * size : number of bytes to be read
967 * mesg : message to be printed if some thing goes wrong
968 *return value
969 * 0 : success
970 * EIO : can not read from the file
971 ****************************************************************************/
972
973int readFile(int fd, void * buf, size_t size, char * mesg)
974{
975 ssize_t nbBytes;
976 nbBytes = read(fd, buf, size);
977 if(nbBytes != size){
978 printf("%s\n",mesg);
979 return EIO;
980 }
981 return 0;
982}
983
984/****************************************************************************
985 *Function name
986 * readBlock : read a block from the file
987 *Input Params
988 * lttdes : ltt trace file
989 * whichBlock : the block which will be read
990 *return value
991 * 0 : success
992 * EINVAL : lseek fail
993 * EIO : can not read from the file
994 ****************************************************************************/
995
963b5f2d 996int readBlock(LttTracefile * tf, int whichBlock)
6cd62ccf 997{
998 off_t nbBytes;
cbd41522 999 guint32 lostSize;
6cd62ccf 1000
1001 if(whichBlock - tf->which_block == 1 && tf->which_block != 0){
963b5f2d 1002 tf->prev_block_end_time = tf->a_block_end->time;
40331ba8 1003 tf->prev_event_time = tf->a_block_end->time;
6cd62ccf 1004 }else{
1005 tf->prev_block_end_time.tv_sec = 0;
1006 tf->prev_block_end_time.tv_nsec = 0;
40331ba8 1007 tf->prev_event_time.tv_sec = 0;
1008 tf->prev_event_time.tv_nsec = 0;
6cd62ccf 1009 }
6cd62ccf 1010
963b5f2d 1011 nbBytes=lseek(tf->fd,(off_t)((whichBlock-1)*tf->block_size), SEEK_SET);
6cd62ccf 1012 if(nbBytes == -1) return EINVAL;
1013
963b5f2d 1014 if(readFile(tf->fd,tf->buffer,tf->block_size,"Unable to read a block"))
1015 return EIO;
6cd62ccf 1016
963b5f2d 1017 tf->a_block_start=(BlockStart *) (tf->buffer + EVENT_HEADER_SIZE);
cbd41522 1018 lostSize = *(guint32 *)(tf->buffer + tf->block_size - sizeof(guint32));
963b5f2d 1019 tf->a_block_end=(BlockEnd *)(tf->buffer + tf->block_size -
1020 lostSize + EVENT_HEADER_SIZE);
e37c1372 1021 tf->last_event_pos = tf->buffer + tf->block_size - lostSize;
6cd62ccf 1022
6cd62ccf 1023 tf->which_block = whichBlock;
963b5f2d 1024 tf->which_event = 1;
40331ba8 1025 tf->cur_event_pos = tf->buffer;//the beginning of the block, block start ev
6cd62ccf 1026 tf->cur_heart_beat_number = 0;
963b5f2d 1027
6cd62ccf 1028 getCyclePerNsec(tf);
1029
62e55dd6 1030 tf->current_event_time = getEventTime(tf);
40331ba8 1031
6cd62ccf 1032 return 0;
1033}
1034
1035/*****************************************************************************
1036 *Function name
1037 * updateTracefile : reinitialize the info of the block which is already
1038 * in the buffer
1039 *Input params
1040 * tf : tracefile
1041 ****************************************************************************/
1042
963b5f2d 1043void updateTracefile(LttTracefile * tf)
6cd62ccf 1044{
963b5f2d 1045 tf->which_event = 1;
40331ba8 1046 tf->cur_event_pos = tf->buffer;
62e55dd6 1047 tf->current_event_time = getEventTime(tf);
6cd62ccf 1048 tf->cur_heart_beat_number = 0;
1049
1050 tf->prev_event_time.tv_sec = 0;
1051 tf->prev_event_time.tv_nsec = 0;
1052}
1053
1054/*****************************************************************************
1055 *Function name
1056 * skipEvent : go to the next event, update the fields of the current event
1057 *Input params
1058 * t : tracefile
1059 *return value
1060 * 0 : success
6cd62ccf 1061 * ERANGE : event id is out of range
1062 ****************************************************************************/
1063
963b5f2d 1064int skipEvent(LttTracefile * t)
6cd62ccf 1065{
1066 int evId, err;
1067 void * evData;
963b5f2d 1068 LttEventType * evT;
1069 LttField * rootFld;
6cd62ccf 1070
cbd41522 1071 evId = (int)(*(guint16 *)(t->cur_event_pos));
6cd62ccf 1072 evData = t->cur_event_pos + EVENT_HEADER_SIZE;
6cd62ccf 1073
908f42fa 1074 evT = ltt_trace_eventtype_get(t->trace,(unsigned)evId);
47a166fc 1075
908f42fa 1076 if(evT) rootFld = evT->root_field;
1077 else return ERANGE;
6cd62ccf 1078
908f42fa 1079 if(rootFld){
1080 //event has string/sequence or the last event is not the same event
1081 if((evT->latest_block!=t->which_block || evT->latest_event!=t->which_event)
1082 && rootFld->field_fixed == 0){
1083 setFieldsOffset(t, evT, evData, t->trace);
47a166fc 1084 }
908f42fa 1085 t->cur_event_pos += EVENT_HEADER_SIZE + rootFld->field_size;
1086 }else t->cur_event_pos += EVENT_HEADER_SIZE;
1087
1088 evT->latest_block = t->which_block;
1089 evT->latest_event = t->which_event;
1090
6cd62ccf 1091 //the next event is in the next block
963b5f2d 1092 if(evId == TRACE_BLOCK_END){
bdc36259 1093 t->cur_event_pos = t->buffer + t->block_size;
6cd62ccf 1094 }else{
1095 t->which_event++;
62e55dd6 1096 t->current_event_time = getEventTime(t);
6cd62ccf 1097 }
1098
1099 return 0;
1100}
1101
1102/*****************************************************************************
1103 *Function name
1104 * getCyclePerNsec : calculate cycles per nsec for current block
1105 *Input Params
1106 * t : tracefile
1107 ****************************************************************************/
1108
963b5f2d 1109void getCyclePerNsec(LttTracefile * t)
6cd62ccf 1110{
963b5f2d 1111 LttTime lBufTotalTime; /* Total time for this buffer */
1112 LttCycleCount lBufTotalNSec; /* Total time for this buffer in nsecs */
1113 LttCycleCount lBufTotalCycle;/* Total cycles for this buffer */
6cd62ccf 1114
1115 /* Calculate the total time for this buffer */
308711e5 1116 lBufTotalTime = ltt_time_sub(t->a_block_end->time, t->a_block_start->time);
6cd62ccf 1117
1118 /* Calculate the total cycles for this bufffer */
e4eced0f 1119 lBufTotalCycle = t->a_block_end->cycle_count;
1120 lBufTotalCycle -= t->a_block_start->cycle_count;
6cd62ccf 1121
1122 /* Convert the total time to nsecs */
e4eced0f 1123 lBufTotalNSec = lBufTotalTime.tv_sec;
308711e5 1124 lBufTotalNSec *= NANOSECONDS_PER_SECOND;
e4eced0f 1125 lBufTotalNSec += lBufTotalTime.tv_nsec;
6cd62ccf 1126
1127 t->cycle_per_nsec = (double)lBufTotalCycle / (double)lBufTotalNSec;
1128}
1129
1130/****************************************************************************
1131 *Function name
1132 * getEventTime : obtain the time of an event
1133 *Input params
1134 * tf : tracefile
1135 *Return value
963b5f2d 1136 * LttTime : the time of the event
6cd62ccf 1137 ****************************************************************************/
1138
963b5f2d 1139LttTime getEventTime(LttTracefile * tf)
6cd62ccf 1140{
963b5f2d 1141 LttTime time;
1142 LttCycleCount cycle_count; // cycle count for the current event
1143 LttCycleCount lEventTotalCycle; // Total cycles from start for event
1144 double lEventNSec; // Total usecs from start for event
1145 LttTime lTimeOffset; // Time offset in struct LttTime
cbd41522 1146 guint16 evId;
1147 gint64 nanoSec, tmpCycleCount = (((guint64)1)<<32);
e4eced0f 1148
cbd41522 1149 evId = *(guint16 *)tf->cur_event_pos;
e4eced0f 1150 if(evId == TRACE_BLOCK_START){
dd691a2e 1151 tf->count = 0;
1152 tf->pre_cycle_count = 0;
e4eced0f 1153 tf->cur_cycle_count = tf->a_block_start->cycle_count;
40331ba8 1154 return tf->a_block_start->time;
e4eced0f 1155 }else if(evId == TRACE_BLOCK_END){
dd691a2e 1156 tf->count = 0;
1157 tf->pre_cycle_count = 0;
e4eced0f 1158 tf->cur_cycle_count = tf->a_block_end->cycle_count;
40331ba8 1159 return tf->a_block_end->time;
e4eced0f 1160 }
40331ba8 1161
e4eced0f 1162 // Calculate total time in cycles from start of buffer for this event
cbd41522 1163 cycle_count = (LttCycleCount)*(guint32 *)(tf->cur_event_pos + EVENT_ID_SIZE);
e4eced0f 1164
dd691a2e 1165 if(cycle_count < tf->pre_cycle_count)tf->count++;
1166 tf->pre_cycle_count = cycle_count;
1167 cycle_count += tmpCycleCount * tf->count;
e4eced0f 1168
dd691a2e 1169 if(tf->cur_heart_beat_number > tf->count)
1170 cycle_count += tmpCycleCount * (tf->cur_heart_beat_number - tf->count);
e4eced0f 1171
1172 tf->cur_cycle_count = cycle_count;
1173
1174 lEventTotalCycle = cycle_count;
1175 lEventTotalCycle -= tf->a_block_start->cycle_count;
6cd62ccf 1176
963b5f2d 1177 // Convert it to nsecs
6cd62ccf 1178 lEventNSec = lEventTotalCycle / tf->cycle_per_nsec;
e4eced0f 1179 nanoSec = lEventNSec;
1180
963b5f2d 1181 // Determine offset in struct LttTime
308711e5 1182 lTimeOffset.tv_nsec = nanoSec % NANOSECONDS_PER_SECOND;
1183 lTimeOffset.tv_sec = nanoSec / NANOSECONDS_PER_SECOND;
6cd62ccf 1184
308711e5 1185 time = ltt_time_add(tf->a_block_start->time, lTimeOffset);
e4eced0f 1186
6cd62ccf 1187 return time;
1188}
1189
1190/*****************************************************************************
1191 *Function name
1192 * setFieldsOffset : set offset of the fields
1193 *Input params
1194 * tracefile : opened trace file
1195 * evT : the event type
1196 * evD : event data, it may be NULL
1197 ****************************************************************************/
1198
40331ba8 1199void setFieldsOffset(LttTracefile *tf,LttEventType *evT,void *evD,LttTrace* t)
6cd62ccf 1200{
963b5f2d 1201 LttField * rootFld = evT->root_field;
6cd62ccf 1202 // rootFld->base_address = evD;
1203
8710c6c7 1204 if(rootFld)
1205 rootFld->field_size = getFieldtypeSize(tf, evT, 0,0,rootFld, evD,t);
6cd62ccf 1206}
1207
1208/*****************************************************************************
1209 *Function name
1210 * getFieldtypeSize: get the size of the field type (primitive type)
1211 *Input params
1212 * tracefile : opened trace file
1213 * evT : event type
1214 * offsetRoot : offset from the root
1215 * offsetParent : offset from the parrent
1216 * fld : field
1217 * evD : event data, it may be NULL
1218 *Return value
1219 * int : size of the field
1220 ****************************************************************************/
1221
963b5f2d 1222int getFieldtypeSize(LttTracefile * t, LttEventType * evT, int offsetRoot,
40331ba8 1223 int offsetParent, LttField * fld, void *evD, LttTrace *trace)
6cd62ccf 1224{
1225 int size, size1, element_number, i, offset1, offset2;
963b5f2d 1226 LttType * type = fld->field_type;
6cd62ccf 1227
8710c6c7 1228 if(t){
963b5f2d 1229 if(evT->latest_block==t->which_block && evT->latest_event==t->which_event){
1230 return fld->field_size;
1231 }
1232 }
6cd62ccf 1233
1234 if(fld->field_fixed == 1){
1235 if(fld == evT->root_field) return fld->field_size;
1236 }
1237
1238 if(type->type_class != LTT_STRUCT && type->type_class != LTT_ARRAY &&
1239 type->type_class != LTT_SEQUENCE && type->type_class != LTT_STRING){
1240 if(fld->field_fixed == -1){
40331ba8 1241 size = (int) ltt_type_size(trace, type);
6cd62ccf 1242 fld->field_fixed = 1;
1243 }else size = fld->field_size;
1244
1245 }else if(type->type_class == LTT_ARRAY){
1246 element_number = (int) type->element_number;
1247 if(fld->field_fixed == -1){
40331ba8 1248 size = getFieldtypeSize(t, evT, offsetRoot,0,fld->child[0], NULL, trace);
6cd62ccf 1249 if(size == 0){ //has string or sequence
1250 fld->field_fixed = 0;
1251 }else{
1252 fld->field_fixed = 1;
1253 size *= element_number;
1254 }
1255 }else if(fld->field_fixed == 0){// has string or sequence
1256 size = 0;
1257 for(i=0;i<element_number;i++){
1258 size += getFieldtypeSize(t, evT, offsetRoot+size,size,
40331ba8 1259 fld->child[0], evD+size, trace);
6cd62ccf 1260 }
1261 }else size = fld->field_size;
1262
1263 }else if(type->type_class == LTT_SEQUENCE){
40331ba8 1264 size1 = (int) ltt_type_size(trace, type);
6cd62ccf 1265 if(fld->field_fixed == -1){
908f42fa 1266 fld->sequ_number_size = size1;
6cd62ccf 1267 fld->field_fixed = 0;
40331ba8 1268 size = getFieldtypeSize(t, evT, offsetRoot,0,fld->child[0], NULL, trace);
6cd62ccf 1269 fld->element_size = size;
1270 }else{//0: sequence
1271 element_number = getIntNumber(size1,evD);
1272 type->element_number = element_number;
1273 if(fld->element_size > 0){
1274 size = element_number * fld->element_size;
1275 }else{//sequence has string or sequence
1276 size = 0;
1277 for(i=0;i<element_number;i++){
1278 size += getFieldtypeSize(t, evT, offsetRoot+size+size1,size+size1,
40331ba8 1279 fld->child[0], evD+size+size1, trace);
6cd62ccf 1280 }
1281 }
1282 size += size1;
1283 }
1284
1285 }else if(type->type_class == LTT_STRING){
1286 size = 0;
1287 if(fld->field_fixed == -1){
1288 fld->field_fixed = 0;
1289 }else{//0: string
47a166fc 1290 size = strlen((char*)evD) + 1; //include end : '\0'
6cd62ccf 1291 }
1292
1293 }else if(type->type_class == LTT_STRUCT){
1294 element_number = (int) type->element_number;
1295 size = 0;
1296 if(fld->field_fixed == -1){
1297 offset1 = offsetRoot;
1298 offset2 = 0;
1299 for(i=0;i<element_number;i++){
40331ba8 1300 size1=getFieldtypeSize(t, evT,offset1,offset2, fld->child[i], NULL, trace);
6cd62ccf 1301 if(size1 > 0 && size >= 0){
1302 size += size1;
1303 if(offset1 >= 0) offset1 += size1;
1304 offset2 += size1;
1305 }else{
1306 size = -1;
1307 offset1 = -1;
1308 offset2 = -1;
1309 }
1310 }
1311 if(size == -1){
1312 fld->field_fixed = 0;
1313 size = 0;
1314 }else fld->field_fixed = 1;
1315 }else if(fld->field_fixed == 0){
1316 offset1 = offsetRoot;
1317 offset2 = 0;
1318 for(i=0;i<element_number;i++){
40331ba8 1319 size=getFieldtypeSize(t,evT,offset1,offset2,fld->child[i],evD+offset2, trace);
6cd62ccf 1320 offset1 += size;
1321 offset2 += size;
1322 }
1323 size = offset2;
1324 }else size = fld->field_size;
1325 }
1326
1327 fld->offset_root = offsetRoot;
1328 fld->offset_parent = offsetParent;
1329 if(!evD){
1330 fld->fixed_root = (offsetRoot==-1) ? 0 : 1;
1331 fld->fixed_parent = (offsetParent==-1) ? 0 : 1;
1332 }
1333 fld->field_size = size;
1334
1335 return size;
1336}
1337
6cd62ccf 1338
1339/*****************************************************************************
1340 *Function name
1341 * getIntNumber : get an integer number
1342 *Input params
1343 * size : the size of the integer
1344 * evD : the event data
1345 *Return value
1346 * int : an integer
1347 ****************************************************************************/
1348
1349int getIntNumber(int size, void *evD)
1350{
cbd41522 1351 gint64 i;
1352 if(size == 1) i = *(gint8 *)evD;
1353 else if(size == 2) i = *(gint16 *)evD;
1354 else if(size == 4) i = *(gint32 *)evD;
1355 else if(size == 8) i = *(gint64 *)evD;
6cd62ccf 1356
1357 return (int) i;
1358}
1359
1360/*****************************************************************************
1361 *Function name
1362 * getDataEndianType : get the data type size and endian type of the local
1363 * machine
1364 *Input params
1365 * size : size of data type
1366 * endian : endian type, little or big
1367 ****************************************************************************/
1368
963b5f2d 1369void getDataEndianType(LttArchSize * size, LttArchEndian * endian)
6cd62ccf 1370{
1371 int i = 1;
1372 char c = (char) i;
1373 int sizeInt=sizeof(int), sizeLong=sizeof(long), sizePointer=sizeof(void *);
1374
1375 if(c == 1) *endian = LTT_LITTLE_ENDIAN;
1376 else *endian = LTT_BIG_ENDIAN;
1377
1378 if(sizeInt == 2 && sizeLong == 4 && sizePointer == 4)
1379 *size = LTT_LP32;
1380 else if(sizeInt == 4 && sizeLong == 4 && sizePointer == 4)
1381 *size = LTT_ILP32;
1382 else if(sizeInt == 4 && sizeLong == 8 && sizePointer == 8)
1383 *size = LTT_LP64;
1384 else if(sizeInt == 8 && sizeLong == 8 && sizePointer == 8)
1385 *size = LTT_ILP64;
1386 else *size = LTT_UNKNOWN;
1387}
1388
a5dcde2f 1389/* get the node name of the system */
1390
1391char * ltt_trace_system_description_node_name (LttSystemDescription * s)
1392{
1393 return s->node_name;
1394}
1395
1396
1397/* get the domain name of the system */
1398
1399char * ltt_trace_system_description_domain_name (LttSystemDescription * s)
1400{
1401 return s->domain_name;
1402}
1403
1404
1405/* get the description of the system */
1406
1407char * ltt_trace_system_description_description (LttSystemDescription * s)
1408{
1409 return s->description;
1410}
1411
1412
1413/* get the start time of the trace */
1414
1415LttTime ltt_trace_system_description_trace_start_time(LttSystemDescription *s)
1416{
1417 return s->trace_start;
1418}
1419
This page took 0.100412 seconds and 4 git commands to generate.