move ltt-private.h from public directroy into private directroy
[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 {
25975c93 874 g_print("End of file\n");
963b5f2d 875 return;
876 }
40331ba8 877 }else if(tailTime == 0){
e37c1372 878 t->cur_event_pos = t->last_event_pos;
62e55dd6 879 t->current_event_time = time;
880 t->cur_heart_beat_number = 0;
881 t->prev_event_time.tv_sec = 0;
882 t->prev_event_time.tv_nsec = 0;
40331ba8 883 return;
6cd62ccf 884 }
6cd62ccf 885}
886
80da81ad 887/*****************************************************************************
888 * Seek to the first event with position equal or larger to ep
889 ****************************************************************************/
890
891void ltt_tracefile_seek_position(LttTracefile *t, LttEventPosition *ep)
892{
893 //if we are at the right place, just return
894 if(t->which_block == ep->block_num && t->which_event == ep->event_num)
895 return;
896
897 if(t->which_block == ep->block_num) updateTracefile(t);
898 else readBlock(t,ep->block_num);
899
900 //event offset is availiable
901 if(ep->old_position){
902 t->cur_heart_beat_number = ep->heart_beat_number;
903 t->cur_event_pos = t->buffer + ep->event_offset;
904 return;
905 }
906
907 //only block number and event index are availiable
908 while(t->which_event < ep->event_num) ltt_tracefile_read(t);
909
910 return;
911}
912
6cd62ccf 913/*****************************************************************************
914 *Function name
40331ba8 915 * ltt_tracefile_read : read the current event, set the pointer to the next
6cd62ccf 916 *Input params
917 * t : tracefile
918 *Return value
963b5f2d 919 * LttEvent * : an event to be processed
6cd62ccf 920 ****************************************************************************/
921
963b5f2d 922LttEvent *ltt_tracefile_read(LttTracefile *t)
6cd62ccf 923{
7525f9e5 924 LttEvent * lttEvent = &t->an_event;
963b5f2d 925 int err;
6cd62ccf 926
bdc36259 927 if(t->cur_event_pos == t->buffer + t->block_size){
928 if(t->which_block == t->block_number){
bdc36259 929 return NULL;
930 }
931 err = readBlock(t, t->which_block + 1);
932 if(err)g_error("Can not read tracefile");
933 }
934
cbd41522 935 lttEvent->event_id = (int)(*(guint16 *)(t->cur_event_pos));
963b5f2d 936 if(lttEvent->event_id == TRACE_TIME_HEARTBEAT)
937 t->cur_heart_beat_number++;
6cd62ccf 938
40331ba8 939 t->prev_event_time = t->current_event_time;
62e55dd6 940 // t->current_event_time = getEventTime(t);
6cd62ccf 941
cbd41522 942 lttEvent->time_delta = *(guint32 *)(t->cur_event_pos + EVENT_ID_SIZE);
963b5f2d 943 lttEvent->event_time = t->current_event_time;
944
6cd62ccf 945 lttEvent->tracefile = t;
946 lttEvent->data = t->cur_event_pos + EVENT_HEADER_SIZE;
908f42fa 947 lttEvent->which_block = t->which_block;
948 lttEvent->which_event = t->which_event;
6cd62ccf 949
40331ba8 950 //update the fields of the current event and go to the next event
951 err = skipEvent(t);
40331ba8 952 if(err == ERANGE) g_error("event id is out of range\n");
40331ba8 953
e4eced0f 954 lttEvent->event_cycle_count = t->cur_cycle_count;
955
6cd62ccf 956 return lttEvent;
957}
958
959/****************************************************************************
960 *Function name
961 * readFile : wrap function to read from a file
962 *Input Params
963 * fd : file descriptor
964 * buf : buf to contain the content
965 * size : number of bytes to be read
966 * mesg : message to be printed if some thing goes wrong
967 *return value
968 * 0 : success
969 * EIO : can not read from the file
970 ****************************************************************************/
971
972int readFile(int fd, void * buf, size_t size, char * mesg)
973{
974 ssize_t nbBytes;
975 nbBytes = read(fd, buf, size);
976 if(nbBytes != size){
977 printf("%s\n",mesg);
978 return EIO;
979 }
980 return 0;
981}
982
983/****************************************************************************
984 *Function name
985 * readBlock : read a block from the file
986 *Input Params
987 * lttdes : ltt trace file
988 * whichBlock : the block which will be read
989 *return value
990 * 0 : success
991 * EINVAL : lseek fail
992 * EIO : can not read from the file
993 ****************************************************************************/
994
963b5f2d 995int readBlock(LttTracefile * tf, int whichBlock)
6cd62ccf 996{
997 off_t nbBytes;
cbd41522 998 guint32 lostSize;
6cd62ccf 999
1000 if(whichBlock - tf->which_block == 1 && tf->which_block != 0){
963b5f2d 1001 tf->prev_block_end_time = tf->a_block_end->time;
40331ba8 1002 tf->prev_event_time = tf->a_block_end->time;
6cd62ccf 1003 }else{
1004 tf->prev_block_end_time.tv_sec = 0;
1005 tf->prev_block_end_time.tv_nsec = 0;
40331ba8 1006 tf->prev_event_time.tv_sec = 0;
1007 tf->prev_event_time.tv_nsec = 0;
6cd62ccf 1008 }
6cd62ccf 1009
963b5f2d 1010 nbBytes=lseek(tf->fd,(off_t)((whichBlock-1)*tf->block_size), SEEK_SET);
6cd62ccf 1011 if(nbBytes == -1) return EINVAL;
1012
963b5f2d 1013 if(readFile(tf->fd,tf->buffer,tf->block_size,"Unable to read a block"))
1014 return EIO;
6cd62ccf 1015
963b5f2d 1016 tf->a_block_start=(BlockStart *) (tf->buffer + EVENT_HEADER_SIZE);
cbd41522 1017 lostSize = *(guint32 *)(tf->buffer + tf->block_size - sizeof(guint32));
963b5f2d 1018 tf->a_block_end=(BlockEnd *)(tf->buffer + tf->block_size -
1019 lostSize + EVENT_HEADER_SIZE);
e37c1372 1020 tf->last_event_pos = tf->buffer + tf->block_size - lostSize;
6cd62ccf 1021
6cd62ccf 1022 tf->which_block = whichBlock;
963b5f2d 1023 tf->which_event = 1;
40331ba8 1024 tf->cur_event_pos = tf->buffer;//the beginning of the block, block start ev
6cd62ccf 1025 tf->cur_heart_beat_number = 0;
963b5f2d 1026
6cd62ccf 1027 getCyclePerNsec(tf);
1028
62e55dd6 1029 tf->current_event_time = getEventTime(tf);
40331ba8 1030
6cd62ccf 1031 return 0;
1032}
1033
1034/*****************************************************************************
1035 *Function name
1036 * updateTracefile : reinitialize the info of the block which is already
1037 * in the buffer
1038 *Input params
1039 * tf : tracefile
1040 ****************************************************************************/
1041
963b5f2d 1042void updateTracefile(LttTracefile * tf)
6cd62ccf 1043{
963b5f2d 1044 tf->which_event = 1;
40331ba8 1045 tf->cur_event_pos = tf->buffer;
62e55dd6 1046 tf->current_event_time = getEventTime(tf);
6cd62ccf 1047 tf->cur_heart_beat_number = 0;
1048
1049 tf->prev_event_time.tv_sec = 0;
1050 tf->prev_event_time.tv_nsec = 0;
1051}
1052
1053/*****************************************************************************
1054 *Function name
1055 * skipEvent : go to the next event, update the fields of the current event
1056 *Input params
1057 * t : tracefile
1058 *return value
1059 * 0 : success
6cd62ccf 1060 * ERANGE : event id is out of range
1061 ****************************************************************************/
1062
963b5f2d 1063int skipEvent(LttTracefile * t)
6cd62ccf 1064{
1065 int evId, err;
1066 void * evData;
963b5f2d 1067 LttEventType * evT;
1068 LttField * rootFld;
6cd62ccf 1069
cbd41522 1070 evId = (int)(*(guint16 *)(t->cur_event_pos));
6cd62ccf 1071 evData = t->cur_event_pos + EVENT_HEADER_SIZE;
6cd62ccf 1072
908f42fa 1073 evT = ltt_trace_eventtype_get(t->trace,(unsigned)evId);
47a166fc 1074
908f42fa 1075 if(evT) rootFld = evT->root_field;
1076 else return ERANGE;
6cd62ccf 1077
908f42fa 1078 if(rootFld){
1079 //event has string/sequence or the last event is not the same event
1080 if((evT->latest_block!=t->which_block || evT->latest_event!=t->which_event)
1081 && rootFld->field_fixed == 0){
1082 setFieldsOffset(t, evT, evData, t->trace);
47a166fc 1083 }
908f42fa 1084 t->cur_event_pos += EVENT_HEADER_SIZE + rootFld->field_size;
1085 }else t->cur_event_pos += EVENT_HEADER_SIZE;
1086
1087 evT->latest_block = t->which_block;
1088 evT->latest_event = t->which_event;
1089
6cd62ccf 1090 //the next event is in the next block
963b5f2d 1091 if(evId == TRACE_BLOCK_END){
bdc36259 1092 t->cur_event_pos = t->buffer + t->block_size;
6cd62ccf 1093 }else{
1094 t->which_event++;
62e55dd6 1095 t->current_event_time = getEventTime(t);
6cd62ccf 1096 }
1097
1098 return 0;
1099}
1100
1101/*****************************************************************************
1102 *Function name
1103 * getCyclePerNsec : calculate cycles per nsec for current block
1104 *Input Params
1105 * t : tracefile
1106 ****************************************************************************/
1107
963b5f2d 1108void getCyclePerNsec(LttTracefile * t)
6cd62ccf 1109{
963b5f2d 1110 LttTime lBufTotalTime; /* Total time for this buffer */
1111 LttCycleCount lBufTotalNSec; /* Total time for this buffer in nsecs */
1112 LttCycleCount lBufTotalCycle;/* Total cycles for this buffer */
6cd62ccf 1113
1114 /* Calculate the total time for this buffer */
308711e5 1115 lBufTotalTime = ltt_time_sub(t->a_block_end->time, t->a_block_start->time);
6cd62ccf 1116
1117 /* Calculate the total cycles for this bufffer */
e4eced0f 1118 lBufTotalCycle = t->a_block_end->cycle_count;
1119 lBufTotalCycle -= t->a_block_start->cycle_count;
6cd62ccf 1120
1121 /* Convert the total time to nsecs */
e4eced0f 1122 lBufTotalNSec = lBufTotalTime.tv_sec;
308711e5 1123 lBufTotalNSec *= NANOSECONDS_PER_SECOND;
e4eced0f 1124 lBufTotalNSec += lBufTotalTime.tv_nsec;
6cd62ccf 1125
1126 t->cycle_per_nsec = (double)lBufTotalCycle / (double)lBufTotalNSec;
1127}
1128
1129/****************************************************************************
1130 *Function name
1131 * getEventTime : obtain the time of an event
1132 *Input params
1133 * tf : tracefile
1134 *Return value
963b5f2d 1135 * LttTime : the time of the event
6cd62ccf 1136 ****************************************************************************/
1137
963b5f2d 1138LttTime getEventTime(LttTracefile * tf)
6cd62ccf 1139{
963b5f2d 1140 LttTime time;
1141 LttCycleCount cycle_count; // cycle count for the current event
1142 LttCycleCount lEventTotalCycle; // Total cycles from start for event
1143 double lEventNSec; // Total usecs from start for event
1144 LttTime lTimeOffset; // Time offset in struct LttTime
cbd41522 1145 guint16 evId;
1146 gint64 nanoSec, tmpCycleCount = (((guint64)1)<<32);
e4eced0f 1147 static LttCycleCount preCycleCount = 0;
1148 static int count = 0;
1149
cbd41522 1150 evId = *(guint16 *)tf->cur_event_pos;
e4eced0f 1151 if(evId == TRACE_BLOCK_START){
1152 count = 0;
1153 preCycleCount = 0;
1154 tf->cur_cycle_count = tf->a_block_start->cycle_count;
40331ba8 1155 return tf->a_block_start->time;
e4eced0f 1156 }else if(evId == TRACE_BLOCK_END){
1157 count = 0;
1158 preCycleCount = 0;
1159 tf->cur_cycle_count = tf->a_block_end->cycle_count;
40331ba8 1160 return tf->a_block_end->time;
e4eced0f 1161 }
40331ba8 1162
e4eced0f 1163 // Calculate total time in cycles from start of buffer for this event
cbd41522 1164 cycle_count = (LttCycleCount)*(guint32 *)(tf->cur_event_pos + EVENT_ID_SIZE);
e4eced0f 1165
1166 if(cycle_count < preCycleCount)count++;
1167 preCycleCount = cycle_count;
1168 cycle_count += tmpCycleCount * count;
1169
1170 if(tf->cur_heart_beat_number > count)
1171 cycle_count += tmpCycleCount * (tf->cur_heart_beat_number - count);
1172
1173 tf->cur_cycle_count = cycle_count;
1174
1175 lEventTotalCycle = cycle_count;
1176 lEventTotalCycle -= tf->a_block_start->cycle_count;
6cd62ccf 1177
963b5f2d 1178 // Convert it to nsecs
6cd62ccf 1179 lEventNSec = lEventTotalCycle / tf->cycle_per_nsec;
e4eced0f 1180 nanoSec = lEventNSec;
1181
963b5f2d 1182 // Determine offset in struct LttTime
308711e5 1183 lTimeOffset.tv_nsec = nanoSec % NANOSECONDS_PER_SECOND;
1184 lTimeOffset.tv_sec = nanoSec / NANOSECONDS_PER_SECOND;
6cd62ccf 1185
308711e5 1186 time = ltt_time_add(tf->a_block_start->time, lTimeOffset);
e4eced0f 1187
6cd62ccf 1188 return time;
1189}
1190
1191/*****************************************************************************
1192 *Function name
1193 * setFieldsOffset : set offset of the fields
1194 *Input params
1195 * tracefile : opened trace file
1196 * evT : the event type
1197 * evD : event data, it may be NULL
1198 ****************************************************************************/
1199
40331ba8 1200void setFieldsOffset(LttTracefile *tf,LttEventType *evT,void *evD,LttTrace* t)
6cd62ccf 1201{
963b5f2d 1202 LttField * rootFld = evT->root_field;
6cd62ccf 1203 // rootFld->base_address = evD;
1204
8710c6c7 1205 if(rootFld)
1206 rootFld->field_size = getFieldtypeSize(tf, evT, 0,0,rootFld, evD,t);
6cd62ccf 1207}
1208
1209/*****************************************************************************
1210 *Function name
1211 * getFieldtypeSize: get the size of the field type (primitive type)
1212 *Input params
1213 * tracefile : opened trace file
1214 * evT : event type
1215 * offsetRoot : offset from the root
1216 * offsetParent : offset from the parrent
1217 * fld : field
1218 * evD : event data, it may be NULL
1219 *Return value
1220 * int : size of the field
1221 ****************************************************************************/
1222
963b5f2d 1223int getFieldtypeSize(LttTracefile * t, LttEventType * evT, int offsetRoot,
40331ba8 1224 int offsetParent, LttField * fld, void *evD, LttTrace *trace)
6cd62ccf 1225{
1226 int size, size1, element_number, i, offset1, offset2;
963b5f2d 1227 LttType * type = fld->field_type;
6cd62ccf 1228
8710c6c7 1229 if(t){
963b5f2d 1230 if(evT->latest_block==t->which_block && evT->latest_event==t->which_event){
1231 return fld->field_size;
1232 }
1233 }
6cd62ccf 1234
1235 if(fld->field_fixed == 1){
1236 if(fld == evT->root_field) return fld->field_size;
1237 }
1238
1239 if(type->type_class != LTT_STRUCT && type->type_class != LTT_ARRAY &&
1240 type->type_class != LTT_SEQUENCE && type->type_class != LTT_STRING){
1241 if(fld->field_fixed == -1){
40331ba8 1242 size = (int) ltt_type_size(trace, type);
6cd62ccf 1243 fld->field_fixed = 1;
1244 }else size = fld->field_size;
1245
1246 }else if(type->type_class == LTT_ARRAY){
1247 element_number = (int) type->element_number;
1248 if(fld->field_fixed == -1){
40331ba8 1249 size = getFieldtypeSize(t, evT, offsetRoot,0,fld->child[0], NULL, trace);
6cd62ccf 1250 if(size == 0){ //has string or sequence
1251 fld->field_fixed = 0;
1252 }else{
1253 fld->field_fixed = 1;
1254 size *= element_number;
1255 }
1256 }else if(fld->field_fixed == 0){// has string or sequence
1257 size = 0;
1258 for(i=0;i<element_number;i++){
1259 size += getFieldtypeSize(t, evT, offsetRoot+size,size,
40331ba8 1260 fld->child[0], evD+size, trace);
6cd62ccf 1261 }
1262 }else size = fld->field_size;
1263
1264 }else if(type->type_class == LTT_SEQUENCE){
40331ba8 1265 size1 = (int) ltt_type_size(trace, type);
6cd62ccf 1266 if(fld->field_fixed == -1){
908f42fa 1267 fld->sequ_number_size = size1;
6cd62ccf 1268 fld->field_fixed = 0;
40331ba8 1269 size = getFieldtypeSize(t, evT, offsetRoot,0,fld->child[0], NULL, trace);
6cd62ccf 1270 fld->element_size = size;
1271 }else{//0: sequence
1272 element_number = getIntNumber(size1,evD);
1273 type->element_number = element_number;
1274 if(fld->element_size > 0){
1275 size = element_number * fld->element_size;
1276 }else{//sequence has string or sequence
1277 size = 0;
1278 for(i=0;i<element_number;i++){
1279 size += getFieldtypeSize(t, evT, offsetRoot+size+size1,size+size1,
40331ba8 1280 fld->child[0], evD+size+size1, trace);
6cd62ccf 1281 }
1282 }
1283 size += size1;
1284 }
1285
1286 }else if(type->type_class == LTT_STRING){
1287 size = 0;
1288 if(fld->field_fixed == -1){
1289 fld->field_fixed = 0;
1290 }else{//0: string
47a166fc 1291 size = strlen((char*)evD) + 1; //include end : '\0'
6cd62ccf 1292 }
1293
1294 }else if(type->type_class == LTT_STRUCT){
1295 element_number = (int) type->element_number;
1296 size = 0;
1297 if(fld->field_fixed == -1){
1298 offset1 = offsetRoot;
1299 offset2 = 0;
1300 for(i=0;i<element_number;i++){
40331ba8 1301 size1=getFieldtypeSize(t, evT,offset1,offset2, fld->child[i], NULL, trace);
6cd62ccf 1302 if(size1 > 0 && size >= 0){
1303 size += size1;
1304 if(offset1 >= 0) offset1 += size1;
1305 offset2 += size1;
1306 }else{
1307 size = -1;
1308 offset1 = -1;
1309 offset2 = -1;
1310 }
1311 }
1312 if(size == -1){
1313 fld->field_fixed = 0;
1314 size = 0;
1315 }else fld->field_fixed = 1;
1316 }else if(fld->field_fixed == 0){
1317 offset1 = offsetRoot;
1318 offset2 = 0;
1319 for(i=0;i<element_number;i++){
40331ba8 1320 size=getFieldtypeSize(t,evT,offset1,offset2,fld->child[i],evD+offset2, trace);
6cd62ccf 1321 offset1 += size;
1322 offset2 += size;
1323 }
1324 size = offset2;
1325 }else size = fld->field_size;
1326 }
1327
1328 fld->offset_root = offsetRoot;
1329 fld->offset_parent = offsetParent;
1330 if(!evD){
1331 fld->fixed_root = (offsetRoot==-1) ? 0 : 1;
1332 fld->fixed_parent = (offsetParent==-1) ? 0 : 1;
1333 }
1334 fld->field_size = size;
1335
1336 return size;
1337}
1338
6cd62ccf 1339
1340/*****************************************************************************
1341 *Function name
1342 * getIntNumber : get an integer number
1343 *Input params
1344 * size : the size of the integer
1345 * evD : the event data
1346 *Return value
1347 * int : an integer
1348 ****************************************************************************/
1349
1350int getIntNumber(int size, void *evD)
1351{
cbd41522 1352 gint64 i;
1353 if(size == 1) i = *(gint8 *)evD;
1354 else if(size == 2) i = *(gint16 *)evD;
1355 else if(size == 4) i = *(gint32 *)evD;
1356 else if(size == 8) i = *(gint64 *)evD;
6cd62ccf 1357
1358 return (int) i;
1359}
1360
1361/*****************************************************************************
1362 *Function name
1363 * getDataEndianType : get the data type size and endian type of the local
1364 * machine
1365 *Input params
1366 * size : size of data type
1367 * endian : endian type, little or big
1368 ****************************************************************************/
1369
963b5f2d 1370void getDataEndianType(LttArchSize * size, LttArchEndian * endian)
6cd62ccf 1371{
1372 int i = 1;
1373 char c = (char) i;
1374 int sizeInt=sizeof(int), sizeLong=sizeof(long), sizePointer=sizeof(void *);
1375
1376 if(c == 1) *endian = LTT_LITTLE_ENDIAN;
1377 else *endian = LTT_BIG_ENDIAN;
1378
1379 if(sizeInt == 2 && sizeLong == 4 && sizePointer == 4)
1380 *size = LTT_LP32;
1381 else if(sizeInt == 4 && sizeLong == 4 && sizePointer == 4)
1382 *size = LTT_ILP32;
1383 else if(sizeInt == 4 && sizeLong == 8 && sizePointer == 8)
1384 *size = LTT_LP64;
1385 else if(sizeInt == 8 && sizeLong == 8 && sizePointer == 8)
1386 *size = LTT_ILP64;
1387 else *size = LTT_UNKNOWN;
1388}
1389
a5dcde2f 1390/* get the node name of the system */
1391
1392char * ltt_trace_system_description_node_name (LttSystemDescription * s)
1393{
1394 return s->node_name;
1395}
1396
1397
1398/* get the domain name of the system */
1399
1400char * ltt_trace_system_description_domain_name (LttSystemDescription * s)
1401{
1402 return s->domain_name;
1403}
1404
1405
1406/* get the description of the system */
1407
1408char * ltt_trace_system_description_description (LttSystemDescription * s)
1409{
1410 return s->description;
1411}
1412
1413
1414/* get the start time of the trace */
1415
1416LttTime ltt_trace_system_description_trace_start_time(LttSystemDescription *s)
1417{
1418 return s->trace_start;
1419}
1420
This page took 0.090766 seconds and 4 git commands to generate.